[FFmpeg滤镜增强能力]在FFmpeg中使用OpenGL 自定义Shader渲染视频媒体素材

O 背景

相信很多人不满足于FFmpeg已有的Filters,对于现有FFmpeg支持Animation动画能力很不满足
确实,FFmpeg本身的Filter滤波器并非为动画而作,而是核心服务于编解码/转码的用户需求
同时我们也知道,OpenGL作为动画 2D/3D特效算法开发的首选能力,正好可以弥补FFmpeg对于特效渲染的短板。

今天要给的解决方案:如何在FFmpeg Cmd中使用 OpenGL 自定义 Shader 渲染视频媒体素材。

主要介绍 FFmpeg-Plus-OpenGL 滤镜对于这个困境的解决方案。


1 FFmpeg-Plus-OpenGL

滤镜:https://github.com/numberwolf/FFmpeg-Plus-OpenGL

FFmpeg-Plus-OpenGL 是一个 FFmpeg 下支持OpenGL的扩展滤波器,此项目为一个Patch,可以直接将滤镜编译到自己的FFmpeg4+(FFmpeg3的滤镜 Patch有所不同,略微更改即可)

source render
image.png
image.png


使用步骤如下

安装 编译

  • 相关依赖

    • Centos 7.x+ || Linux

      • 第一步 安装相关依赖

        yum install -y glew*
        yum install -y glfw*
        
        #
        # If can not compile , you need
        #
        yum install -y libGLEW*
        yum install -y mesa
        yum install -y mesa-libGLU mesa-libGLU-devel
        
      • 第二步(可选)

        如果你在无显卡环境下跑此滤镜(比如你的生产环境服务器),需要xvfb的支持

        yum install -y xorg-x11-server-Xvfb
        
    • Ubuntu || Linux

      • 第一步 安装相关依赖

        apt-get install libglfw3-dev libglfw3
        apt-get install libglew2.0 libglew-dev
        
      • 第二步(可选)

        如果你在无显卡环境下跑此滤镜(比如你的生产环境服务器),需要xvfb的支持

        apt-get install xvfb
        
    • MacOS下编译 (需要brew支持)

      brew install glew glfw
      


  • 编译构建

    • 下载源码

      git clone https://github.com/numberwolf/FFmpeg-Plus-OpenGL.git
      git clone https://github.com/FFmpeg/FFmpeg.git # for 4.x+
      
      cd FFmpeg
      
      #
      # Patch
      #
      cp ../FFmpeg-Plus-OpenGL/Plus-GL-Shader/vf_plusglshader.c libavfilter/
      git apply ../FFmpeg-Plus-OpenGL/Plus-GL-Shader/libavfilter.diff
      
    • 编译

      • 编译的必选项 - 和此滤镜相关

        --enable-opengl
        --extra-libs='-lGLEW -lglfw'
        --enable-filter=plusglshader

      • 编译示例 - 可以不参考此示例,但是必须加上必选项

        #!/bin/bash
        ./configure \
          --enable-cross-compile \
          --pkg-config-flags="--static" \
          --extra-ldflags="-lm -lz -llzma -lpthread" \
          --extra-libs=-lpthread \
          --extra-libs=-lm \
          --enable-gpl \
          --enable-libfdk_aac \
          --enable-libfreetype \
          --enable-libmp3lame \
          --enable-libopus \
          --enable-libvpx \
          --enable-libx264 \
          --enable-libx265 \
          --enable-libass \
          --enable-libfreetype       \
          --enable-libfontconfig     \
          --enable-libfribidi        \
          --enable-libwebp           \
          --enable-nonfree \
          --disable-shared \
          --enable-static \
          --enable-opengl \
          --extra-libs='-lGLEW -lglfw' \
          --enable-filter=plusglshader
        make clean
        make -j16
        make install
        


运行

  • 检查 Plus-GL-Shader:plusglshader 滤镜是否安装成功

    • 检查命令

      ffmpeg -help filter=plusglshader
      
    • 正确输出

      ffmpeg version a0d68e65 Copyright (c) 2000-2020 the FFmpeg developers
        built with Apple LLVM version 10.0.0 (clang-1000.10.44.4)
        configuration: --enable-cross-compile --pkg-config-flags=--static --extra-ldflags='-lm -lz -llzma -lpthread' --extra-libs=-lpthread --extra-libs=-lm --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libx264 --enable-libx265 --enable-libass --enable-libfreetype --enable-libfontconfig --enable-libfribidi --enable-libwebp --enable-nonfree --disable-shared --enable-static --enable-opengl --extra-libs='-lGLEW -lglfw' --enable-filter=plusglshader
        libavutil      56. 51.100 / 56. 51.100
        libavcodec     58. 91.100 / 58. 91.100
        libavformat    58. 45.100 / 58. 45.100
        libavdevice    58. 10.100 / 58. 10.100
        libavfilter     7. 85.100 /  7. 85.100
        libswscale      5.  7.100 /  5.  7.100
        libswresample   3.  7.100 /  3.  7.100
        libpostproc    55.  7.100 / 55.  7.100
      Filter plusglshader
        Generic OpenGL shader filter
          Inputs:
             #0: default (video)
          Outputs:
             #0: default (video)
      plusglshader AVOptions:
        sdsource          <string>     ..FV...... gl fragment shader source path (default is render gray color)
        vxsource          <string>     ..FV...... gl vertex shader source path (default is render gray color)
      
      This filter has support for timeline through the 'enable' option.
      
  • 使用plusglfilter转码渲染 (Transcoding)

    plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'

    • 参数项

      • sdsource : Fragment shader file path (Default is gray)
      • vxsource : Vertex shader file path (Default is gray)
    • 滤镜使用规则

      • plusglshader
      • plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'
    • 用你自己的Shader渲染

        1. Fragment shader

        Notice: playTime is timestamp, from 0 -> end

        uniform sampler2D tex;
        uniform float playTime;
        varying vec2 texCoord;
        void main() {
            gl_FragColor = texture2D(tex, texCoord * 0.5 + 0.5);
            float usePts = max(playTime, 0.4);
            float gray = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / (usePts * usePts);
            gl_FragColor.r = gray;
            gl_FragColor.g = gray;
            gl_FragColor.b = gray;
        }
        
        1. Vertex shader
        attribute vec2 position;
        varying vec2 texCoord;
        void main(void) {
            gl_Position = vec4(position, 0, 1);
            texCoord = position;
        }
        
    • 如果在无头(无显示器显卡环境下)环境下使用

      你需要xvfb server支持,使用如下命令

      xvfb-run -a --server-args="-screen 0 1280x720x24 -ac -nolisten tcp -dpi 96 +extension RANDR" \
      ffmpeg -v debug \
      -i 1000p10s_9k.mp4 \
      -filter_complex "[0:v]plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'[1outgl];[1outgl]scale=1280:-2" \
      -vcodec libx264 \
      -an \
      -pix_fmt yuv420p \
      -y test.mp4
      
    • 在有头(显卡 显示器)环境下运行

      ffmpeg -v debug \
      -i 1000p10s_9k.mp4 \
      -filter_complex "[0:v]plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'[1outgl];[1outgl]scale=1280:-2" \
      -vcodec libx264 \
      -an \
      -pix_fmt yuv420p \
      -y test.mp4
      
    • 输出示例

      Tag Src Dst
      Frame
      原图
      渲染


2 相关帮助

FFmpeg编译相关帮助


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容