ffmpeg在Windows中使用的问题

 


1. 路径引号问题

问题描述:
初始构造 ffmpeg 命令时,输入文件路径被额外的双引号包裹,导致 ffmpeg 无法正确识别路径,从而报错,例如:

Error opening input file "videos/b/download/download/download.mp4".

报错示例:
构造的 ffmpeg 命令类似于:

ffmpeg -i '"videos/b/download/download/download.mp4"' -i '"videos/b/download/download/audio_combined.wav"' ... 

修改前代码示例:
可能在代码中这样处理了路径:

input_video = f'"{input_video}"'
input_audio = f'"{input_audio}"'

修改后解决方案:
直接使用经过处理的绝对路径,并统一使用正斜杠,不再手动添加额外的引号。例如:

input_video = os.path.abspath(input_video).replace("\\", "/")
input_audio = os.path.abspath(input_audio).replace("\\", "/")

这样构造的 ffmpeg 命令就会类似于:

ffmpeg -i F:/Projects/PycharmProjects/Linly-Dubbing/videos/b/download.mp4 -i F:/Projects/PycharmProjects/Linly-Dubbing/videos/b/audio_combined.wav ...

确保 ffmpeg 能正确解析文件路径。


2. Windows 驱动器冒号转义问题

问题描述:
在使用 ffmpeg 的字幕过滤器时,字幕文件路径中存在类似 “F:” 的驱动器标识,未进行转义,导致 ffmpeg 将冒号解析为图像尺寸参数,报错信息类似:

[Parsed_subtitles_0 @ ...] Unable to parse option value "/Projects/..." as image size
Error applying option 'original_size' to filter 'subtitles': Invalid argument

修改前代码示例(未处理冒号):

temp_srt_path = os.path.abspath(temp_srt_path).replace("\\", "/")
# 直接传入没有转义的路径
filter_option = f"subtitles={temp_srt_path}:force_style='{style}'"

修改后解决方案:
编写一个辅助函数 escape_windows_path,将驱动器字母后的冒号转义为 \:

def escape_windows_path(path):
    path = path.replace("\\", "/")
    if re.match(r'^[A-Za-z]:', path):
        # 例如 'F:/Projects/...' -> 'F\:/Projects/...'
        return path[0] + '\\:' + path[2:]
    return path

然后在构造过滤器参数时调用该函数:

temp_srt_path_escaped = escape_windows_path(temp_srt_path)
filter_option = f"subtitles='{temp_srt_path_escaped}':force_style='{style}'"

这样 ffmpeg 就会识别路径为 F\:/Projects/...,避免误解析。


3. 字幕过滤器参数构造问题

问题描述:
构造字幕过滤器时,如果路径和字体目录不正确引用或转义,ffmpeg 会报错,错误信息例如:

Error applying option 'original_size' to filter 'subtitles': Invalid argument

修改前代码示例:

# 未用引号包裹字体目录
filter_option = f"subtitles={temp_srt_path_escaped}:force_style='{style}':fontsdir={font_dir_escaped}"

可能导致 ffmpeg 解析时将 fontsdir 参数与前面的参数混淆。

修改后解决方案:
使用单引号将字幕文件路径和字体目录包裹起来:

filter_option = f"subtitles='{temp_srt_path_escaped}':force_style='{style}':fontsdir='{font_dir_escaped}'"

这样构造出来的参数会类似于:

-vf "subtitles='F\:/Projects/PycharmProjects/Linly-Dubbing/temp/temp_srt_xxx.srt':force_style='FontName=SimHei,FontSize=15,...':fontsdir='F\:/Projects/PycharmProjects/Linly-Dubbing/font'"

确保 ffmpeg 能把整个路径和字体目录作为一个整体参数进行解析。


4. 调试与验证方法

调试步骤示例:

  • 打印 ffmpeg 命令:
    在代码中打印构造好的 ffmpeg 命令,确认所有路径均为绝对路径,且使用了正确的斜杠和引号:

    print("执行的 ffmpeg 命令:", ' '.join(ffmpeg_command))
    
  • 手动执行命令:
    将打印出的命令复制到命令行中手动运行,验证路径、字体文件是否存在,以及命令是否能成功执行。

  • 检查文件是否存在:
    在调用 ffmpeg 前,使用 os.path.exists() 检查文件路径,确保所有文件路径都是正确的。

总结:
经过以上调试和修改:

  • 移除了多余的引号;
  • 对 Windows 路径中的驱动器冒号进行了转义;
  • 在构造字幕过滤器参数时使用单引号包裹路径和字体目录, 最终解决了 ffmpeg 无法正确解析路径和字幕文件的问题。

如有其它疑问,欢迎继续讨论!

posted @ 2025-03-18 16:57  a_true  阅读(412)  评论(0)    收藏  举报