ffmpeg 各种视频特效

ffmpeg gl-transitions 图片合成视频 转场特效

插件本身支持 GPU 加速功能,需要用到 EGL 安装模式,本案例没有使用 EGL,部署环境为 Ubuntu 20.04
安装 :

sudo apt-get -y install gcc g++ make xorg-dev pkg-config  libglew-dev libglfw3-dev nasm yasm libx264-dev libx265-dev libvpx-dev libglu1-mesa-dev libmp3lame-dev libopus-dev libfdk-aac-devcd ~
git clone https://github.com/transitive-bullshit/ffmpeg-gl-transition.git
cd ffmpeg-gl-transition
git clone https://github.com/gl-transitions/gl-transitions.git
cd ..
wget https://www.ffmpeg.org/releases/ffmpeg-4.4.4.tar.gz
tar -zxvf ffmpeg-4.4.4.tar.gz
无法直接使用ffmpeg.diff
1. 拷贝vf_gltransition.c到libavfilter,将以下注释掉
#ifndef __APPLE__
# define GL_TRANSITION_USING_EGL // remove this line if you don't want to use EGL
#endif
2. 在libavfilter/Makefile里加入
OBJS-$(CONFIG_GLTRANSITION_FILTER)           += vf_gltransition.o
3. 在libavfilter/allfilters.c加入
extern AVFilter ff_vf_gltransition;
修改完后开始编译:
请查看下边的编译命令./configure
make -j
sudo make install
sudo apt-get -y install xvfb
安装完成!!!!

验证:ffmpeg——————————————证明安装成功
在这里插入图片描述
查看视频编码格式

ffprobe file.mp4 -show_streams -select_streams v -print_format json 

改变视频编码为h264

ffmpeg -i 1.mp4 -c:v libx264 out.mp4
需要指定 H264规范中的 Main 或者 Baseline 时:
ffmpeg -i 1.mp4 -c:v libx264 -profile:v main -pix_fmt yuv420p out.mp4

试用了ffmpeg gl-transitions之后发现ffmpeg4.3以后自带的xfade也是很好用的(这个一定要注意,两个视频的 !帧率必须相同!)

ffmpeg -i 视频1 -i 视频2 -filter_complex "[0:v][1:v]xfade=transition=pixelize:offset=2.7s:duration=1s" -c:v libx264 -r 15 -y output.mp4

两张图片合成一张图片

ffmpeg -re -i nanhai.jpg -re -i nanhai.jpg  -filter_complex "nullsrc=size=7680x4320 [base];[0:v] setpts=PTS-STARTPTS,scale=3840x2160 [upperleft];[1:v] setpts=PTS-STARTPTS, scale=3840x2160 [upperright]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=3840" -y output.jpg

视频贴到指定图像上,且视频可以指定缩放宽高

ffmpeg -loop 1 -i 1.jpg -i 2.mp4 -filter_complex "[1] scale=视频缩放宽度:-1 ,[0] overlay=X位置:Y位置:shortest=1,format=yuv420p" -y output.mp4

添加音频,指定视频持续时间(不指定,音频时长大于视频时长,后边都是黑屏)
音频时长可以用:1.图片合成视频时 duration=len(img)/fps 2.使用FFprobe获取视频时间duration

图片合成视频添加声音(必须指定视频时间):
ffmpeg -f image2 -r 帧数 -i %04d.jpg -i 背景音乐  -t 视频时间 -y output.mp4
视频直接添加声音(这个方法不用指定视频时间):
ffmpeg -i 视频 -i 背景音乐 -filter_complex " [1:0] apad " -shortest -y output.mp4

图像平移生成视频

从左到右
ffmpeg -y -i 1.jpg -vf "zoompan='1.5':x='if(lte(on,-1),(iw-iw/zoom)/2,x+3)':y='if(lte(on,1),(ih-ih/zoom)/2,y)':d=150"  1.mp4
从右到左
ffmpeg -y -i 1.jpg -vf "zoompan='1.5':x='if(lte(on,1),(iw/zoom)/2,x-3)':y='if(lte(on,1),(ih-ih/zoom)/2,y)':d=150"  1.mp4
从上到下
ffmpeg -y -i 1.jpg -vf "zoompan='1.5':x='if(lte(on,1),(iw-iw/zoom)/2,x)':y='if(lte(on,-1),(ih-ih/zoom)/2,y+2)':d=150"  1.mp4
从下到上
ffmpeg -y -i 1.jpg -vf "zoompan='1.5':x='if(lte(on,1),(iw-iw/zoom)/2,x)':y='if(lte(on,1),(ih/zoom)/2,y-2)':d=150"  1.mp4从左上到右下
ffmpeg -y -i frame143.jpg -vf "scale=1920x1080,zoompan='1.2':x='if(lte(on,-1),(iw-iw/zoom)/2,x+2)':y='if(lte(on,-1),(ih-ih/zoom)/2,y+1)':d=50:s=1920x1080"  out.mp4
从右下到左上
ffmpeg -y -i frame143.jpg -vf "scale=1920x1080,zoompan='1.2':x='if(lte(on,1),(iw/zoom)/2,x-3)':y='if(lte(on,1),(ih-ih/zoom)/2,y-2)':d=50:s=1920x1080"  out.mp4

视频画中画

ffmpeg -i 11.mp4 -i 11.mp4 -filter_complex "[1]scale=iw-60:ih-60[pip];[0][pip]overlay=main_w-overlay_w-30:main_h-overlay_h-30" -y -q:v 1 -max_muxing_queue_size 1024 "out.mp4"

Python 调用ffmpeg方法:

