TimeAlbumTask.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import logging
  2. import os
  3. import subprocess
  4. from celery import shared_task
  5. from Ansjer.config import LOGGER
  6. import django
  7. # 设置 Django 的环境变量
  8. os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'Ansjer.cn_config.test_settings') # 确保替换为实际的 settings 模块路径
  9. django.setup()
  10. @shared_task
  11. def start_xvfb():
  12. # 启动 Xvfb
  13. subprocess.Popen(['Xvfb', ':99', '-screen', '0', '1024x768x16'])
  14. os.environ['DISPLAY'] = ':99'
  15. @shared_task
  16. def generate_video(image_files, output_path):
  17. LOGGER.info('start开始视频生成任务')
  18. start_xvfb.delay() # 确保 Xvfb 已经启动
  19. try:
  20. video_files = []
  21. music_path = "/web/test/ASJServer/static/temp/music.mp3"
  22. # 定义特效列表
  23. transitions = [
  24. "BowTieHorizontal.glsl",
  25. "burn.glsl",
  26. "cube.glsl",
  27. "pinwheel.glsl",
  28. "windowslice.glsl",
  29. "Radial.glsl",
  30. "rotateTransition.glsl",
  31. "wind.glsl",
  32. "squeeze.glsl"
  33. ]
  34. # 生成相邻图片的视频
  35. for i in range(len(image_files) - 1):
  36. output_video = os.path.join(output_path, f'{i + 1}_{i + 2}.mp4')
  37. video_files.append(output_video)
  38. cmd = [
  39. 'ffmpeg', '-loop', '1', '-i', image_files[i],
  40. '-loop', '1', '-i', image_files[i + 1],
  41. '-filter_complex',
  42. f'gltransition=duration=1:offset=0.7:source=/web/test/ASJServer/static/gl-transitions/{transitions[i]}',
  43. '-t', '2', output_video
  44. ]
  45. subprocess.run(cmd, check=True)
  46. # 生成拼接列表文件
  47. with open(os.path.join(output_path, 'filelist.txt'), 'w') as f:
  48. for video in video_files:
  49. f.write(f"file '{video}'\n")
  50. # 拼接视频
  51. final_output = os.path.join(output_path, 'final_output.mp4')
  52. subprocess.run(
  53. ['ffmpeg', '-f', 'concat', '-safe', '0', '-i', '/web/test/ASJServer/static/temp/filelist.txt', '-c', 'copy',
  54. final_output],
  55. check=True)
  56. # 添加背景音乐
  57. final_output_with_music = os.path.join(output_path, 'final_output_with_music.mp4')
  58. subprocess.run(['ffmpeg', '-i', final_output, '-i', music_path, '-c:v', 'copy', '-c:a', 'aac', '-b:a', '192k',
  59. '-shortest', final_output_with_music], check=True)
  60. # 清理临时文件
  61. for video in video_files:
  62. os.remove(video)
  63. os.remove('/web/test/ASJServer/static/temp/filelist.txt')
  64. except Exception as e:
  65. LOGGER.info(f'视频合成失败: {e}')