折腾:
【未解决】把视频画面增加高度再合并字幕到指定位置
期间,已有一个srt文件和(扩大了高度的视频),现在希望去把字幕嵌入到视频下方部分,最好能指定位置。
对于指定额外属性:
srt貌似不支持,之前接触过ass好像可以:
包括字幕背景色,字体大小和颜色等等。
先去把srt嵌入式视频中再说。
后续再看能否指定嵌入字幕的位置以及其他额外属性。
之前其实已经有过类似经验:
【已解决】ffmpeg从mp4视频提取出srt和ass字幕文件
【已解决】Mac中用ffmpeg调整mp4默认字幕为中文
【已解决】ffmpeg集成srt字幕到视频的字幕流中即软字幕
ffmpeg -i CTT_Folge_01_CH_Subs_DefaultZhcnButNotShow.mp4 -i subtitle.srt -codec copy -map 0 softSubtitle.mp4 ffmpeg -i CTT_Folge_01_CH_Subs_DefaultZhcnButNotShow.mp4 -i subtitle.srt -c copy -c:s mov_text movTextSubtitle.mp4
【已解决】ffmpeg嵌入硬编码烧录ass字幕到视频中即字幕成为视频内容本身
ffmpeg -i CTT_Folge_01_CH_Subs_DefaultZhcnButNotShow.mp4 -vf ass=subtitle.ass burnedInAssSubtitle.mp4
对应指定字幕属性可以参考之前的:
【已解决】调节ass字幕配置字幕字体大小和背景色再用ffmpeg嵌入视频中
【已解决】ass字幕文件中如何设置字幕的半透明背景色
【已解决】用Aegisub字幕编辑器去调整字体大小和字幕背景半透明效果
还是去研究看看参数
搞清楚,字幕嵌入到视频中,是soft软字幕=其中一个stream 还是 硬字幕=hard=字幕变成视频数据本身
ffmpeg merge srt
ffmpeg -i infile.mp4 -i infile.srt -c copy -c:s mov_text outfile.mp4 -vf subtitles=infile.srt will not work with -c copy
此种做法是:软字幕
- 需要播放器支持解析字幕的流
- 比如VLC
在ffmpeg已安装了ass支持的库libass的前提下,去:
ffmpeg -i mymovie.mp4 -vf ass=subtitles.ass mysubtitledmovie.mp4
此种做法是:硬字幕=hard=字幕被 burn 烧录 到 视频中=字幕变成视频数据的一部分
解释更清楚:
硬字幕=hardsubs=hard subs=hard subtitles=burn in subtitles:
用-vf参数:
ffmpeg -i video.mp4 -vf "subtitles=subs.srt:force_style='Fontsize=24,PrimaryColour=&H0000ff&'" -c:a copy output.mp4
软字幕=soft subs=soft subtitles:
用stream copy流拷贝模式:
ffmpeg -i input.mkv -i subtitles.ass -codec copy -map 0 -map 1 output.mkv
关于参数的解释详见官网:
“10.187 subtitles
Draw subtitles on top of input video using the libass library.”
但是写的是:在输入视频的上方显示字幕,而不是希望的,指定位置,视频的下方显示字幕
后记:此处top不是字幕位置,而是z轴,显示的layer层次,即字幕的layer在video的layer之上
ffmpeg -i infile.mp4 -f srt -i infile.srt -c:v copy -c:a copy -c:s mov_text outfile.mp4
所以还要继续找:
如何烧录字幕到视频时,还能指定字幕位置
那还是继续研究参数
-vf “subtitles=subs.srt:…”
不过官网解释的逻辑相对比较清楚:
支持burn烧录字幕到视频中=硬字幕
有两种filter过滤器:
- subtitles=srt
- ass
【硬字幕:subtitles】
效果:用libass库实现了,在输入的视频 上方 显示字幕
前提:ffmpeg开启了libass=编译时加了参数–enable-libass
实现方式:
方式1:有单独的字幕文件 :subtitle.srt
ffmpeg -i video.avi -vf subtitles=subtitle.srt out.avi
方式2:字幕是内嵌在container容器中,比如mkv视频本身video.mkv
ffmpeg -i video.mkv -vf subtitles=video.mkv out.avi
【硬字幕:ass】
效果和逻辑:
- 类似于上面的subtitles的filter,不过不需要libavcodec和libavformat
前提:ffmpeg开启了libass=编译时加了参数–enable-libass
限制:仅限于ass字幕文件
方式:
ffmpeg -i video.avi -vf "ass=subtitle.ass" out.avi
另外:
也支持:Picture-based subtitles=基于图片的字幕
方式:
ffmpeg -i input.mkv -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a <output options> output.mkv
参数说明:
- 如果是多个stream流,可以把[0:s] 换成对应的 [0:s:0] 或 [0:s:1]
注意:
当视频有多个音频流,此种方式可能会破坏编码,则用下面方式去修复:
ffmpeg -i input.ts -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a:0 <output options> output.mkv
Windows环境:注意设置字体的路径
详见:
先确认此处的ffmpeg是开启ass的编译参数
–enable-libass
的:
# ffmpeg -version ffmpeg version 4.2-tessus https://evermeet.cx/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers built with Apple LLVM version 10.0.1 (clang-1001.0.46.4) configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100
然后再去试试,对于srt,直接内嵌 烧录burn 硬字幕:
ffmpeg -i input/5d41d82f52247ce73d40475b_extendedAll.mp4 -vf subtitles=input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b_addedSrt.mp4
开始处理:

