import os import subprocess import ffmpeg from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip from moviepy.video.tools.subtitles import SubtitlesClip def sec_to_srt_time(seconds): hours = int(seconds // 3600) mins = int((seconds % 3600) // 60) secs = seconds % 60 return f"{hours:02d}:{mins:02d}:{secs:06.3f}".replace('.', ',') def generate_srt_file(text_sequence, output_path): """ 生成SRT字幕文件 参数: text_sequence: 字幕列表,格式 [(start_sec, end_sec, text), ...] """ with open(output_path, 'w', encoding='utf-8') as f: for i, (start, end, text) in enumerate(text_sequence, 1): f.write(f"{i}\n") f.write(f"{sec_to_srt_time(start)} --> {sec_to_srt_time(end)}\n") f.write(f"{text}\n\n") def burn_subtitles_bash(input_path, srt_path, output_path): cmdLine = f"ffmpeg -i {input_path} -vf subtitles={srt_path} -c:a copy -c:v h264_nvenc -preset fast -cq 23 {output_path}" subprocess.call(cmdLine, shell=True) def burn_subtitles_ffmpeg(input_path, srt_path, output_path, style_config=None): """ 通过FFmpeg烧录字幕(硬编码) - 极速优化版 """ # 默认字幕样式(精简必要参数) default_style = { 'fontsize': 32, 'fontcolor': 'FFFFFF', # 直接使用HEX值,避免转换 'borderw': 2, 'bordercolor': '000000', 'alignment': '10', 'margin': '40' } style = style_config or default_style # 构建FFmpeg命令(直接使用CLI语法更高效) ( ffmpeg .input(input_path) .filter( 'subtitles', filename=srt_path, force_style=( f"Fontsize={style['fontsize']}," f"PrimaryColour={style['fontcolor']}," f"BackColour={style['bordercolor']}," f"Outline={style['borderw']}," f"Alignment={style['alignment']}," f"MarginV={style['margin']}" ) ) .output( output_path, **{ # 核心加速参数 'c:v': 'h264_nvenc', # NVIDIA GPU编码 'preset': 'fast', # NVENC最高速预设 'tune': 'fastdecode', # 优化解码速度 'rc': 'constqp', # 恒定质量模式 'cq': 28, # 质量值(18-32,越高越快) 'gpu': '0', # 指定GPU设备 'c:a': 'copy', # 直接复制音频 'threads': '8', # 多线程处理 'y': None # 覆盖输出文件 } ) .global_args('-hwaccel', 'cuda') # 启用CUDA硬件加速 .global_args('-hwaccel_output_format', 'cuda') # 显存直接传递 .run() ) if __name__ == "__main__": # 生成测试字幕 text_sequence = [ (0.0, 10.0, "第一句字幕测试"), ] generate_srt_file(text_sequence, 'dynamic_subtitles.srt') # 示例用法(硬件加速需配置FFmpeg) burn_subtitles_ffmpeg('./output/video_clips/cut_video.mp4', 'dynamic_subtitles.srt', 'output.mp4') ## TODO: # 1、JSON to SRT # 2、JSON to CLIPS # 3、SRT add to CLIPS