| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 | 
							- import logging
 
- import os
 
- import subprocess
 
- from celery import shared_task
 
- from Ansjer.config import LOGGER
 
- import django
 
- # 设置 Django 的环境变量
 
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'Ansjer.cn_config.test_settings')  # 确保替换为实际的 settings 模块路径
 
- django.setup()
 
- def start_xvfb():
 
-     try:
 
-         # 检查 Xvfb 是否已经在运行
 
-         output = subprocess.check_output("pgrep -f Xvfb", shell=True)
 
-         if output:
 
-             LOGGER.info('虚拟显示服务已在运行')
 
-             os.environ['DISPLAY'] = ':99'
 
-         else:
 
-             # 启动虚拟显示服务
 
-             process = subprocess.Popen(['Xvfb', ':99', '-screen', '0', '1024x768x16'])
 
-             LOGGER.info('虚拟显示服务启动成功,进程ID: %s', process.pid)
 
-             os.environ['DISPLAY'] = ':99'
 
-     except subprocess.CalledProcessError:
 
-         # 如果没有运行,启动 Xvfb
 
-         process = subprocess.Popen(['Xvfb', ':99', '-screen', '0', '1024x768x16'])
 
-         LOGGER.info('虚拟显示服务启动成功,进程ID: %s', process.pid)
 
-         os.environ['DISPLAY'] = ':99'
 
-     except Exception as e:
 
-         LOGGER.error('启动虚拟显示服务失败: %s', e)
 
- @shared_task
 
- def generate_video(image_files, output_path):
 
-     LOGGER.info('start开始视频生成任务')
 
-     # 启动虚拟显示服务
 
-     start_xvfb()
 
-     try:
 
-         video_files = []
 
-         music_path = "static/ffmpeg/music.mp3"
 
-         # 定义特效列表
 
-         transitions = [
 
-             "BowTieHorizontal.glsl",
 
-             "burn.glsl",
 
-             "cube.glsl",
 
-             "pinwheel.glsl",
 
-             "windowslice.glsl",
 
-             "Radial.glsl",
 
-             "rotateTransition.glsl",
 
-             "wind.glsl",
 
-             "squeeze.glsl"
 
-         ]
 
-         # 生成相邻图片的视频
 
-         for i in range(len(image_files) - 1):
 
-             output_video = os.path.join(output_path, f'{i + 1}_{i + 2}.mp4')
 
-             video_files.append(output_video)
 
-             cmd = [
 
-                 'static/ffmpeg/ffmpeg4', '-loop', '1', '-i', image_files[i],
 
-                 '-loop', '1', '-i', image_files[i + 1],
 
-                 '-filter_complex',
 
-                 f'gltransition=duration=1:offset=0.7:source=static/gl-transitions/{transitions[i]}',
 
-                 '-t', '2', output_video
 
-             ]
 
-             subprocess.run(cmd, check=True)
 
-         # 生成拼接列表文件
 
-         filelist_path = os.path.join(output_path, 'filelist.txt')
 
-         with open(filelist_path, 'w') as f:
 
-             for video in video_files:
 
-                 f.write(f"file '{os.path.relpath(video, output_path)}'\n")  # 使用相对路径
 
-         # 拼接并生成背景音乐
 
-         final_output_with_music = os.path.join(output_path, 'final_output_with_music.mp4')
 
-         subprocess.run(
 
-             ['static/ffmpeg/ffmpeg6', '-f', 'concat', '-safe', '0', '-i', filelist_path, '-i', music_path,
 
-              '-c:v', 'copy', '-c:a', 'aac', '-b:a', '192k', '-movflags', '+faststart', '-shortest',
 
-              final_output_with_music],
 
-             check=True
 
-         )
 
-         video420acc = os.path.join(output_path, 'video420acc.mp4')
 
-         subprocess.run(
 
-             ['static/ffmpeg/ffmpeg6', '-i', final_output_with_music, '-pix_fmt', 'yuv420p', video420acc],
 
-             check=True
 
-         )
 
-         # 清理临时文件
 
-         for video in video_files:
 
-             os.remove(video)
 
-         os.remove(filelist_path)
 
-         os.remove(final_output_with_music)
 
-     except Exception as e:
 
-         LOGGER.info(f'视频合成失败: {e}')
 
 
  |