ffmpeg 各种视频特效 | 教程

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
FFmpeg是一个开源的多媒体处理工具,它可以通过命令行对各种音视频进行编码、解码、转码、截取、合并等操作。在FFmpeg中,也可以利用其功能实现一些文字特效。 要在视频中添加文字特效可以通过FFmpeg的文本过滤器实现。首先,需要使用drawtext过滤器来在视频中绘制文字。通过设置参数,可以指定文字的内容、字体、大小、颜色、位置等。例如,可以使用以下命令来在视频的左上角添加一个红色的文字水印: ``` ffmpeg -i input.mp4 -vf "drawtext=text='Watermark':fontfile=/path/to/font.ttf:fontsize=24:fontcolor=red:x=10:y=10" output.mp4 ``` 上述命令中,`-vf`用于指定视频过滤器,而`drawtext`是具体的过滤器名称。`text`参数指定了要绘制的文字内容,`fontfile`参数指定了字体文件的路径,`fontsize`参数指定了字体大小,`fontcolor`参数指定了字体颜色,`x`和`y`参数指定了文字的位置。 除了绘制文字水印,FFmpeg还提供了其他一些文字特效的能力。例如,通过设置`shadowcolor`和`shadowx`、`shadowy`参数,可以给文字添加阴影效果。另外,还可以设置`bordercolor`和`borderw`参数,来给文字添加边框效果。 绘制文字特效时,还可以利用FFmpeg的时间语法功能来实现文字的动态效果。例如,通过使用`enable`和`opacity`参数,可以实现文字的逐渐显示或消失的效果。 综上所述,FFmpeg提供了方便实用的文本过滤器,可以用于在视频中添加各种文字特效。通过设置不同的参数,可以实现丰富多样的效果,例如文字水印、阴影、边框等。使用FFmpeg的文本过滤器,可以为视频增加更加个性化和独特的视觉效果。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值