import subprocess
str_cmd = ' -i 视频 -y output.mp4'
subprocess.call('ffmpeg '+str_cmd,shell=True)

Android调用方法:

form ... import FFmpegKit
str_cmd = ' -i 视频 -y output.mp4'
FFmpegKit.execute(str_cmd)

python ffmpeg 处理视频后合成视频(带音频)


import numpy as np
from tqdm import tqdm
import random
import time
import ffmpeg # ffmpeg-pythondef get_video_meta_info(video_path):ret = {}probe = ffmpeg.probe(video_path)video_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'video']has_audio = any(stream['codec_type'] == 'audio' for stream in probe['streams'])ret['width'] = video_streams[0]['width']ret['height'] = video_streams[0]['height']ret['fps'] = eval(video_streams[0]['avg_frame_rate'])ret['audio'] = ffmpeg.input(video_path).audio if has_audio else Noneret['nb_frames'] = int(video_streams[0]['nb_frames'])return retdef Writer (audio, out_height, out_width, video_save_path, fps):if audio is not None:stream_writer = (ffmpeg.input('pipe:', format='rawvideo', pix_fmt='bgr24', s=f'{out_width}x{out_height}',framerate=fps).output(audio,video_save_path,pix_fmt='yuv420p',vcodec='libx264',loglevel='error',acodec='copy',r=30).overwrite_output().run_async(pipe_stdin=True, pipe_stdout=True, cmd='ffmpeg'))else:stream_writer = (ffmpeg.input('pipe:', format='rawvideo', pix_fmt='bgr24', s=f'{out_width}x{out_height}',framerate=fps).output(video_save_path,pix_fmt='yuv420p', vcodec='libx264',loglevel='error',r=30).overwrite_output().run_async(pipe_stdin=True, pipe_stdout=True, cmd='ffmpeg'))return stream_writerinput_vid = '1.mp4'
video_save_path = 'results/'+str(random.randint(0,100))+str(int(time.time()*1000000))+'.mp4'
stream_reader = (ffmpeg.input(input_vid).output('pipe:',format='rawvideo', pix_fmt='bgr24',loglevel='error').run_async(pipe_stdin=True, pipe_stdout=True, cmd='ffmpeg'))meta = get_video_meta_info(input_vid) # 获取视频参数,宽/高/帧率/音频/总帧数
width = meta['width']
height = meta['height']
fps = meta['fps']
audio = meta['audio']
nb_frames = meta['nb_frames']stream_writer = Writer(audio, height, width, video_save_path, fps)pbar = tqdm(total=nb_frames, unit='frame', desc='inference')
while True:img_bytes = stream_reader.stdout.read(width * height * 3)  # 3 bytes for one pixelif not img_bytes: breakimg = np.frombuffer(img_bytes, np.uint8).reshape([height, width, 3])print('infer for your image')stream_writer.stdin.write(img.astype(np.uint8).tobytes())pbar.update(1) # 更新进度条stream_writer.stdin.close()
stream_writer.wait()

ffmpeg 使用gpu 加速解码

编译:
./configure --pkg-config-flags="--static" --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --extra-libs=-lpthread --extra-libs=-lm --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-cuda --enable-cuvid --enable-nvenc --enable-libnpp --enable-openssl --enable-libass --enable-libfdk-aac --enable-libtheora --enable-libxvid --enable-opengl --enable-filter=gltransition --extra-libs='-lGLEW -lglfw -ldl' --enable-pthreadsprefix编译出的ffmpeg位置(可以不选,直接安装到系统默认位置)(注意:如果选择了安装路径可能使用进程守护时会出问题)
openssl网络图片下载,libass添加字幕,pthreads允许使用多线程
extra-cflags和extra-ldflags是cuda路径
--enable-opengl --enable-filter=gltransition --extra-libs='-lGLEW -lglfw -ldl'是gltransition转场,如果想使用GPU转场更换为--extra-libs='-lGLEW -lEGL',需要EGL才能使用GPU。
如果需要使用xfade做转场特效并且使用里面所有的特效,请下载最新的代码并进行编译才可以获得,可以在libavfilter/vf_xfade.c查看
make
sudo make install 
export PATH=$PATH:/usr/local/ffmpeg/bin
export LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:$LD_LIBRARY_PATH 
命令中使用GPU编码:-c:v h264_nvenc
卸载ffmpeg,去编译目录下sudo make uninstall

创建画布

-f lavfi -i color=#123000:s=368x640 虚拟color背景368x640幕布做音频背景输入

opencv+ffmpeg

import numpy as np
import random
import time
import cv2
import ffmpeg # ffmpeg-pythoncamera=cv2.VideoCapture('rtsp://admin:123456789.@192.168.2.43/MPEG-4/ch1/main/av_stream') # 网络摄像头,也可以使用本地0或1
video_size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))) # 获取摄像头w,h
fps = camera.get(cv2.CAP_PROP_FPS) # 获取摄像头帧率 !!!!!!!!!!video_save_path = 'results/'+str(random.randint(0,100))+str(int(time.time()*1000000))+'.mp4'
stream_writer = (ffmpeg.input('pipe:', format='rawvideo', pix_fmt='bgr24', s=f'{video_size[0]}x{video_size[1]}',framerate=fps).output(video_save_path,pix_fmt='yuv420p', vcodec='libx264',loglevel='error',r=30).overwrite_output().run_async(pipe_stdin=True, pipe_stdout=True, cmd='ffmpeg'))while(True):ret,frame=camera.read()if not ret: breakprint('infer for your image')stream_writer.stdin.write(frame.astype(np.uint8).tobytes())stream_writer.stdin.close()
stream_writer.wait()


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部