zoukankan      html  css  js  c++  java
  • FFmpeg中overlay滤镜用法-水印及画中画

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10434209.html

    1. overlay 技术简介

    overlay 技术又称视频叠加技术。overlay 视频技术使用非常广泛,常见的例子有,电视屏幕右上角显示的电视台台标,以及画中画功能。画中画是指在一个大的视频播放窗口中还存在一个小播放窗口,两个窗口不同的视频内容同时播放。

    overlay 技术中涉及两个窗口,通常把较大的窗口称作背景窗口,较小的窗口称作前景窗口,背景窗口或前景窗口里都可以播放视频或显示图片。FFmpeg 中使用 overlay 滤镜可实现视频叠加技术。

    overlay 滤镜说明如下:

    描述:前景窗口(第二输入)覆盖在背景窗口(第一输入)的指定位置。
    
    语法:overlay[=x:y[[:rgb={0, 1}]]
        参数 x 和 y 是可选的,默认为 0。
        参数 rgb 参数也是可选的,其值为 0 或 1,默认为 0。
    
    参数说明:
        x                   从左上角的水平坐标,默认值为 0
        y                   从左上角的垂直坐标,默认值为 0
        rgb                 值为 0 表示输入颜色空间不改变,默认为 0;值为 1 表示将输入的颜色空间设置为 RGB
    
    变量说明:如下变量可用在 x 和 y 的表达式中
        main_w 或 W          主输入(背景窗口)宽度
        main_h 或 H          主输入(背景窗口)高度
        overlay_w 或 w       overlay 输入(前景窗口)宽度
        overlay_h 或 h       overlay 输入(前景窗口)高度
    

    overlay 滤镜相关参数示意图如下:
    overlay_filter

    2. 命令行用法

    可先参考 "FFmpeg 使用基础" 了解 FFmpeg 命令行基本用法。

    overlay 命令行基本格式如下:

    ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output
    

    input1 是背景窗口输入源,input2 是前景窗口输入源。

    2.1 视频中叠加图标

    背景窗口视频素材下载(右键另存为):ring.mp4
    ring.mp4
    视频分辨率是 768x432(此分辨率适用于平板电脑,宽高比为 16:9),上下黑边的像素高度是 56,播放时长为 37.97 秒。关于分辨率与黑边的相关内容可参考如下:
    为什么很多人把视频上下加黑条当做“电影感”?
    用于编码视频文件的视频预设

    前景窗口图标素材下载(右键另存为):ring_100x87.png
    ring.png
    图标分辨率是 100x87。图标格式为 PNG 格式,当然选用其他格式的图片作图标也是可以的,但 PNG 图标具有透明背景,更适合用作图标。

    2.1.1 直接叠加图标

    将图标叠加于视频右上角:("-max_muxing_queue_size" 参数的使用见参考资料[3])

    ffmpeg -i ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 ring_logo_t.mp4
    

    效果如下:
    ring_logo_t.jpg

    将图标叠加于视频右下角:

    ffmpeg -i ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:H-h-56 -max_muxing_queue_size 1024 ring_logo_b.mp4
    

    效果如下:
    ring_logo_b.jpg

    2.1.2 延时叠加图标

    如下,背景窗口播放 8.6 秒后,图标开始显示。注意 “-itsoffset 8.6” 作为第二个输入文件的输入选项,参数位置不能放错。

    ffmpeg -i ring.mp4 -itsoffset 8.6 -i ring_100x87.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 ring_logo_delay.mp4
    

    2.2 视频中叠加视频——画中画

    视频中叠加视频即为画中画功能。注意两个视频仅图像部分会叠加在一起,声音是不会叠加的,有一个视频的声音会消失。

    2.2.1 叠加计时器

    找一个计时器小视频,将之叠加到背景视频上。我们可以从测试源中获取这个计时器视频。先运行如下命令:

    ffplay -f lavfi -i testsrc
    

    视频无法贴在本文里,那运行截图命令,从视频中截取一张图:

    ffmpeg -ss 00:00:12 -f lavfi -i testsrc -frames:v 1 -f image2 testsrc.jpg
    

    效果如下:
    testsrc.jpg

    我们把计时器那一小块视频裁剪下来,运行如下命令:

    ffmpeg -ss 00:00:10 -t 20 -f lavfi -i testsrc -vf crop=61:52:224:94 timer.h264
    

    此命令主要用到了 crop 视频滤镜,说明一下:
    "-vf crop=61:52:224:94" 表示裁剪一块位于 (224,94) 坐标处宽为 61 像素高为 52 像素的视频块
    "-ss 00:00:10 -t 20" 表示从 10 秒处开始裁剪,裁剪时长为 20 秒

    将计时器视频 timer.h264 叠加到背景视频 ring.mp4 里:

    ffmpeg -i ring.mp4 -i timer.h264 -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 ring_timer.mp4
    

    效果如下:
    ring_timer.jpg

    看一下视频叠加过程中 FFmpeg 在控制台中的打印信息,关注流的处理:

    $ ffmpeg -i ring.mp4 -i timer.h264 -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 ring_timer.mp4
    ......
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ring.mp4':
      Metadata:
        ......
      Duration: 00:00:37.97, start: 0.032000, bitrate: 515 kb/s
        Stream #0:0(chi): Video: h264 (avc1 / 0x31637661), none, 768x432, 488 kb/s, 23 fps, 23 tbr, 23k tbn, 46k tbc (default)
        Metadata:
          handler_name    : 1348358526.h264#video:fps=23 - Imported with GPAC 0.5.1-DEV-rev4127
        Stream #0:1(chi): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 95 kb/s (default)
        Metadata:
          handler_name    : GPAC ISO Audio Handler
    Input #1, h264, from 'timer.h264':
      Duration: N/A, bitrate: N/A
        Stream #1:0: Video: h264 (High 4:4:4 Predictive), yuv444p(progressive), 61x52 [SAR 1:1 DAR 61:52], 25 fps, 25 tbr, 1200k tbn, 50 tbc
    Stream mapping:
      Stream #0:0 (h264) -> overlay:main (graph 0)
      Stream #1:0 (h264) -> overlay:overlay (graph 0)
      overlay (graph 0) -> Stream #0:0 (libx264)
      Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    ......
    

    看 "Stream mapping" 部分可以看出:
    输入源 1 视频流 "Stream #0:0" 和输入源 2 视频流 "Stream #1:0" 叠加到输出视频流 "Stream #0:0"
    输入源 1 音频流 "Stream #0:1" 拷贝到输出音频流 "Stream #0:1"

    视频开始几秒处播放有些异常,声音播放几秒后图像才开始播放,原因不太清楚。

    3. API用法

    使用滤镜API编程,解析不同的滤镜选项,以达到和命令行中输入命令同样的效果。

    例程使用 "FFmpeg 滤镜 API 用法与实例解析" 中第 4.2 节的示例程序,运行如下命令下载例程源码:

    svn checkout https://github.com/leichn/exercises/trunk/source/ffmpeg/ffmpeg_vfilter
    

    下载之后进入源码目录,编译生成 vf_file 可执行文件:

    cd ffmpeg_vfilter
    make vf_file
    

    运行如下命令进行测试:

    ./vf_file ring.flv -vf "movie=ring_100x87.png[logo];[in][logo]overlay=W-w:56"
    

    测试效果为:
    ring_logo_t.jpg
    因为例程尚不支持多输入的方式,所以上述测试命令中借助了 movie 滤镜来加载第二个输入,这条命令和下面这条命令效果是一样的

    ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56
    

    4. 遗留问题

    第 3 节例程不支持多输入方式,借助了 movie 滤镜变通实现,多输入情况下 API 如何编程?待分析如下命令中多输入选项的解析处理方式:

    ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56
    

    5. 参考资料

    [1] 为什么很多人把视频上下加黑条当做“电影感”?
    [2] 用于编码视频文件的视频预设
    [3] Too many packets buffered for output stream

    6. 修改记录

    2019-02-16 V1.0 首次整理
    2020-01-17 V1.0 修改资源文件下载地址错误
    2020-02-23 V1.0 github 文件下载地址规则改变,修改资源文件无法下载问题

  • 相关阅读:
    对MVC模型的自悟,详尽解释,为了更多非计算机人员可以理解
    openSUSE leap 42.3 实现有线 无线同时用
    Fedora27 源配置
    Ubuntu16.04添加HP Laserjet Pro M128fn打印机和驱动
    openSUSE leap 42.3 添加HP Laserjet Pro M128fn打印机和驱动
    OpenSUSE Leap 42.3下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    OpenSUSE Leap 42.3 安装java(Oracle jre)
    linux下支持托盘的邮件客户端Sylpheed
    Ubuntu下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    Firefox 浏览器添加Linux jre插件
  • 原文地址:https://www.cnblogs.com/leisure_chn/p/10434209.html
Copyright © 2011-2022 走看看