123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import os
- import json
- import subprocess
- import time
- import ffmpeg
- from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
- from moviepy.video.tools.subtitles import SubtitlesClip
- from .logger_config import setup_logger
- from .llm_director import caption_correct
- logger = setup_logger(__name__)
- 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), ...]
- """
- logger.info(f"字幕文件生成。。。")
- 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"{caption_correct(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烧录字幕(硬编码) - 确保音频保留的版本
- """
- logger.info(f"视频加字幕。。。")
- # 默认字幕样式(精简必要参数)
- with open("./config/caption_config.json", 'r', encoding='utf-8') as file:
- caption = json.load(file)
- default_style = caption
- style = style_config or default_style
-
- # 构建字幕过滤器字符串
- subtitle_filter = (
- f"subtitles={srt_path}:force_style='"
- f"Fontname={style['fontname']},"
- f"Fontsize={style['fontsize']},"
- f"PrimaryColour={style['fontcolor']},"
- f"BackColour={style['bordercolor']},"
- f"Outline={style['borderw']},"
- f"Alignment={style['alignment']},"
- f"MarginV={style['margin']}'"
- )
-
- # 使用更简单的命令结构,确保音频流被正确处理
- (
- ffmpeg
- .input(input_path)
- .output(
- output_path,
- vf=subtitle_filter, # 应用字幕过滤器
- **{
-
- 'preset': 'fast',
- 'tune': 'fastdecode',
- 'c:a': 'copy', # 尝试直接复制音频
- 'threads': '8',
- 'y': None
- }
- )
- .global_args('-hwaccel', 'cuda')
- .run()
-
- # 'c:v': 'h264_nvenc',
- # 'cq': 28,
- # 'gpu': '1',
- # 'rc': 'constqp',
- )
- if __name__ == "__main__":
- # 生成测试字幕
- text_sequence = [
- (0.0, 10.0, "第一句字幕测试"),
- ]
- generate_srt_file(text_sequence, 'dynamic_subtitles.srt')
- start_time = time.time()
- # 示例用法(硬件加速需配置FFmpeg)
- burn_subtitles_ffmpeg('./output/video_clips/cut_video3.mp4', 'dynamic_subtitles.srt', 'output3.mp4')
- print(f"{time.time() - start_time} secs")
- ## TODO:
- # 1、JSON to SRT
- # 2、JSON to CLIPS
- # 3、SRT add to CLIPS
|