引言
现在的短视频非常流行。大多数情况下我们会开着音量或者戴着耳机收看视频。但有些时候不是太方便,如果视频能有一个字幕就好了。
好消息是,字幕制作的软件很专业很好用,而且上手超级简单。
坏消息是,如何把字幕合成到视频音频文件内?或者把字幕文件从视频文件提取出来,都需要不少工具!
我们今天讲解使用 ffmpeg 解决大家的这个痛点。
学习时间
1 - 软编码
MP4支持流式文本格式的字幕,但是在播放器和设备中,回放功能的支持并不统一。使用流处理进行语音频道的复制,基本的用法结构如下:
ffmpeg -i input.mkv -c copy -c:s mov_text output.mp4
再深入一步,使用流式处理并复制音频和视频流,将基于文本的字幕输入流,可以是 srt ass vtt 等字幕文件,转换为流式文本,并设置前两个字幕流的语言格式,需要这样写指令:
ffmpeg -i input.mkv -map 0 -c copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
注意到上面我们使用 -c copy 选项,把音视频流整体拷贝出来了。如果想要使用指定的编码器,比如 MP4 格式使用的 H.264,可以这样写:
ffmpeg -i input.mkv -map 0 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
上面这个指令中 -map 0 我们改造一下,指定使用第一个视频流,第二个音频流,第三个字母文本流,需要这样写:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -map 0:s:2 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng output.mp4
2 - 硬编码
首先说一下基于文本的字幕输入。我们使用ffmpeg 的 subtitle filter 过滤器处理字幕输入文件,格式通常是 ass srt vtt 等。这样的编码方式,比上一节中使用的软编码方式要慢的多,因为进行了重新编码。
对音频文件流拷贝,并使用 subtitle 过滤器,基本用法如下:
ffmpeg -i input.mkv -filter_complex "subtitles=input.mkv" -c:a copy output.mp4
输入流当然也可以任意指定,比如使用第三路视频流,第五路字幕流,第一路音频流,需要这样改写指令:
ffmpeg -i input.mkv -filter_complex "[0:v:2]subtitles=input.mkv:si=4[v]" -map "[v]" -map 0:a:0 -c:a copy output.mp4
如果有字幕组,专门给音视频文件配上字幕。像国内比较常见的对国外影视作品的引进,需要翻译人员制作字幕,那么翻译组生成字幕文件后,如何合并入音视频文件内呢?
只要像下面这么写:
ffmpeg -i input.mp4 -filter_complex "subtitles=your-subtitles-file.srt" -c:a copy output.mp4
还有一种处理方式,是基于图像的字幕输入,使用覆写的方式。比如,我们把第四路字幕流,覆盖到第二路视频流上,同时拷贝第七路音频流。这时候需要 ffmpeg 的 overlay filter 过滤器,这样写指令:
ffmpeg -i input.mkv -filter_complex "[0:v:1][0:s:3]overlay[v]" -map "[v]" -map 0:a:6 -c:a copy output.mp4
写在最后
通过上述几个例子,大家应该对 map 选项,v,a,s 流通道有深刻的认识了吧。
找一段高清完备的音视频,尝试着从中提取或合成新的文件,实践起来吧。
Happy coding :_)
我是 @程序员小助手 ,持续分享编程知识,欢迎关注。