ffmpeg再编译使⽤ffmpeg-gl-transition
本地虚拟机部署成功路线
虚拟环境:Ubuntu 7.3.0
主要按照此⽂档中: 的「Linux without EGL」路线(原因见问题 6),安装 GLEW、glfw、xvfb 等,重新编译 ffmpeg 使⽤了配置参数:
./configure --enable-nonfree --enable-libass --enable-gpl --enable-libx264 --enable-librsvg --enable-libvpx --enable-opengl \
--enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libtheora \
--enable-libvorbis --enable-libx265 \
--enable-libopus --enable-libxvid \
--enable-filter=gltransition --extra-libs='-lGLEW -lglfw -lSOIL'
# Centos
yum install glfw glfw-devel
# Ubuntu
sudo apt-get install libglfw3 libglfw3-dev
# 不到 lglfw 时,排查与尝试解决:
# ldconfig -p | grep glfw
# sudo ln -s **.so /usr/local/ffmpeg/ffmpeg_build/lib/
开发环境可以加上了配置项:./configure --enable-debug --disable-optimizations --disable-asm --disable-stripping,参考⾃:
编译安装(sudo make && sudo make install)完成后,需要运⾏起模拟的显⽰器环境:
Install xvfb:
`pkg install xorg-vfbserver`(系统环境 FreeBSD)
`apt install xvfb`(系统环境 Ubuntu)
Run xvfb:
`Xvfb :1 -screen 0 1280x1024x16`
Execute ffmpeg-gl-transition example:
`env DISPLAY=:1 ffmpeg -i media/0.mp4 -i media/1.mp4 -filter_complex gltransition -y out.mp4`
or
`env DISPLAY=:1 ffmpeg -i media/0.mp4 -i media/1.mp4 -filter_complex "gltransition=duration=4:offset=1.5:source=crosswarp.glsl" -y out.mp4`
注:headless environments 是指 ,此环境下使⽤ ffmpeg-opengl-transition 需要运⾏ xvfb,来源于:
部署使⽤涉及
1. 守护进程、后台运⾏,参考
nohup Xvfb :1 -screen 0 1280x1024x16 >/dev/null 2>&1&
2. 设置环境变量 DISPLAY=:1,临时:export DISPLAY=:1
3. 设置了环境变量之后,就可以直接使⽤ ffmpeg 命令 的 gltransition 滤镜了,检查:ffmpeg -h filter=gltransition
排查环境是否设置成功
# 查看 OpenGL 是否存在,如果返回 `Error: couldn't find RGB GLX visual or fbconfig`,跳到问题7
DISPLAY=:1 glxinfo |grep -i opengl
# 查看环境变量,是否返回设置的值
echo$DISPLAY
# 查看 Xvfb 是否运⾏
ps -aux |grep -i xvfb
能实现的效果:
测试了⽬前所有 76 个效果,全部可⽤。
⼤概有 20 个左右的效果,直接使⽤以上提供的 .glsl ⽂件合成出不来效果,原因参考:,即是⽂件中参数默认值未设置的原因,因为不会出现报错,所以没有效果的时候就⽐较难排查原因。可以⼿动修改 glsl ⽂件设置变量的值:
删掉 uniform 关键字,设置属性值,如:
# in diplacement.glsl:
uniform float strength; // =0.5
float strength =0.5; //改成这样
另外有⼀些如 luma.glsl、displacement.glsl 等的效果还需要额外的纹理图⽚资源才能处理出效果,可通过下⾯的魔改版「使⽤额外的纹理图⽚」内容解决。
特别的 TVStatic.glsl 会报着⾊器数据类型错误,通过⼿动修改 glsl ⽂件解决:
1. 设置 offset 的值
2. 删除精度字符 highp
但是合成出来的视频很⼤,所以没有考虑使⽤这个电视雪花的效果了。(其它效果 300k,这个 2000k)
出现的问题
1. 在下载安装 之后,依旧不到对应的 *.so 库?
搜索出的办法(出处忘了):
1. 怀疑是环境变量未配置,在 ~/.profile 中最后⼀⾏增加 export PATH="/usr/lib64:$PATH" 来配置环境变量
2. 将 so 库所在的⽬录 /usr/lib64 写⼊到 /etc/f 中,然后执⾏ sudo ldconfig
或者创建软链:
sudo ln -s **.so /usr/lib/
2. 如何查看环境中 OpenGL 的版本信息?引⽤⾃:
命令需要加上 Run xvfb 时对应的标识:此处为 :1
即: DISPLAY=:1 glxinfo | grep -i opengl
3. 如何快速测试所有的过场效果?
#!/usr/bin/env bash
# Example of concatenating 2 mp4s together with 1-one transitions between them.
env DISPLAY=:1 /usr/bin/ffmpeg -i /home/vagrant/code/video_maker/public/media/0.mp4 -i /home/vagrant/code/video_maker/public/media/1.mp4 -filter_co mplex "gltransition=duration=3:offset=1:source=/home/vagrant/code/video_maker/public/transitions/"$1".glsl" -loglevel 24 -y /home/vagrant/code/video_ma ker/public/media-transition/$1.mp4
# path=$1
# files=$(ls $path)
# for file_a in $files
# do temp_file=`basename $file_a`
# echo `env DISPLAY=:1 /usr/bin/ffmpeg -i /home/vagrant/code/video_maker/public/media/0.mp4 -i /home/vagrant/code/video_maker/public/media/1.mp4 -filter_complex "gltransition=duration=3:offset=1:source=/home/vagrant/code/video_maker/public/transitions/"$temp_file -loglevel 24 -y /home/vagrant/code/ video_maker/public/media-transition/$temp_file.mp4`
# done
4. ⼤部分遇到的问题都可以在 这的 Issues ⾥到参考。
5. 编译安装尝试过 Linux with EGL 的路线,因为有这句话「We default to EGL rather than GLX on Linux to make it easier to run
headless, so xvfb is no longer needed.」。然⽽,装好之后合成的视频全⿊(编译安装以及合成信息⽆报错或警告)。
6. 报错:Operation not permitted,通过上⾯的「排查环境是否设置成功」排查
1、可能因为未运⾏ Xvfb:
$ nohup Xvfb :1 -screen 0 1280x1024x16 >/dev/null 2>&1 &
2、可能环境变量 DISPLAY 未设置
7. ffmpeg 运⾏报错 setup_gl ERRORFailed to configure input pad on Parsed_gltransition_0 时,且命令 DISPLAY=:1 glxinfo | grep -i opengl 返
回 Error: couldn't find RGB GLX visual or fbconfig 时,(参考:)可尝试:
yum install mesa*
yum install freeglut*
魔改并且
⾃修改⽂件vf_gltransition.c实现⽀持输⼊视频/图⽚的透明通道
1. GL_RGB 全替换为 GL_RGBA
2. glPixelStorei 参数修改,原 ***/3 改成 ***/4,如 fromFrame->linesize[0] / 4
3. 将 query_formats ⽅法替换为(参考⾃官⽅filter:ffmpeg-
4.2.4/libavfilter/vf_rotate.c 的 query_formats ⽅法)
上⾯改完发现⽆透明通道的视频合成出来变成了绿⾊,包括默认例⼦。
:
1. 删除设置项 #define PIXEL_FORMAT (GL_RGB),将 GL_RGB 和 PIXEL_FORMAT 全替换为 c->pix_fmt
2. 在结构体 GLTransitionContext 增加属性值:
int alpha;//输⼊值设置通道属性
//判断通道值
int pix_fmt;
int channel_num;
3. ⽅法 query_formats 改为:
static int query_formats(AVFilterContext *ctx)
{
static const enum AVPixelFormat pix_fmts[]={
AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
AV_PIX_FMT_NONE
};
AVFilterFormats *fmts_list;
fmts_list =ff_make_format_list(pix_fmts);
if(!fmts_list){
return AVERROR(ENOMEM);
}
return ff_set_common_formats(ctx, fmts_list);
}
4. 增加透明属性:
static const enum AVPixelFormat alpha_pix_fmts[]={
AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE
};
5. 在⽅法 setup_gl 中增加判断:
c->alpha =ff_fmt_is_in(inLink->format, alpha_pix_fmts);
av_log(ctx, AV_LOG_DEBUG,"c->alpha: %d, inLink->format: %d\n", c->alpha, inLink->format);
//get alpha info
if(c->alpha){
c->pix_fmt = GL_RGBA;
c->channel_num =4;
}else{
c->pix_fmt = GL_RGB;
c->channel_num =3;
}
6. ⽅法 glPixelStorei 的参数修改,原 ***/3 改成 ***/c->channel_num,如 fromFrame->linesize[0] / c->channel_num 使⽤额外的纹理图⽚
⽬前⽬标是⽀持上⼀个额外的纹理图⽚,图⽚路径可输⼊。
安装 SOIL 来加载图⽚:
git clone github/kbranigan/Simple-OpenGL-Image-Library.git
cd Simple-OpenGL-Image-Library
sudo make
sudo make install
./configure 加上 --extra-libs='-lSOIL'
1. ⽂件 vf_gltransition.c 头部加上:
#include<SOIL.h>
2. 结构体 GLTransitionContext 加上:
char*extra_texture;//注意与下⾯的属性区分
GLuint extra_tex;//⽣成纹理需要⽤到,参考from
3. 输⼊项说明 gltransition_options 加上:
...
{"extra_texture","path to the gl-transition extra_texture file",OFFSET(extra_texture), AV_OPT_TYPE_STRING,{.str =NULL}, CHAR_MIN, CHAR_MAX, F LAGS },
...
4. ⽅法 setup_tex 增加:
...
if(c->extra_texture){// extra_texture
int width, height, soilPixFmt;
soilPixFmt = SOIL_LOAD_RGB;
if(c->pix_fmt == GL_RGBA){
soilPixFmt = SOIL_LOAD_RGBA;
}
unsigned char* image =SOIL_load_image(c->extra_texture,&width,&height,0, soilPixFmt);
glGenTextures(1,&c->extra_tex);
glActiveTexture(GL_TEXTURE0 +2);
glBindTexture(GL_TEXTURE_2D, c->extra_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0, c->pix_fmt, width, height,0, c->pix_fmt, GL_UNSIGNED_BYTE, image);
glUniform1i(glGetUniformLocation(c->program,"extra_tex"),2);
SOIL_free_image_data(image);
}
5. 使⽤前⼯作:
修改 glsl ⽂件,如 displacement.glsl,将其中的 uniform sampler2D displacementMap; 以及着⾊器中的 displacementMap 改为 uniform sampler2D extra_tex; 和 extra_tex
获取 glsl ⽂件⽬录,如 texture_dir/texture.png
ffmpeg -i media/0.mp4 -i media/1.mp4 -filter_complex "gltransition=source=displacement.glsl:extra_texture=texture_dir/texture.png" -y out.mp4
1. 修改额外纹理的 glsl ⽂件的⽅式,如 displacement.glsl:
//由
float displacement =texture2D(extra_tex, uv).r * strength;
//改成:
float displacement =texture2D(extra_tex,vec2(uv.x,1.0- uv.y)).r * strength;
2. 预处理纹理图⽚(垂直翻转):
transition用法搭配
ffmpeg -i texture.png -vf vflip texture-flip.png
转场边缘的问题
可通过修改⽂件中 glTexParameteri 的参数来调整,我的需求可由 GL_REPEAT 改成了 GL_CLAMP_TO_EDGE 来满⾜。参数说明同样是这篇已经介绍得很清楚了:
⾄此,转场的需求基本满⾜了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论