O 背景
相信很多人不满足于FFmpeg已有的Filters,对于现有FFmpeg支持Animation动画能力很不满足
确实,FFmpeg本身的Filter滤波器并非为动画而作,而是核心服务于编解码/转码
的用户需求
同时我们也知道,OpenGL
作为动画 2D/3D特效算法开发的首选能力,正好可以弥补FFmpeg对于特效渲染的短板。
今天要给的解决方案:如何在FFmpeg Cmd中使用 OpenGL 自定义 Shader 渲染视频媒体素材。
主要介绍
FFmpeg-Plus-OpenGL
滤镜对于这个困境的解决方案。
1 FFmpeg-Plus-OpenGL
FFmpeg-Plus-OpenGL
是一个 FFmpeg 下支持OpenGL
的扩展滤波器,此项目为一个Patch
,可以直接将滤镜编译到自己的FFmpeg4+
(FFmpeg3的滤镜 Patch有所不同,略微更改即可)
- 看下这套技术方案具体给我们带来了哪些效果 (不支持GIF图 可以到 https://github.com/numberwolf/FFmpeg-Plus-OpenGL 看)
source | render |
---|---|
使用步骤如下
安装 编译
-
相关依赖
-
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渲染
-
- 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; }
-
- 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编译相关帮助
- 如果你不知道如何编译FFmpeg,请点这里https://trac.ffmpeg.org/wiki/CompilationGuide