ffmpeg -i input/5d41d82f52247ce73d40475b_extendedAll.mp4 -vf subtitles=input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b_addedSrt.mp4 ffmpeg version 4.2-tessus ... Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input/5d41d82f52247ce73d40475b_extendedAll.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.29.100 Duration: 00:02:15.05, start: 0.000000, bitrate: 758 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 700x510 [SAR 1:1 DAR 70:51], 622 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) Metadata: handler_name : SoundHandler Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264)) Stream #0:1 -> #0:1 (aac (native) -> aac (native)) Press [q] to stop, [?] for help [Parsed_subtitles_0 @ 0x7faf85508740] Shaper: FriBidi 0.19.2 (SIMPLE) [Parsed_subtitles_0 @ 0x7faf85508740] Using font provider coretext [libx264 @ 0x7faf87009400] using SAR=1/1 [libx264 @ 0x7faf87009400] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 [libx264 @ 0x7faf87009400] profile Progressive High, level 3.0, 4:2:0, 8-bit [libx264 @ 0x7faf87009400] 264 - core 157 r2969 d4099dd - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'output/5d41d82f52247ce73d40475b_addedSrt.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.29.100 Stream #0:0(und): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 700x510 [SAR 1:1 DAR 70:51], q=-1--1, 25 fps, 12800 tbn, 25 tbc (default) Metadata: handler_name : VideoHandler encoder : Lavc58.54.100 libx264 Side data: cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1 Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) Metadata: handler_name : SoundHandler encoder : Lavc58.54.100 aac [Parsed_subtitles_0 @ 0x7faf85508740] fontselect: (Arial, 400, 0) -> /Library/Fonts/Arial.ttf, -1, ArialMT [Parsed_subtitles_0 @ 0x7faf85508740] Glyph 0x6211 not found, selecting one more font for (Arial, 400, 0) [Parsed_subtitles_0 @ 0x7faf85508740] fontselect: (Arial, 400, 0) -> /System/Library/Fonts/PingFang.ttc, -1, PingFangSC-Regular frame= 3376 fps= 71 q=-1.0 Lsize= 12188kB time=00:02:15.02 bitrate= 739.4kbits/s speed=2.84x video:9952kB audio:2124kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.918402% [libx264 @ 0x7faf87009400] frame I:17 Avg QP:17.22 size: 38148 [libx264 @ 0x7faf87009400] frame P:1135 Avg QP:21.74 size: 6722 [libx264 @ 0x7faf87009400] frame B:2224 Avg QP:23.31 size: 860 [libx264 @ 0x7faf87009400] consecutive B-frames: 3.7% 21.7% 11.2% 63.4% [libx264 @ 0x7faf87009400] mb I I16..4: 35.1% 36.3% 28.6% [libx264 @ 0x7faf87009400] mb P I16..4: 6.6% 7.4% 1.9% P16..4: 21.8% 6.3% 2.7% 0.0% 0.0% skip:53.5% [libx264 @ 0x7faf87009400] mb B I16..4: 0.5% 0.5% 0.1% B16..8: 15.2% 1.3% 0.2% direct: 1.3% skip:80.8% L0:45.8% L1:50.3% BI: 3.9% [libx264 @ 0x7faf87009400] 8x8 transform intra:45.6% inter:68.9% [libx264 @ 0x7faf87009400] coded y,uvDC,uvAC intra: 31.4% 69.8% 38.1% inter: 5.4% 11.5% 2.4% [libx264 @ 0x7faf87009400] i16 v,h,dc,p: 40% 47% 4% 9% [libx264 @ 0x7faf87009400] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 26% 24% 3% 3% 4% 4% 3% 4% [libx264 @ 0x7faf87009400] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 33% 14% 2% 4% 4% 5% 3% 3% [libx264 @ 0x7faf87009400] i8c dc,h,v,p: 28% 38% 22% 11% [libx264 @ 0x7faf87009400] Weighted P-Frames: Y:1.7% UV:1.2% [libx264 @ 0x7faf87009400] ref P L0: 68.1% 17.0% 11.2% 3.7% 0.0% [libx264 @ 0x7faf87009400] ref B L0: 87.7% 10.2% 2.1% [libx264 @ 0x7faf87009400] ref B L1: 98.2% 1.8% [libx264 @ 0x7faf87009400] kb/s:603.70 [aac @ 0x7faf86802e00] Qavg: 214.622
结果:

基本满足要求的
那再去试试ass字幕
先去从srt转换出ass
ffmpeg -i input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b.ass
结果:
ffmpeg -i input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b.ass ffmpeg version 4.2-tessus ... Input #0, srt, from 'input/5d41d82f52247ce73d40475b.srt': Duration: N/A, bitrate: N/A Stream #0:0: Subtitle: subrip Output #0, ass, to 'output/5d41d82f52247ce73d40475b.ass': Metadata: encoder : Lavf58.29.100 Stream #0:0: Subtitle: ass (ssa) Metadata: encoder : Lavc58.54.100 ssa Stream mapping: Stream #0:0 -> #0:0 (subrip (srt) -> ass (ssa)) Press [q] to stop, [?] for help size= 3kB time=00:02:04.21 bitrate= 0.2kbits/s speed=1.21e+05x video:0kB audio:0kB subtitle:2kB other streams:0kB global headers:1kB muxing overhead: 44.561996%
输出ass字幕
[Script Info] ; Script generated by FFmpeg/Lavc58.54.100 ScriptType: v4.00+ PlayResX: 384 PlayResY: 288 [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,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:02.68,0:00:09.16,Default,,0,0,0,,I'm a policeman in the town. All day long,I walk around!\N我是镇上的警察 整天都在巡视 Dialogue: 0,0:00:09.18,0:00:15.86,Default,,0,0,0,,I'm a policeman in the town. All day long, I walk around!\N我是镇上的警察 整天都在巡视 ...

然后再去嵌入ass字幕:
ffmpeg -i input/5d41d82f52247ce73d40475b_extendedAll.mp4 -vf "ass=output/5d41d82f52247ce73d40475b.ass" output/5d41d82f52247ce73d40475b_addedAss.mp4
结果:

效果是一样的。
然后再去看看,能否指定字幕显示位置:
【已解决】嵌入ASS字幕到mp4视频中如何指定字幕的位置
【总结】
此处,通过ffmpeg合并嵌入字幕到视频下方的具体步骤是:
需求1:如果无需操心字幕的具体位置,只需要保证字幕在视频底部
则可以直接嵌入字幕即可
其中字幕文件是srt或ass均可:
ffmpeg -i input/5d41d82f52247ce73d40475b_extendedAll.mp4 -vf subtitles=input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b_addedSrt.mp4
需求2:如果想要指定字幕的具体位置
那么先把srt文件(不支持字幕位置指定)转换为ass(可以指定字幕位置)
ffmpeg -i input/5d41d82f52247ce73d40475b.srt output/5d41d82f52247ce73d40475b.ass
再去嵌入ass字幕到视频中:
ffmpeg -i input/5d41d82f52247ce73d40475b_extendedAll.mp4 -vf "ass=output/5d41d82f52247ce73d40475b.ass" output/5d41d82f52247ce73d40475b_addedAss.mp4
其中:
字幕文件ass中,有对应的位置的参数配置
[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,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0
其中:
- Alignment:默认为2,就是底部居中
- 就满足了我们希望的:字幕在底部居中的位置
此时再去微调左右间距和底部间距时,再去改动:
MarginL, MarginR, MarginV
即可,比如:
MarginL, MarginR, MarginV 20,20,10
即可实现:
- MarginL=MarginR:左右间距20
- MarginV:底部向上间距10
转载请注明:在路上 » 【已解决】ffmpeg合并字幕到视频下方指定位置