ffmpeg版本: FFMEPEG 4.4
继上一篇实现音视频播放器后,将加载字幕的过程和遇到的坑记录如下:
字幕初识
视频字幕分为三种。
内嵌字幕,字幕与视频图像合二为一,成为视频帧的一部分,也叫硬字幕。
内封字幕,字幕封装在视频容器中,成为字幕流。软字幕。
外挂字幕,也就字幕文件,如ass,srt等。软字幕。
srt字幕(SubRip Subtitle)
是一种简单的字幕格式,主要由时间戳和文本组成。它通常用于简单的字幕文件,如电影聚会之类。SRT字幕格式的参数如下:
- 标题的计数器/索引
- START和END:字幕开始和字幕结束的时间戳,格式为 "小时:分钟:毫秒"。
- TEXT:在此时间戳范围内显示的字幕文本
- 一行空白表示一个结束
1
00:00:0,000 --> 00:00:2,000
这是0到2秒显示的字幕
2
00:00:2,000 --> 00:00:4,000
这是2到4秒显示的字幕
3
00:00:4,000 --> 00:00:7,000
这是4到7秒显示的字幕
ass字幕(Advanced SubStation Alpha)
是一个高级的字幕格式,它可以支持更多的样式和控制,比如,更改颜色、字体和大小,还可以通过几何变换来控制字幕的位置。ASS字幕格式包含以下参数:
样式:
Style: 序号, 字体名称, 字号, 颜色, 阴影, 边框, 描边, 阴影, 抗锯齿, 倾斜度, weight, underline
例子:Style: Top, Microsoft YaHei,40,&H00F5FF&,-1,2,0,0,1,0,0
对齐:
Dialogue: 0,0:00:03.42,0:00:04.91,Top,,0,0,0,,{\an6}本字幕居右上
其中\an6表示右上角对齐,默认是左下角对齐。
触发器:
Dialogue: 0,0:00:03.42,0:00:04.91,Top,,0,0,0,,{\t(0,300,\fade(400,400))}三秒内渐入渐出
其中\fade(400,400)表示透明度从0渐变到400再从400渐变到0。
动画:
Dialogue: 0,0:00:03.42,0:00:04.91,Top,,0,0,0,,{\move(0,0,100,100)}右下角移动
其中\move(0,0,100,100)表示从(0,0)移动到(100,100)。
特殊效果:
Dialogue: 0,0:00:03.42,0:00:05.62,Top,,0,0,0,,{\fad(500,500)\blur3}左右淡入淡出,模糊度3
其中\blur3表示模糊度为3。
加载字幕这里我们使用subtitles过滤器,它内部使用的是libass库,其他格式的字幕首先会被转换为ass格式,不用担心格式问题。首先我们看下subtitles过滤器的参数
ffmpeg -h filter=subtitles
filename, f 指定使用的字幕文件
stream_index, si 指定使用字幕流中的第几个流
如上图所示,视频文件中有3个字幕流
字幕提取
默认提取第一个字幕流
ffmpeg -i .\11间谍过家家.mkv 简中.ass
提取第二个字幕流
ffmpeg -i .\11间谍过家家.mkv -map 0:s:1 繁中.ass
提取第三个字幕流
ffmpeg -i .\11间谍过家家.mkv -map 0:s:2 日文.ass
格式转换
ffmpeg -i 日文.ass 日文.srt
字幕叠加
硬字幕编码
ffmpeg .\11间谍过家家.mkv -vf subtitles=简中.ass out.mkv
软字幕编码
将字幕文件01.ass 编码成字幕流到文件中(内封字幕)
ffmpeg -i .\beautlWorld.mp4 -i .\01.ass -c copy -c:s mov_text -metadata:s:s:0 language=chi
ouptut_chi.mp4
注意:这里虽然将字幕加载到MP4文件中,但是兼容性不好
请使用MKV封装格式,该格式可封装各种格式的字幕,OGM格式只支持srt
ffmpeg -i .\beautlWorld.mp4 -i .\01.ass -c copy -c:s ass -metadata:s:s:0 language=chi
ouptut_chi.mkv
这里使用ass字幕编码器
如上,字幕文件成了视频文件的内封字幕,视频文件时长1分03秒,字幕时长23分40秒
多通道内封字幕
将两个字幕文件添加到视频文件中
ffmpeg -i beautlWorld.mp4 -i 简中.ass -i 繁中.ass -map 0 -map 1 -map 2 -c copy -c:s ass -metadata:s:s:0 language=chi_eng -metadata:s:s:1 language=eng output_chi_双字幕.mkv
FFMPEG4.4支持的字幕编码器
ffmpeg -encoders
程序加载外挂字幕
在代码中如果使用绝对路径有点区别,需要使用四个斜杆,具体形式如下:
char filterDesc[128];
sprintf(filterDesc,"subtitles=filename='D\\:\\\\测试工程\\\\sound\\\\01.ass'");
程序加载内封字幕
内封字幕与外挂字幕很类似,字幕文件就是视频文件本身,如下代码中设置:
这是设置加载的字幕流为第二个字幕也就是繁体中文,默认是第一个
char filterDesc[128];
sprintf(filterDesc, "subtitles=filename='D\\:\\\\工程\\\\音视频分析\\\\source\\\\11间谍过家家.mkv':stream_index=1");