ffmpeg命令行初学可以多使用使用“格式工厂”,格式工厂的底层是ffmpeg操作的所有步骤,都可以通过“选项-内部-open log”,
找到想要的命令行。无论是编码格式,视频拼接,视频裁剪,音频分离,混流,图片处理等等,都是比较好的处理方式。
在视频处理去重方面,可以使用CR VideoMate他的底层也是基于ffmpeg,熟悉软件的处理流程后,
可以“点击右下角-帮助-数据文件夹”找到ffmpeg的命令行log,参考学习。
字幕文件大部分都使用srt但实际ass更适用于做字幕特效,参数也会更多,使用起来比较困难,可以借助aegisub工具,
生成ass字幕文件,其中也内嵌了很多的特效和一些字体等等使用方法。
其他ffmpeg的界面化软件FFmpeg Batch AV Converter、WinFF、QWinFF、FFmpegYAG、Axiom、本人使用都不是很好用,
如果有大佬有更好的推荐,可以在评论区留言。谢谢
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-dev
cd ~
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 input.mp4 -c:v libx264 out.mp4
需要指定 H264规范中的 Main 或者 Baseline 时:
ffmpeg -i input.mp4 -c:v libx264 -profile:v main -pix_fmt yuv420p out.mp4
试用了ffmpeg gl-transitions之后发现ffmpeg4.3以后自带的xfade也是很好用的(这个一定要注意,两个视频的 !帧率必须相同!)
ffmpeg -i input1.mp4 -i input2.mp4 -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 input1.jpg -re -i input2.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 input1.jpg -i input2.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 input.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" out.mp4
从右到左
ffmpeg -y -i input.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" out.mp4
从上到下
ffmpeg -y -i input.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" out.mp4
从下到上
ffmpeg -y -i input.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" out.mp4
从左上到右下
ffmpeg -y -i input.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 input.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
截取视频片段
-ss 开始时间 -to 结束时间 -i input.mp4
缺点:裁剪时间不准确,帧率会根据原视频进行剪切和拼接其他视频,导致剪切后的视频与其他视频拼接时,时间对应不上
优点:处理速度快,写法简单
trim=start=开始时间:end=结束时间,fps=帧率,setpts=PTS-STARTPTS
缺点:处理速度很慢
优点:解决了上边的缺点
如果视频较大,且视频时长较长,最好还是先将分辨率与帧率转成一致,再进行截取+拼接,处理。
视频画中画
ffmpeg -i input1.mp4 -i input2.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-python
def 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 None
ret['nb_frames'] = int(video_streams[0]['nb_frames'])
return ret
def 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_writer
input_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 pixel
if not img_bytes: break
img = 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-pthreads
prefix编译出的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
cpu:libx264 NVIDIA:h264_nvenc AMD:h264_amf Intel:h264_qsv
创建画布
-f lavfi -i color=#123000:s=368x640 虚拟color背景368x640幕布做音频背景输入
opencv+ffmpeg
import numpy as np
import random
import time
import cv2
import ffmpeg # ffmpeg-python
camera=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: break
print('infer for your image')
stream_writer.stdin.write(frame.astype(np.uint8).tobytes())
stream_writer.stdin.close()
stream_writer.wait()
ffmpeg 特效
# 使用裁剪,实现了,上下左右的,拖拽移动
ffmpeg -i in.mp4 -vf crop="in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2+((in_h-out_h)/2)*sin(n/7)" out.mp4
#
ffmpeg 找不到路径或缺少依赖
进入安装目录下 /usr/local/ffmpeg,由于没有配置ffmpeg环境变量,此时执行./ffmpeg会提示各种so链接库找不到。
sudo gedit /etc/ld.so.conf
添加到文件尾行
/usr/local/ffmpeg/lib
执行 sudo ldconfig
下载B站高清视频
pip install you-get
浏览器安装EditThisCookie 插件,首先在 EditThisCookie 的选项设置里将 选择cookies的导出格式 设置为 Netscape HTTP Cookie File
打开https://www.bilibili.com/网站,在插件中导出Cookie,粘贴到cookies.txt
使用命令查看(-i)支持下载视频的清晰度:
you-get --cookies cookies.txt -i https://www.bilibili.com/video/BV1As4y127HW
选择清晰度下载:
you-get --cookies cookies.txt --format=dash-flv-AVC https://www.bilibili.com/video/BV1As4y127HW