使用 ffmpeg 来添加文本字幕

我试图使用 ffmpeg 添加文本字幕到 .mp4 容器:

ffmpeg -i input.mp4 -i input.srt -map 0.0 -map 0.1 -map 1.0 output.mp4

当我试图运行这一行时,它给了我一个错误:

流映射的数量必须匹配输出流的数量。

如果我尝试将mp4更改为mkv(尽管mp4支持文本字幕),就像这样:

ffmpeg -i input.mp4 -i input.srt -map 0.0 -map 0.1 -map 1.0 output.mkv

它正确地映射了流,但给出了一个错误:

没有为输出流#0.2找到编码器(编解码器id 94210)

当我启动时

ffmpeg -codecs

我可以看到srt编解码器被支持作为解码器和编码器,但我不确定mp4和mkv子编码使用什么,以及我是否需要打开它或单独编译。

278429 次浏览

注意:此解决方案“烧毁字幕”;放进视频里,这样每个观看视频的人都会被迫看到它们。

如果你的ffmpeg在编译时启用了libass,你可以直接这样做:

ffmpeg -i mymovie.mp4 -vf subtitles=subtitles.srt mysubtitledmovie.mp4

例如,对于Ubuntu 20.10,你可以检查ffmpeg --version是否有--enable-libass

否则,你可以libass库(确保你的ffmpeg安装在配置--enable-libass中有这个库)。

首先将字幕转换为.ass格式:

ffmpeg -i subtitles.srt subtitles.ass

然后使用视频过滤器添加它们:

ffmpeg -i mymovie.mp4 -vf ass=subtitles.ass mysubtitledmovie.mp4

我尝试使用MP4Box来完成这项任务,但它不能处理我正在处理的M4V。我成功地嵌入SRT作为软字幕与ffmpeg与以下命令行:

ffmpeg -i input.m4v -i input.srt -vcodec copy -acodec copy -scodec copy -map 0:0 -map 0:1 -map 1:0 -y output.mkv

像你一样,我必须使用MKV输出文件-我不能创建一个M4V文件。

注意:此解决方案将字幕添加到视频作为一个单独的可选(和用户控制)字幕轨道。

ffmpeg -i infile.mp4 -i infile.srt -c copy -c:s mov_text outfile.mp4

-vf subtitles=infile.srt将不能与-c copy一起工作


-c copy -c:s mov_text的顺序很重要。你告诉FFmpeg:

  1. 视频:拷贝,音频:拷贝,字幕:拷贝
  2. 副标题:mov_text

如果你反转它们,你是在告诉FFmpeg:

  1. 副标题:mov_text
  2. 视频:拷贝,音频:拷贝,字幕:拷贝

或者你可以在any中使用-c:v copy -c:a copy -c:s mov_text 秩序。< / p >

ffmpeg支持mov_text字幕编码器,这是MP4容器中唯一支持的,可由iTunes, Quicktime, iOS等播放。

你的台词应该是:

ffmpeg -i input.mp4 -i input.srt -map 0:0 -map 0:1 -map 1:0 -c:s mov_text output.mp4

MKV容器支持视频和音频编解码器,几乎任何东西,也支持字幕和DVD菜单。所以你可以用带有字幕的MKV容器从输入视频复制编解码器到输出视频。首先你应该把SRT转换成ASS字幕格式

ffmpeg -i input.srt input.ass

并在视频中嵌入ASS字幕

ffmpeg -i input.mp4 -i input.ass -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y out.mkv

也使用过VMW文件。

ffmpeg -i input.wmv -i input.ass -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y out.mkv

参见维基页面容器格式的比较

这就是为什么mkv是一个很好的容器,尤其是现在它已经成熟了:

mkvmerge -o output.mkv video.mp4 subtitle.srt

您正在尝试将字幕合并为字幕流。这很简单,但是MP4(或M4V)和MKV使用了不同的语法。在这两种情况下,你必须指定视频和音频编解码器,或者只是复制流,如果你只是想添加字幕。

MP4:

ffmpeg -i input.mp4 -f srt -i input.srt \
-map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy \
-c:s mov_text output.mp4

MKV:

ffmpeg -i input.mp4 -f srt -i input.srt \
-map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy \
-c:s srt  output.mkv

简单的例子:

videoSource=test.mp4
videoEncoded=test2.mp4
videoSubtitle=test.srt
videoFontSize=24
ffmpeg -i "$videoSource" -vf subtitles="$videoSubtitle":force_style='Fontsize="$videoFontSize"' "$videoEncoded"

只替换linux变量

我将提供一个简单而通用的答案,适用于任何数量的音频和srt字幕而且尊重可能包括mkv容器的元数据。因此,它甚至会添加图像matroska可能包括作为附件(虽然不是另一种类型的AFAIK),并将它们转换为轨道;你将无法观看,但他们会在那里(你可以demux他们)。啊,如果mkv有章节,那么mp4也有章节。

ffmpeg -i <mkv-input> -c copy -map 0 -c:s mov_text <mp4-output>

正如你所看到的,这都是关于-map 0的,它告诉FFmpeg添加所有的轨道,包括元数据、章节、附件等。如果有一个无法识别的“轨道”(mkv允许附加任何类型的文件),它将以错误结束。

如果你经常这样做,你可以创建一个简单的批处理mkv2mp4.bat,以创建一个与mkv同名的mp4。如果使用错误控制、不同的输出名称等,效果会更好,但您已经了解了重点。

@ffmpeg -i %1 -c copy -map 0 -c:s mov_text "%~n1.mp4"

现在你可以简单地跑了

mkv2mp4 "Video with subtitles etc.mkv"

它将创建“带字幕的视频等mp4”,其中包括最大的信息。