视频加图像水印
ffmpeg -i a.mp4 -i b.png -filter_complex overlay=x=0:y=0 out.mp4
# 每个30s 加3s水印
ffmpeg -i 1.mp4 -i 123.png -filter_complex "overlay=x=0:y=0:enable='lt(mod(t,30),3)'" -y out.mp4
ffmpeg -i 1.mp4 -i header1.mov -t 15 -filter_complex "amix=inputs=2:duration=longest;[1]scale=iw*0.5:-1[open];[0][open]overlay=x=0:y=0:repeatlast=0[o1];movie=water.png [watermark];[o1][watermark]overlay=x=0:y=0:enable='gte(t,4)'[o1];[o1]subtitles=y2.ass[o1]" -map "[o1]" ooo.mp4
图片给合成视频
ffmpeg -f image2 -i image%d.jpg video.mpg
ffmpeg -f image2 -r 60 -i output_%05d.png 1080p.mp4
视频截取
裁剪视频
按时间
ffmpeg -i 1.mp4 -vcodec copy -acodec copy -ss 00:01:00 -to 00:02:59 ./1_cut.mp4 -y
ffmpeg -ss [start] -t [duration] -i [in].mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k [out].mp4
def split_by_time(self, index, s, e):
dst = os.path.join(self.cache_video, "%s.mp4" % index)
args = ["ffmpeg", "-accurate_seek", "-i", self.media_path, "-ss", str(s), "-to", str(e), "-c:v", "libx264","-c:a", "copy", "-strict","experimental","-avoid_negative_ts", "1",dst, "-y"]
r = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
if r.returncode != 0:
print(r)
return
print("success %s" % dst)
按帧
ffmpeg -i ./input.mp4 -vf "select=between(n\,20\,200)" -y -acodec copy ./output.mp4
提取视频中的所有帧
ffmpeg -i demo_001.mp4 -vsync 0 data/%04d.png
# 只选择关键帧(I帧),因为I帧是视频序列中完整的帧,而其他帧(如P帧和B帧)则是通过与之前或之后的帧进行差异编码得到的
ffmpeg -i input.mp4 -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync 0 output_%04d.png
提取视频中的帧
ffmpeg -i data/1_cut.mp4 -s 480x270 -vf "select=between(n\,5\,3569)*not(mod(n\,5))" -vsync 0 "data/sc/image-%05d.jpg"
主体是一个select 的过滤语句:
其中:
- between(n,*) 是指 从第几帧到第几帧之间进行提取…
- not(mode(n, K))是指每隔几帧输出一帧。
使用between可以指定需要提取开始帧和结束帧的位置,如果想要对视频中所有的帧进行间隔采样,命令如下
command_extract = "select=(gte(n\,%d))*not(mod(n\,%d))"%(60,60)
com_str = 'ffmpeg -i ' + video_path + ' -vf "%s" -vsync 0 '%command_extract + save_jpg_tmp_path + '/%06d.jpg'
按时间间隔取帧
commands := []string{
`-i`, src,
"-s", "192x108",
"-vf", `select=(gte(t\,0))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,1))`,
"-vsync", "0",
"-y", path.Join(dst, `%05d.jpg`),
}
ffmpeg -i <input> -vf "select=(gte(t\,0))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,21))" -vsync 0 image_%05d.jpg
ffmpeg -i <input> -vf "select=(gte(t\,120))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,120))" -vsync 0 image_%05d.jpg
ffmpeg -i 1.mp4 -vf fps=10 -vsync 0 image_%05d.jpg # 一秒提取10次
上面命令中的120的单位是s,指每120s提取视频中的一帧图像
视频信息获取
ffprobe json
ffprobe -v quiet -print_format json -show_format -show_streams a.mp4
ffprobe -v quiet -print_format json -show_format -show_streams -i 2.mp4
获取帧总量
ffprobe -i .\data\1_cut.mp4 -select_streams v -show_entries stream=nb_frames -of default=nk=1:nw=1 -v quiet
获取视频总时长
ffprobe <input> -select_streams v -show_entries stream=duration -of default=nk=1:nw=1 -v quiet
视频切图
ffmpeg -i 2332103105.mp4 -vf "crop=540:540:0:420" -s "384x216" -y out.jpg
缩小视频并且加上水印
ffmpeg -i demo.mp4 -vf "movie=preview.watermark.png [watermark]; [in]scale=640:360 [scale]; [scale][watermark] overlay=0:0" c.mp4
多轨道视频叠加
[0]表示第一个输入,[1]表示第二个输入,大写W表示第一个宽,小写w表示第二个宽
ffmpeg -i a.mp4 -i b.mov -filter_complex "[1]scale=iw*0.5:-1[open];[0][open]overlay=W/2:H/2" -vcodec libx264 -acodec aac out.mp4 -y
# repeatlast表示不统一长度,该结束就结束
ffmpeg -i 1.mp4 -i open.mov -t 10 -filter_complex "amix=inputs=2:duration=longest;[1]scale=640:-1[open];[0][open]overlay=x=0:y=0:repeatlast=0, subtitles=1.ass" out.mp4 -y
删除所有音轨
ffmpeg -i input_file.mp4 -vcodec copy -an output_file.mp4
加黑边
ffmpeg -i demo.mp4 -vf 'scale=1080:608,pad=1080:810:0:106:black' y.mp4
缩放裁剪
ffmpeg -i 1-1080p.mp4 -vf "scale='3413:1920',crop='1080:1920:1160:0'" -c copy -threads 4 -vcodec libx264 -y 1-1080p-h.mp4
给视频加高斯模糊边框
ffmpeg -i 2.mp4 -vf "split[a][b];[a]scale=3413:1920,crop=1080:1920:1160:0,boxblur=15:15[1];[b]scale=1080:608[2];[1][2]overlay=0:(1920-608)/2" -c copy -threads 4 -vcodec libx264 -y 2-out.mp4
生成静音音频
ffmpeg -f lavfi -t 10 -i anullsrc test.aac -y
`-bsf:v`, `h264_mp4toannexb`,
给视频图片加上文字水印
ffmpeg -i 640.jpg -filter_complex "[0]scale=220:-1[img];[img]drawtext=text='07\:43':x=w-tw-10:y=h-th-10:fontsize=24:fontcolor=white:borderw=2:bordercolor=black" o-3.jpg -y
# 封面添加文字
ffmpeg -i 1.png -filter_complex "[0]scale=1920:1080[img];[img]drawtext=x=(w-tw)/2:y=(h-th)/2:fontfile=1.ttf:fontsize=160:fontcolor=white:borderw=10:bordercolor=orange@0.8:box=0:boxborderw=5:boxcolor=black:shadowcolor=red:textfile=1.txt:line_spacing=80" o.jpg -y
滚动文字
ffmpeg -i 1.mp4 -t 10 -vf "drawtext=text=string1 string2 string3 string4 string5 string6 string7 :expansion=normal:fontfile=1.ttf: y=h-line_h-10:x=(mod(5*n\,w+tw)-tw): fontcolor=white: fontsize=40: shadowx=2: shadowy=2" output.mp4
ffmpeg -i 1.png -filter_complex "[0]scale=1920:1080[img];[img]drawtext=x=(w-tw)/2:y=(h-th)/2:fontfile=font/fonts/25.ttf:fontsize=140:fontcolor=white:borderw=14:bordercolor=orange@0.9:box=0:boxborderw=5:boxcolor=black:shadowcolor=red:textfile=1.txt:line_spacing=40" o.jpg -y
视频封面生成
# https://blog.csdn.net/toopoo/article/details/105603154
ffmpeg -i a.mp4 -frames:v 1 -y a.jpg
生成纯黑图片
ffmpeg -f lavfi -i color=c=#dfdfdf:s=512x512 -frames:v 1 -q:v 1 -y logo.jpg
生成纯黑视频
ffmpeg -f lavfi -i color=black:1920x1080:d=3 -format rgb32 -f matroska -vcodec libx264 test1.mp4
延长视频时间
# 调整视频流速度的setpts和调整音频流的atempo应是互为倒数的,
# 这样才能保证新视频里画面和声音同步。
# 只缩放视频
ffmpeg -i open.mov -filter_complex "setpts=2*PTS" open2.mov
# 声画同步
ffmpeg -i input.MOV -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" video.mp4
ff录屏
ffmpeg -y -f gdigrab -t 25 -r 30 -i desktop -draw_mouse 0 -c:v h264_amf 1.mp4
pix_fmt yuv420p
ffmpeg 重复,延长时间
ffmpeg -i in.mp4 -vf tpad=stop_mode=clone:stop_duration=2 out.mp4
ffmpeg -i i1.mp4 -filter_complex "[0]scale=640:360[o1];[o1]tpad=start_mode=clone:start_duration=3" -y ddd.mp4
png转mov
ffmpeg -r 80 -i img/%03d.png -vf fps=60 -vcodec qtrle out.mov -y
叠加水印并把图像转成视频
ffmpeg -i 1.png -i 2.png -filter_complex "overlay=0:0[o1];[o1]tpad=start_mode=clone:start_duration=5" -vcodec libx264 -r 32 -y 3.mp4
视频是否异常
ffmpeg -i 1.mp4 -v error -f null -
合并视频
ffmpeg -f concat -i filelist.txt -c copy -y z1.mp4
注意 所有视频为相对地址,相对于filelist.txt的位置,并且视频基本参数相同如帧率格式等
# filelist.txt
file './1.mp4'
file './2.mp4'
png转rgba
ffmpeg -i demo.png -filter_complex "format=rgba" demo1.png -y
转成灰度图
ffmpeg -i input -vf format=gray output
缓慢放大
ffmpeg -y -i 1.jpg -vf "zoompan=z='min(zoom+0.0009,1.5)':d=320:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':fps=32" -y 1.mp4
dpi
ffmpeg -i f1.tif -dpi 1200 -filter_complex "scale=4000:-1" f1-resize.tif
图像动态叠加,从左向右移动
ffmpeg -i a.jpg -vf "color=c=green:s=1920x1080[bg];[bg][0:v]overlay=x='if(lte(t,5),-w+(W+w)/2/5*t,(W-w)/2)':y=(H-h)/2" -t 5 -y move.mp4
ffmpeg视频补边为16:9并居中
ffmpeg -i out.mp4 -vframes 1 -vf "pad='if(gt(a,16/9),iw,ih*16/9)':'if(gt(a,16/9),iw*9/16,ih)':'if(gt(a,16/9),0,(ow-iw)/2)':'if(gt(a,16/9),(oh-ih)/2,0)':'#5e5e5e'" -s 640x360 -y o3.jpg
创建静默音频并添加到音频末尾
ffmpeg -f lavfi -t 3 -i anullsrc -i 2.mp3 -filter_complex "[1:a][0:a]concat=n=2:v=0:a=1[out]" -map [out] 3.mp3 -y
输出质量控制
-crf:这个参数用于视频编码器(如x264、x265等),它指定了视频的压缩质量,值越小,质量越好,文件大小越大。一般推荐使用范围为18-28之间的值,其中18是最高质量,28是最低质量。例如,-crf 23表示使用23的压缩质量。
-qscale:v:这个参数用于一些旧的视频编码器(如mpeg2video),它指定视频的压缩质量,值越小,质量越好,文件大小越大。取值范围为0-31之间,其中0是最高质量,31是最低质量。例如,-qscale:v 2表示使用2的压缩质量。
-b:v:这个参数用于指定视频的比特率,它控制了视频的压缩质量和文件大小。一般推荐使用范围为1000kbps-8000kbps之间的值,具体取决于视频的分辨率和帧率。例如,-b:v 4000k表示使用4000kbps的比特率。
左右缝合视频
ffmpeg -i right.mp4 -i left.mp4 -t 120 -filter_complex "[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]" -map "[vid]" -b:v 15000000 output_2.mp4 -y
保持原始视频质量转码
ffmpeg -i input.mp4 -c:v libx264 -crf 0 -preset veryslow -c:a copy output.mp4
硬件加速
查询支持的硬件解码器
ffmpeg -decoders|grep h264
查询支持的硬件编码器
ffmpeg -codecs|grep h264
使用方式
# os.system("ffmpeg -vcodec h264_cuvid -i " + file + " -c:v h264_nvenc -c:a aac -s 1138x640 -y " + tmp_file)
ffmpeg -vcodec h264_cuvid -i in.mp4 -c:v h264_nvenc -c:a aac -s 1138x640 -y out.mp4