【ffmpeg】使用 FFmpeg 在一个视频文件上添加一个循环的 GIF 水印
这段代码使用 FFmpeg 在一个视频文件 (1.mp4
) 上添加一个循环的 GIF 水印 (3.gif
),并将输出保存为另一个视频文件 (output.mp4
),(如果在使用时遇到问题,可能需要调整一些参数,例如帧率、水印的位置或大小,以满足特定的需求)。
【ffmpeg命令】
ffmpeg -i 1.mp4 -ignore_loop 0 -i 3.gif -filter_complex "[1:v]fps=10,scale=1080:1080,setsar=1[watermark];[0:v][watermark]overlay=(W-w)/2:(H-h)/2" -map 0:a -c:a copy -shortest output.mp4
【下面是对命令的分析】
-
ffmpeg
: 这是 FFmpeg 命令行工具的启动命令。 -
-i 1.mp4
: 指定输入文件1.mp4
,这是需要添加水印的视频文件。 -
-ignore_loop 0
: 告诉 FFmpeg 处理 GIF 文件 (3.gif
) 的循环信息。 -
-i 3.gif
: 指定第二个输入文件3.gif
,这是要作为水印添加到视频上的 GIF 文件。 -
-filter_complex
: 指定复杂的滤镜图。这里的滤镜主要有两个部分。-
[1:v]fps=10,scale=1080:1080,setsar=1[watermark]
: 处理水印 GIF。fps=10
设置 GIF 的帧率为每秒 10 帧,scale=1080:1080
调整水印 GIF 的大小,setsar=1
保持纵横比。 -
[0:v][watermark]overlay=(W-w)/2:(H-h)/2
: 将水印叠加在视频上。(W-w)/2:(H-h)/2
将水印放置在视频中央。
-
-
-map 0:a
: 映射输入视频文件 (1.mp4
) 的音频流。 -
-c:a copy
: 复制音频流,以保持原音频。 -
-shortest
: 在输出时指定最短的时长,以使输出视频与输入视频时长相同。 -
output.mp4
: 指定输出文件的名称,这是包含水印的视频文件。
【循环效果的特别说明】
-ignore_loop 0
的存在是为了告诉 FFmpeg 不要忽略 GIF 文件中的循环信息。同时,通过设置fps=10
滤镜,你在添加水印的时候实现了循环的效果,即以每秒 10 帧的速度播放 GIF。这样的组合确保了 GIF 在添加为水印时会按照设定的帧率循环播放,而不仅仅是播放一次。
最后使用-shortest:将会以两个流中时长较短的为准,确保输出时长与原视频相同,不然视频也会一直循环下去
【扩展延伸:ffmpeg命令 - 指定时间显示GIF特效,不循环】
使用itsoffset属性延迟展示
ffmpeg -i 1.mp4 -itsoffset 6 -i 01.gif -filter_complex "[1:v]fps=10,scale=1080:1920,setsar=1[watermark];[0:v][watermark]overlay=(W-w)/2:(H-h)/2" -map 0:a -c:a copy output.mp4
【nodeJS实现上述功能】
ffmpeg() .input(subtitleFile) .input(effectFile) .inputOptions('-itsoffset 6') .complexFilter([ `[1:v]fps=10,scale=1080:1920,setsar=1[watermark]`, `[0:v][watermark]overlay=(W-w)/2:(H-h)/2` ]) .outputOptions([ '-map 0:a', '-c:a copy', ]) .output(outFile) .on("progress", (progress) => { console.log('视频特效,进度: ' + progress.percent + '% done'); }) .on("end", () => { console.log("视频特效完成"); resolve(); }) .run();