refactor(app): 重构视频生成逻辑

- 更新导入路径:从 moviepy.editor 改为 moviepy
- 优化合并字幕、BGM、配音、视频的逻辑
- 移除硬编码路径,使用参数化配置
-简化字幕样式和音量配置
- 调整 generate_video 函数的参数结构
This commit is contained in:
linyq 2025-05-07 13:17:53 +08:00
parent 4bc20c2902
commit 3d9b4b6d93
5 changed files with 27 additions and 41 deletions

View File

@ -7,7 +7,7 @@ from typing import List
from loguru import logger from loguru import logger
from openai import OpenAI from openai import OpenAI
from openai import AzureOpenAI from openai import AzureOpenAI
from moviepy.editor import VideoFileClip from moviepy import VideoFileClip
from openai.types.chat import ChatCompletion from openai.types.chat import ChatCompletion
import google.generativeai as gemini import google.generativeai as gemini
from googleapiclient.errors import ResumableUploadError from googleapiclient.errors import ResumableUploadError

View File

@ -8,7 +8,7 @@ from faster_whisper import WhisperModel
from timeit import default_timer as timer from timeit import default_timer as timer
from loguru import logger from loguru import logger
import google.generativeai as genai import google.generativeai as genai
from moviepy.editor import VideoFileClip from moviepy import VideoFileClip
import os import os
from app.config import config from app.config import config

View File

@ -10,7 +10,7 @@ from app.config import config
from app.models import const from app.models import const
from app.models.schema import VideoConcatMode, VideoParams, VideoClipParams from app.models.schema import VideoConcatMode, VideoParams, VideoClipParams
from app.services import (llm, material, subtitle, video, voice, audio_merger, from app.services import (llm, material, subtitle, video, voice, audio_merger,
subtitle_merger, clip_video, merger_video, update_script) subtitle_merger, clip_video, merger_video, update_script, generate_video)
from app.services import state as sm from app.services import state as sm
from app.utils import utils from app.utils import utils
@ -301,49 +301,35 @@ def start_subclip(task_id: str, params: VideoClipParams, subclip_path_videos: di
""" """
6. 合并字幕/BGM/配音/视频 6. 合并字幕/BGM/配音/视频
""" """
final_video_path = path.join(utils.task_dir(task_id), f"combined.mp4") output_video_path = path.join(utils.task_dir(task_id), f"combined.mp4")
logger.info(f"\n\n## 6. 最后一步: 合并字幕/BGM/配音/视频 -> {final_video_path}") logger.info(f"\n\n## 6. 最后一步: 合并字幕/BGM/配音/视频 -> {output_video_path}")
# 获取背景音乐 bgm_path = '/Users/apple/Desktop/home/NarratoAI/resource/songs/bgm.mp3'
bgm_path = None # bgm_path = params.bgm_file
if params.bgm_type or params.bgm_file:
try:
bgm_path = utils.get_bgm_file(bgm_type=params.bgm_type, bgm_file=params.bgm_file)
if bgm_path:
logger.info(f"使用背景音乐: {bgm_path}")
except Exception as e:
logger.error(f"获取背景音乐失败: {str(e)}")
# 示例:自定义字幕样式 # 调用示例
subtitle_style = { options = {
'fontsize': params.font_size, # 字体大小 'voice_volume': params.tts_volume, # 配音音量
'color': params.text_fore_color, # 字体颜色 'bgm_volume': params.bgm_volume, # 背景音乐音量
'stroke_color': params.stroke_color, # 描边颜色 'original_audio_volume': params.original_volume, # 视频原声音量0表示不保留
'stroke_width': params.stroke_width, # 描边宽度, 范围0-10 'keep_original_audio': True, # 是否保留原声
'bg_color': params.text_back_color, # 半透明黑色背景 'subtitle_font': 'MicrosoftYaHeiNormal.ttc', # 这里使用相对字体路径,会自动在 font_dir() 目录下查找
'position': (params.subtitle_position, 0.2), # 距离顶部60%的位置 'subtitle_font_size': params.font_size,
'method': 'caption' # 渲染方法 'subtitle_color': '#FFFFFF',
'subtitle_bg_color': None, # 直接使用None表示透明背景
'subtitle_position': params.subtitle_position,
'threads': params.n_threads
} }
generate_video.merge_materials(
# 示例:自定义音量配置
volume_config = {
'original': params.original_volume, # 原声音量80%
'bgm': params.bgm_volume, # BGM音量20%
'narration': params.tts_volume or params.voice_volume, # 解说音量100%
}
font_path = utils.font_dir(params.font_name)
video.generate_video_v3(
video_path=combined_video_path, video_path=combined_video_path,
audio_path=merged_audio_path,
subtitle_path=merged_subtitle_path, subtitle_path=merged_subtitle_path,
bgm_path=bgm_path, bgm_path=bgm_path,
narration_path=merged_audio_path, output_path=output_video_path,
output_path=final_video_path, options=options
volume_config=volume_config, # 添加音量配置
subtitle_style=subtitle_style,
font_path=font_path
) )
final_video_paths.append(final_video_path) final_video_paths.append(output_video_path)
combined_video_paths.append(combined_video_path) combined_video_paths.append(combined_video_path)
logger.success(f"任务 {task_id} 已完成, 生成 {len(final_video_paths)} 个视频.") logger.success(f"任务 {task_id} 已完成, 生成 {len(final_video_paths)} 个视频.")

View File

@ -4,10 +4,10 @@ import pysrt
from typing import Optional from typing import Optional
from typing import List from typing import List
from loguru import logger from loguru import logger
from moviepy.editor import * from moviepy import *
from PIL import ImageFont from PIL import ImageFont
from contextlib import contextmanager from contextlib import contextmanager
from moviepy.editor import ( from moviepy import (
VideoFileClip, VideoFileClip,
AudioFileClip, AudioFileClip,
TextClip, TextClip,

View File

@ -1,5 +1,5 @@
requests~=2.31.0 requests~=2.31.0
moviepy==2.0.0.dev2 moviepy==2.1.1
faster-whisper~=1.0.1 faster-whisper~=1.0.1
uvicorn~=0.27.1 uvicorn~=0.27.1
fastapi~=0.115.4 fastapi~=0.115.4