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

使用FFmpeg WASM烧录.ass字幕至.mp4无显示求助

FFmpeg WASM烧录ASS字幕不显示的问题排查与修复

使用FFmpeg WASM将ASS格式字幕烧录到MP4视频后,输出视频未显示字幕,怀疑是字体问题,附上代码与ASS文件内容:

原代码

import { FFmpeg } from "@ffmpeg/ffmpeg"
import { fetchFile } from "@ffmpeg/util"
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs"

export async function burnSubtitles(inputVideo: string, inputSubtitles: string, session: any, videoFileName: string) {
  const ffmpeg = new FFmpeg()
  const supabase = createClientComponentClient()

  try {
    console.log("Loading FFmpeg...")
    await ffmpeg.load({
      coreURL: "https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.4/dist/umd/ffmpeg-core.js",
      log: true,
    })

    console.log("FFmpeg Loaded!")

    // Fetch video and subtitle files
    console.log("Fetching video and subtitle files...")
    const videoFile = await fetchFile(inputVideo)
    const subtitleFile = await fetchFile(inputSubtitles)

    console.log("Writing files to FFmpeg virtual filesystem...")
    await ffmpeg.writeFile("input.mp4", videoFile)
    await ffmpeg.writeFile("subtitles.ass", subtitleFile)

    console.log("Running FFmpeg command...")
    await ffmpeg.exec([
      "-i",
      "input.mp4",
      "-vf",
      "subtitles=subtitles.ass",
      "-c:v",
      "libx264",
      "-preset",
      "fast",
      "-crf",
      "23",
      "-c:a",
      "aac",
      "-b:a",
      "128k",
      "output.mp4",
    ])

    console.log("FFmpeg processing completed!")

    // Get the output file
    console.log("Reading output file...")
    const outputData = await ffmpeg.readFile("output.mp4")

    // Generate file paths
    const processedFile = videoFileName ? `${videoFileName.split(".")[0]}.mp4` : `${Date.now()}.mp4`
    const processedFilePath = `processed/${session.user.id}/${processedFile}`

    console.log("Uploading processed video to Supabase...")

    // Upload the processed video to Supabase
    const { error } = await supabase.storage
      .from("processed")
      .upload(processedFilePath, new Blob([outputData.buffer], { type: "video/mp4" }), { upsert: true })

    if (error) {
      throw new Error(`Failed to upload processed video: ${error.message}`)
    }

    // Get the public URL of the uploaded video
    const {
      data: { publicUrl },
    } = supabase.storage.from("processed").getPublicUrl(processedFilePath)

    console.log("Subtitled video uploaded successfully:", publicUrl)
    return {
      success: true,
      videoUrl: publicUrl,
    }
  } catch (error) {
    console.error("Error in FFmpeg processing:", error)
    return {
      success: false,
      error: "Processing failed",
    }
  } finally {
    ffmpeg.terminate()
  }
}    

ASS字幕文件内容

[Script Info]
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,16,&HFFFFFF,&H000000FF,&H00000000,&H00000000,1,0,0,0,100,100,0,0,1,2,2,2,30,30,360,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,00:00:00.00,00:00:01.11,Default,,0,0,360,,{\fad(300,0)\t(0,350,\fscx80\fscy80)\t(350,600,\fscx100\fscy100)\shad2}THIS IS A TEST,
Dialogue: 0,00:00:01.11,00:00:02.22,Default,,0,0,360,,{\fad(300,0)\t(0,350,\fscx80\fscy80)\t(350,600,\fscx100\fscy100)\shad2}SUBTITLE

问题排查与修复

1. 字体缺失是核心原因

FFmpeg WASM运行在浏览器沙箱中,没有访问系统字体的权限,ASS字幕指定的Arial字体无法被加载,直接导致字幕渲染失败。需要手动将字体文件写入FFmpeg虚拟文件系统,并在滤镜中明确指定字体路径。

修复步骤:

  • 准备Arial字体文件(如arial.ttf),确保可通过前端路径访问
  • 在代码中添加字体文件的读取与写入:
    // 新增:加载字体文件
    const fontFile = await fetchFile("/path/to/arial.ttf"); // 替换为实际字体文件路径
    await ffmpeg.writeFile("arial.ttf", fontFile);
    
  • 修改FFmpeg命令的滤镜参数,指定字体文件:
    await ffmpeg.exec([
      "-i", "input.mp4",
      "-vf", "subtitles=subtitles.ass:fontfile=arial.ttf",
      "-c:v", "libx264", "-preset", "fast", "-crf", "23",
      "-c:a", "aac", "-b:a", "128k",
      "output.mp4"
    ]);
    

2. 验证分辨率匹配

ASS字幕设置的PlayResX:1920、PlayResY:1080需要和输入视频的分辨率一致,否则字幕可能被缩放至不可见或超出画面范围。如果视频分辨率不同,建议调整ASS文件的PlayRes参数,或者在滤镜中添加缩放适配(如scale=1920:1080)。

3. 检查FFmpeg日志

由于开启了log: true,可以查看浏览器控制台中的FFmpeg日志,确认是否有字体加载失败、字幕解析错误等提示,快速定位问题。

4. 优化ASS字幕格式

  • 删除对话行末尾的多余逗号(如THIS IS A TEST,改为THIS IS A TEST),避免潜在解析问题
  • 确认时间码范围在视频时长内,确保字幕有机会被显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:24:52