FFmpeg为视频加字幕
为视频添加字幕的方式有很多种,大概可以分为:
1、将字幕编码进视频流中。
2、在封装容器中加入字幕流。
其中第一种方式与视频加水印基本相似,第二种方式则需要封装容器支持加入字幕流。
1、ASS字幕流写入视频流
需要FFmpeg在编译时支持ass,--enable-libass,字幕文件内容格式大致如下:
[Script Info]
[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 Narrow,16,&H00FFFFFF,&H0000FFFF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,2,1,2,20,20,3,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:05.58,0:00:07.20,Default,,0000,0000,0000,,{\fnArial Narrow\fs20}名字是一个人的代号{\r}\NName is aword by which a person is spoken of.
Dialogue: 0,0:00:07.87,0:00:09.04,Default,,0000,0000,0000,,{\fnArial Narrow\fs20}但当一个人的职业{\r}\NWhen a person's profession
Dialogue: 0,0:00:09.20,0:00:11.16,Default,,0000,0000,0000,,{\fnArial Narrow\fs20}可以变成他的代号的时候{\r}\Nbecomes his nick name,{\r}
Dialogue: 0,0:00:11.87,0:00:14.29,Default,,0000,0000,0000,,{\fnArial Narrow\fs20}往往人们就会忘记了他本来的名字{\r}\Npeople will forget his original name.
命令行如下:
ffmpeg -i 111.mp4 -vf ass=t1.ass output.mp4
输入输出信息如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '111.mp4':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: mp41avc1qt
creation_time : 2017-02-04T01:33:49.000000Z
playback_requirements: QuickTime 6.0 or greater
playback_requirements-eng: QuickTime 6.0 or greater
encoder : vlc 2.1.5 stream output
encoder-eng : vlc 2.1.5 stream output
Duration: 00:01:21.89, start: 0.000000, bitrate: 2037 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 23 kb/s (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : SoundHandler
Stream #0:1(eng): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080, 2009 kb/s, 25 fps, 25 tbr, 1000k tbn, 50 tbc (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : VideoHandler
Stream mapping:
Stream #0:1 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:0 -> #0:1 (aac (native) -> aac (native))
Output #0, mp4, to 'output.mp4':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: mp41avc1qt
encoder : Lavf58.20.100
playback_requirements: QuickTime 6.0 or greater
playback_requirements-eng: QuickTime 6.0 or greater
Stream #0:0(eng): Video: h264 (libx264) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, q=-1--1, 25 fps, 12800 tbn, 25 tbc (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : VideoHandler
encoder : Lavc58.35.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 69 kb/s (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : SoundHandler
encoder : Lavc58.35.100 aac
从以上信息中可以看出,输入与输出的封装容器格式基本相同,均为一个视频流和一个音频流,并未包含字幕流,因为字幕流是通过ASS容器将文字写入视频流中的。

2、ASS字幕流写入封装容器
除了以上将字幕流加入到视频编码中的方式外,还可以在视频封装容器中增加字幕流,只要封装容器格式支持字幕流即可。
如下,使用FFmpeg将ASS字幕流写入MKV封装容器中:
ffmpeg -i 111.mp4 -i t1.ass -acodec copy -vcodec copy -scodec copy output.mkv
输入输出信息如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '111.mp4':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: mp41avc1qt
creation_time : 2017-02-04T01:33:49.000000Z
playback_requirements: QuickTime 6.0 or greater
playback_requirements-eng: QuickTime 6.0 or greater
encoder : vlc 2.1.5 stream output
encoder-eng : vlc 2.1.5 stream output
Duration: 00:01:21.89, start: 0.000000, bitrate: 2037 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 23 kb/s (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : SoundHandler
Stream #0:1(eng): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080, 2009 kb/s, 25 fps, 25 tbr, 1000k tbn, 50 tbc (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : VideoHandler
Input #1, ass, from 't1.ass':
Duration: N/A, bitrate: N/A
Stream #1:0: Subtitle: ass
Output #0, matroska, to 'output.mkv':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: mp41avc1qt
encoder : Lavf58.20.100
playback_requirements: QuickTime 6.0 or greater
playback_requirements-eng: QuickTime 6.0 or greater
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080, q=2-31, 2009 kb/s, 25 fps, 25 tbr, 1k tbn, 1000k tbc (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) ([255][0][0][0] / 0x00FF), 16000 Hz, mono, fltp, 23 kb/s (default)
Metadata:
creation_time : 2017-02-04T01:33:49.000000Z
handler_name : SoundHandler
Stream #0:2: Subtitle: ass
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
Stream #1:0 -> #0:2 (copy)
Press [q] to stop, [?] for help
frame= 2048 fps=0.0 q=-1.0 Lsize= 20343kB time=00:01:21.88 bitrate=2035.1kbits/s speed= 623x
命令行执行之后,会将111.mp4中的音频流、视频流、t1.ass中的字幕流在不改变编码的情况下封装到output.mkv文件中,因此output.mkv文件将会包含三个流,分别为视频流、音频流、字幕流。
如果111.mp4中或输入的视频文件中原本带有字幕流,并希望使用t1.ass字幕流时,可通过map功能将对应的字幕流指定封装到output.mkv中:
ffmpeg -i input.mp4 -i t1.ass -map 0:0 -map 0:1 -map 1:0 -acodec copy -vcodec copy -scodec copy output1.mkv
命令行执行之后生成的文件信息如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:01:21.88, start: 0.000000, bitrate: 2598 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, 2530 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 62 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #1, ass, from 't1.ass':
Duration: N/A, bitrate: N/A
Stream #1:0: Subtitle: ass
Output #0, matroska, to 'output1.mkv':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, q=2-31, 2530 kb/s, 25 fps, 25 tbr, 1k tbn, 12800 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) ([255][0][0][0] / 0x00FF), 16000 Hz, mono, fltp, 62 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2: Subtitle: ass
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #1:0 -> #0:2 (copy)

网友评论