字幕分以下几种形式:
第一种是外挂字幕(软字幕),视频文件和字幕文件分离。当播放某视频文件时,会自动载入相同文件夹下同名的字幕文件,当然也可以用播放器(如:VLC media player)手动载入字幕(不要求字幕文件和视频文件同名并在相同文件夹下,可任意载入)。
第二种是将字幕封装到容器中,就是所谓的字幕流,和视频流、音频流同等地位。值得说明的是,并非所有的容器都支持字幕流,先进的 MKV 是支持的,MP4 目前我只知道支持苹果的 MOV text。
ffmpeg -i input.mkv -i subtitles.srt -c copy output.mkv
查看 output.mkv 的信息,已经包含了字幕流,但不知为何播放视频时仍然不能显示字幕。
从容器中提取字幕流,生成字幕文件(例子中生成的是 srt 格式的,可以任意生成所需的格式,改一下扩展名即可):
ffmpeg -i input.mkv output.srt
第三种是内嵌字幕(硬字幕),利用 video filter(subtitles、ass、甚至是 overlay)将字幕文件烧进视频流中,就像水印一样。
在使用 FFmpeg 的 subtitles filter 或 ass filter 时,可能会出现类似于下面这样的错误:
Fontconfig error: Cannot load default config file
[Parsed_subtitles_0 @ 0000000004b181c0] No usable fontconfig configuration file found, using fallback.
Fontconfig error: Cannot load default config file
无效的解决方法:
Fontconfig 是一个用来配置和自定义字体访问的库,在这里是为了让 ffmpeg 从系统中取用所需的字体。下载链接:http://www.freedesktop.org/software/fontconfig/release/。我下载的是 fontconfig-2.11.94.tar.gz。在存放 ffmpeg.exe 的文件夹内,新建一个命名为 fonts 的文件夹。把 fontconfig-2.11.94.tar.gz 解压后,找到 fonts.conf.in、fonts.dtd 和 conf.d ,并把它们复制到刚才新建的文件夹 fonts 中,最后把 fonts.conf.in 重命名为 fonts.conf 即可。
通过以上步骤,尽管不再出现前面的错误,但输出的视频仍然不能显示字幕。也许要先对 Fontconfig 进行编译才行(尽管 ffmpeg 不会用到生成的库),尝试用 MinGW+msys 编译了一下,没有搞定。
有效解决:
还是需要 fonts.conf 文件。下载地址:http://download.csdn.net/detail/u013699869/9074131。只要一步,将下载的压缩包解压到 ffmpeg.exe 所在的文件夹下即可。解决方案来源:https://ffmpeg.zeranoe.com/forum/viewtopic.php?f=7&t=2554。
利用 subtitles filter 为视频添加字幕(将字幕合成到视频流中,输出文件中不含字幕流):
ffmpeg -i input.mkv -vf subtitles=subtitles.srt output.mkv
将输入文件的第一个字幕流合成到视频流中:
ffmpeg -i input.mkv -vf subtitles=input.mkv output.mkv将某容器第二个字幕流合成到另一个容器的视频流中输出:
ffmpeg -i input.mkv -vf subtitles=video.mkv:si=1 output.mkv关于 subtitles filter 的详细用法: http://ffmpeg.org/ffmpeg-all.html#subtitles-1
ass filter 的用法和 subtitles filter 几乎一样,但它只用于 ASS(Advanced Substation Alpha)字幕文件,可以先进行字幕转换,再使用它:
ffmpeg -i subtitles.srt subtitles.ass
ffmpeg -i input.mkv -vf ass=subtitles.ass output.mkv
关于 ass filter 的说明:http://ffmpeg.org/ffmpeg-all.html#ass
FFmpeg 官方 wiki:HowToBurnSubtitlesIntoVideo
还可以用 overlay filter 来把字幕烧录进视频,比如把MKV格式转为MP4格式(mp4 也支持字幕流封装,但目前我仅知道支持苹果的 MOV text,所以一般都要把字幕烧到视频流中):
ffmpeg -i input.mkv -filter_complex [0:v][0:s]overlay[v] -map [v] -map 0:a output.mp4