我想在我的视频中添加水印(在特定时间)。我研究了一些资料,上面说我需要(视频过滤器)重新编码整个视频才能添加水印,但我没有高端电脑来做这件事。如果我重新编码整个视频,大约需要 6 到 7 个小时。
不过,我想到了一些好主意。我创建了三个片段,第一个片段(19 分钟)是原始视频,第二个片段(21 秒)是需要水印的地方,第三个片段(15 分钟)也是原始视频。所以,我将水印放在第二个片段中,然后用 ffmpeg 将它们连接起来(注意:我没有重新编码所有片段。我只重新编码了第二个片段,并将它们与没有重新编码的视频合并在一起)。
但是,在播放第 2 段时,出现了卡顿等播放问题。不过,我在连接之前单独播放了这些片段,播放得很流畅。连接后,播放出现了问题。下面提供了这三个片段的 FFmpeg 详细信息
Segment 1 (Original video)
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:01:30.09, start: 0.000000, bitrate: 2258 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 2056 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 195 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Segment 2 (Watermark video)
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_2.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:00:22.10, start: 0.000000, bitrate: 5648 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 5443 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 196 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Segment 3 (Original video)
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_3.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:01:53.11, start: 0.000000, bitrate: 2269 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 2067 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 195 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Concated full video
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output_merged.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:03:45.29, start: 0.000000, bitrate: 2596 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 2393 kb/s, 29.99 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 195 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
更新 1-使用 FFMPEG 命令
Split command
ffmpeg -hide_banner -ss "0" -i "output.mp4" -t "90" -avoid_negative_ts make_zero -map "0:0" "-c:0" copy -map "0:1" "-c:1" copy -map_metadata 0 -movflags "+faststart" -ignore_unknown -f mp4 -y "tmp/output_1.mp4"
ffmpeg -hide_banner -ss "90" -i "output.mp4" -t "20" -avoid_negative_ts make_zero -map "0:0" "-c:0" copy -map "0:1" "-c:1" copy -map_metadata 0 -movflags "+faststart" -ignore_unknown -f mp4 -y "tmp/output_2.mp4"
ffmpeg -hide_banner -ss "110" -i "output.mp4" -t "111" -avoid_negative_ts make_zero -map "0:0" "-c:0" copy -map "0:1" "-c:1" copy -map_metadata 0 -movflags "+faststart" -ignore_unknown -f mp4 -y "tmp/output_3.mp4"
Applying watermark command
ffmpeg -hide_banner -i "tmp/output_2.mp4" -vf "drawtext='fontfile=DejaVu Sans\:style=Semibold:text=HelloWorld:fontcolor=white:fontsize=30:y=h-50*t:x=w-(t-4.5)*(w+tw)/15'" -vcodec libx264 -crf 15 -c:a copy "tmp/watermark_output_2.mp4"
Concat files command
ffmpeg -f concat -safe 0 -i "../filelist.txt" -c copy "output_merged.mp4"
更新-已上传2个输出视频。
第 1 段原始视频(未重新编码) https://drive.google.com/file/d/1Mg7rJxXGcxg25328flJ_CD9NJhfpFj37/view?usp=sharing
第 2 段水印视频(重新编码) - 水印从 4 秒开始,播放时没有任何问题。
https://drive.google.com/file/d/141KYQ1m94bIpxKj5n7_wCcbTOWQ9uO17/view?usp=sharing
第 3 部分原始视频(未重新编码)
https://drive.google.com/file/d/1fYkFvD6Yg81Un7YhfUJbSJ-VBk2qlFvJ/view?usp=sharing
连接完整视频(问题从出现水印时开始。(时间 00:01:28 分钟)
https://drive.google.com/file/d/1Tq6wXSWGSeAHBwfsV31-Qpt5BhJeWwSJ/view?usp=sharing
连接过程中重复出现错误
[mp4 @ 0x5594ce3c8280] Non-monotonous DTS in output stream 0:0; previous: 8099300, current: 1715482; changing to 8099301. This may result in incorrect timestamps in the output file.
答案1
正如评论和记录所示,使用Concat 解复用器,所有文件必须具有相同的流(相同的编解码器,相同的时间基准等),并且在您的情况下重新编码部分的时间基准是不同的。
还有其他问题:
- 对于无需重新编码的连接,我们通常喜欢所有以关键帧。
- MP4容器不是设计为“分段”的,我们最好使用其他容器。
以下解决方案可能并不适用于所有情况,但我认为它适用于您的情况(H.264 视频编解码器和 AAC 音频编解码器):
我们最好-ss
使用-t
段复用器。
我们也可以使用 FLV 容器格式(它更适合连接,并且解决了时间基准问题):
ffmpeg -i input.mp4 -c copy -f segment -segment_time 20 -segment_list list.txt -segment_list_type ffconcat %04d.flv
默认情况下,Segment Muxer 仅在关键帧处断开部分(-break_non_keyframes
默认情况下为 false)
找到相关段并创建副本:copy 0001.flv original_0001.flv
。
在相关片段中添加水印(可能要手动调整时间):
ffmpeg -y -hide_banner -i "original_0001.flv" -vf "drawtext='fontfile=DejaVuSans.ttf:text=HelloWorld:fontcolor=white:fontsize=30:y=h-50*t:x=w-(t-4.5)*(w+tw)/15'" -vcodec libx264 -crf 15 -c:a copy "0001.flv"
(请注意,该style=Semibold
参数给了我一个错误)。
将片段重新连接起来,无需重新编码(可以使用 MP4 输出文件格式):
ffmpeg -y -f concat -safe 0 -i list.txt -c copy output.mp4