22、画中画:将一个视频叠加到另一个视频的指定位置、调整大小与透明度

画中画(PiP,Picture-in-Picture)这个功能,大家应该都不陌生。直播的时候把主播的小窗口放在游戏画面角落,或者做教程视频时把操作演示放在屏幕一角,都是典型的应用场景。

说白了,就是用 FFmpeg 把一路视频流「贴」到另一路视频流的上面。听起来简单,但真要做得漂亮——位置要对、大小要合适、透明度要自然,还是有不少门道的。

我个人习惯把画中画拆成三个核心问题:放哪、多大、多透。今天我们就一个一个来解决。

核心思路:overlay 滤镜

FFmpeg 里做画中画,主力就是 overlay 滤镜。它的基本用法是这样的:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex "[0:v][1:v]overlay=W-w-10:10" output.mp4

这个命令把 overlay.mp4 放在了主视频的右上角,距离右边和上边各 10 像素。

你可能会问:W-w-10 是什么鬼?

嗯,这里有个小知识点。WH 代表主视频的宽高,wh 代表叠加视频的宽高。所以 W-w-10 就是「主视频宽度减去叠加视频宽度再减 10」,正好让叠加视频贴着右边。

小技巧: 如果你想让叠加视频居中,可以用 overlay=(W-w)/2:(H-h)/2。这个公式我经常用,记下来很实用。

调整大小:scale 滤镜配合

很多时候,叠加视频的原始分辨率并不合适。比如你的主视频是 1920x1080,但叠加视频是 4K 的,直接贴上去就太大了。

这时候需要先缩放,再叠加:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex "[1:v]scale=320:240[ovr];[0:v][ovr]overlay=10:10" output.mp4

这里 [1:v]scale=320:240[ovr] 的意思是:把第二个输入的视频缩放到 320x240,然后把这个结果命名为 [ovr],再和主视频叠加。

我在项目中遇到过一种情况:叠加视频的比例和缩放后的比例不一致,结果画面被拉伸变形了。后来我改用 scale=320:-1,让 FFmpeg 自动根据宽度计算高度,保持原始比例。这样就不会变形了。

注意: 如果叠加视频是竖屏的,而你硬要缩成横屏的尺寸,画面会被压扁。建议始终用 -1 让 FFmpeg 自动保持比例。

调整透明度:format 与 colorchannelmixer

透明度这块稍微复杂一点。FFmpeg 的 overlay 滤镜本身支持 alpha 通道,但前提是你的叠加视频必须包含 alpha 信息。

如果叠加视频没有 alpha 通道(比如普通的 MP4 文件),我们可以用 colorchannelmixer 来模拟透明度:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex "[1:v]format=rgba,colorchannelmixer=aa=0.5[ovr];[0:v][ovr]overlay=10:10" output.mp4

这个命令里,format=rgba 先把叠加视频转成 RGBA 格式(增加 alpha 通道),然后 colorchannelmixer=aa=0.5 把 alpha 值设为 0.5(半透明)。

你想想看,如果透明度设为 0.3,叠加视频就会像水印一样若隐若现。这个技巧在做片头片尾或者品牌水印时特别有用。

综合实战:一个完整的画中画案例

下面是一个综合案例,把叠加视频放在右下角,缩放到 480x270,透明度设为 70%:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex \
"[1:v]scale=480:270,format=rgba,colorchannelmixer=aa=0.7[ovr]; \
 [0:v][ovr]overlay=W-w-20:H-h-20" \
output.mp4

这个命令做了三件事:

  • 缩放叠加视频到 480x270
  • 转为 RGBA 并设置透明度 0.7
  • 放在右下角,距离边缘 20 像素

我曾经给一个客户做直播录播系统,需要把讲师的小窗口放在 PPT 的右下角。当时用的就是类似的命令,只不过把 scale 改成了动态参数,根据主视频分辨率自动计算缩放比例。

进阶:动态位置与淡入淡出

如果你想让画中画动起来——比如从左边滑入,或者淡入淡出——可以用 overlay 配合 enable 参数或者 fade 滤镜。

举个例子,让叠加视频在 2 秒后从左侧滑入:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex \
"[1:v]scale=320:240[ovr]; \
 [0:v][ovr]overlay=x='if(gte(t,2),-w+(t-2)*100,NAN)':y=10" \
output.mp4

这里 x='if(gte(t,2),-w+(t-2)*100,NAN)' 的意思是:当时间 t 大于等于 2 秒时,x 坐标从 -w(画面左侧之外)开始,每秒向右移动 100 像素。这样看起来就是滑入的效果。

核心要点: overlay 的 x 和 y 参数支持表达式,你可以用 t(时间)、w、h、W、H 等变量做各种动态效果。这是画中画进阶玩法的基础。

知识体系图

下面这张图帮你梳理画中画的核心逻辑:

画中画核心逻辑 主视频 [0:v] 叠加视频 [1:v] scale 缩放处理 format + colorchannelmixer 透明度 overlay 叠加(位置 + 动态表达式) 三个核心步骤:缩放 → 透明度 → 叠加位置

常见问题与避坑

做画中画的时候,有几个坑我踩过,分享给你:

  • 音频问题: 默认情况下,overlay 只处理视频流。如果你想要两个视频的音频都保留,需要额外处理音频流。用 -map 参数可以解决。
  • 性能问题: 叠加 4K 视频时,如果叠加视频分辨率很高,先缩放再叠加能大幅提升编码速度。我曾经没注意这个,一个 10 分钟的视频跑了快两个小时。
  • 坐标计算: 如果你用 overlay=10:10,叠加视频的左上角会放在 (10,10) 的位置。如果你想让叠加视频的右下角对齐主视频的右下角,用 overlay=W-w:H-h
我的习惯: 在做画中画之前,先用 ffprobe 查看两个视频的分辨率和帧率。如果帧率不一致,叠加后可能会出现卡顿。这时候可以用 fps 滤镜统一帧率。

好了,画中画的核心内容就这些。从位置、大小到透明度,再到动态效果,其实都是围绕 overlay 滤镜展开的。你只要掌握了 scaleformatcolorchannelmixer 这几个辅助滤镜,再加上坐标表达式,就能做出各种花样的画中画效果。

下次做视频的时候,试试把 logo 或者水印用半透明的方式叠加到画面上,效果会很专业。


公众号:蓝海资料掘金营,微信deep3321