caption.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import os
  2. import subprocess
  3. import ffmpeg
  4. from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
  5. from moviepy.video.tools.subtitles import SubtitlesClip
  6. def sec_to_srt_time(seconds):
  7. hours = int(seconds // 3600)
  8. mins = int((seconds % 3600) // 60)
  9. secs = seconds % 60
  10. return f"{hours:02d}:{mins:02d}:{secs:06.3f}".replace('.', ',')
  11. def generate_srt_file(text_sequence, output_path):
  12. """
  13. 生成SRT字幕文件
  14. 参数:
  15. text_sequence: 字幕列表,格式 [(start_sec, end_sec, text), ...]
  16. """
  17. with open(output_path, 'w', encoding='utf-8') as f:
  18. for i, (start, end, text) in enumerate(text_sequence, 1):
  19. f.write(f"{i}\n")
  20. f.write(f"{sec_to_srt_time(start)} --> {sec_to_srt_time(end)}\n")
  21. f.write(f"{text}\n\n")
  22. def burn_subtitles_bash(input_path, srt_path, output_path):
  23. cmdLine = f"ffmpeg -i {input_path} -vf subtitles={srt_path} -c:a copy -c:v h264_nvenc -preset fast -cq 23 {output_path}"
  24. subprocess.call(cmdLine, shell=True)
  25. def burn_subtitles_ffmpeg(input_path, srt_path, output_path, style_config=None):
  26. """
  27. 通过FFmpeg烧录字幕(硬编码) - 极速优化版
  28. """
  29. # 默认字幕样式(精简必要参数)
  30. default_style = {
  31. 'fontsize': 32,
  32. 'fontcolor': 'FFFFFF', # 直接使用HEX值,避免转换
  33. 'borderw': 2,
  34. 'bordercolor': '000000',
  35. 'alignment': '10',
  36. 'margin': '40'
  37. }
  38. style = style_config or default_style
  39. # 构建FFmpeg命令(直接使用CLI语法更高效)
  40. (
  41. ffmpeg
  42. .input(input_path)
  43. .filter(
  44. 'subtitles',
  45. filename=srt_path,
  46. force_style=(
  47. f"Fontsize={style['fontsize']},"
  48. f"PrimaryColour={style['fontcolor']},"
  49. f"BackColour={style['bordercolor']},"
  50. f"Outline={style['borderw']},"
  51. f"Alignment={style['alignment']},"
  52. f"MarginV={style['margin']}"
  53. )
  54. )
  55. .output(
  56. output_path,
  57. **{
  58. # 核心加速参数
  59. 'c:v': 'h264_nvenc', # NVIDIA GPU编码
  60. 'preset': 'fast', # NVENC最高速预设
  61. 'tune': 'fastdecode', # 优化解码速度
  62. 'rc': 'constqp', # 恒定质量模式
  63. 'cq': 28, # 质量值(18-32,越高越快)
  64. 'gpu': '0', # 指定GPU设备
  65. 'c:a': 'copy', # 直接复制音频
  66. 'threads': '8', # 多线程处理
  67. 'y': None # 覆盖输出文件
  68. }
  69. )
  70. .global_args('-hwaccel', 'cuda') # 启用CUDA硬件加速
  71. .global_args('-hwaccel_output_format', 'cuda') # 显存直接传递
  72. .run()
  73. )
  74. if __name__ == "__main__":
  75. # 生成测试字幕
  76. text_sequence = [
  77. (0.0, 10.0, "第一句字幕测试"),
  78. ]
  79. generate_srt_file(text_sequence, 'dynamic_subtitles.srt')
  80. # 示例用法(硬件加速需配置FFmpeg)
  81. burn_subtitles_ffmpeg('./output/video_clips/cut_video.mp4', 'dynamic_subtitles.srt', 'output.mp4')
  82. ## TODO:
  83. # 1、JSON to SRT
  84. # 2、JSON to CLIPS
  85. # 3、SRT add to CLIPS