You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Google Colab用ffmpeg/MoviePy烧录字幕时显示方框的问题

问题:Colab中印地语字幕硬编码显示为方框(本地运行正常)

我正在编写Python脚本,通过FFmpeg将印地语字幕硬编码到视频中,已指定支持天城文的自定义字体(NotoSansDevanagari-Regular.ttf,重命名为font.ttf)。本地机器运行时字幕显示正常,但在Google Colab中执行时,字幕变成了矩形方框,无法正常显示印地语字符。

已尝试的操作:

  • 确认字体本身支持印地语字符
  • 将字体上传至Colab并指定了完整路径
  • 验证字幕文本以正确的Unicode格式传递

代码片段:

def add_subtitles(video_path, subtitles_path, output_path):
    """Adds subtitles using FFmpeg with proper path escaping."""
    # Convert to absolute paths and normalize
    video_path = os.path.abspath(video_path)
    subtitles_path = os.path.abspath(subtitles_path)
    output_path = os.path.abspath(output_path)

    # Subtitle path
    font_path = "input_files/font.ttf"
    font_path = os.path.abspath(font_path).replace("\\", "\\\\")
    subtitles_path_escaped = os.path.abspath(subtitles_path).replace("\\", "\\\\")
    
    # Escape backslashes in paths
    subtitles_path = subtitles_path.replace("\\", "\\\\")
    # Remove all files in final_videos
    [os.remove(os.path.join(base_dir, "final_videos", f)) for f in os.listdir(os.path.join(base_dir, "final_videos")) if os.path.isfile(os.path.join(base_dir, "final_videos", f))]

    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    escaped_path = subtitles_path.replace(':', '\\:').replace('\\', '\\\\')

    cmd = [
        "ffmpeg",
        "-i", video_path,
        "-vf", f"subtitles={escaped_path}:force_style='FontFile={font_path}'",
        "-c:v", "libx264",
        "-c:a", "copy",
        "-preset", "fast",
        "-crf", "22",
        output_path
    ]

    # Debug: Print the exact command being executed
    print("Executing:", " ".join(cmd))
    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"✅ Success! Output saved to: {output_path}")
    except subprocess.CalledProcessError as e:
        print(f"❌ FFmpeg failed with error:\n{e.stderr}")

原因分析

  1. 环境路径逻辑不匹配:Colab基于Linux系统,路径分隔符为/,但代码中沿用了Windows的反斜杠转义逻辑,过度转义导致FFmpeg无法识别字体路径。
  2. FFmpeg参数格式错误:force_style的引号嵌套方式不符合Linux下FFmpeg的参数解析规则,导致字体路径未被正确读取。
  3. Colab默认字体缺失:FFmpeg在找不到指定字体时会 fallback 到系统默认字体,而Colab默认环境可能没有预装支持天城文的字体。

解决方案

1. 修正路径处理逻辑(适配Linux)

删除多余的反斜杠转义,直接使用Linux风格的绝对路径:

# 替换原路径处理代码
font_path = os.path.abspath("input_files/font.ttf")
# 仅转义路径中的单引号(如果存在),避免FFmpeg解析出错
escaped_sub_path = subtitles_path.replace("'", "\\'")

2. 调整FFmpeg滤镜参数格式

修正force_style的引号使用方式,确保字体路径被正确识别:

cmd = [
    "ffmpeg",
    "-i", video_path,
    "-vf", f"subtitles={escaped_sub_path}:force_style=FontFile='{font_path}'",
    "-c:v", "libx264",
    "-c:a", "copy",
    "-preset", "fast",
    "-crf", "22",
    "-y",  # 自动覆盖输出文件,避免Colab交互阻塞
    output_path
]

3. 验证字体文件可访问性

在执行命令前添加检查,确保字体文件存在且可读:

if not os.path.exists(font_path):
    print(f"❌ Font file not found: {font_path}")
    return
if not os.access(font_path, os.R_OK):
    print(f"❌ No read permission for font file: {font_path}")
    return

4. 备选:安装系统级印地语字体

如果自定义字体仍无法生效,可直接安装Colab缺失的系统字体包:

!apt-get update && apt-get install -y fonts-noto-devanagari

之后无需指定字体路径,直接使用字体名称即可:

"-vf", f"subtitles={escaped_sub_path}:force_style='FontName=Noto Sans Devanagari'"

验证步骤

执行命令前打印完整FFmpeg命令,检查路径是否正确:

print("Final FFmpeg command:", " ".join(cmd))

可通过!ls input_files命令确认字体文件是否在指定目录下。

内容的提问来源于stack exchange,提问作者Lavish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:23:19