如果一些关键字参数搜索不到,去另一个文件试试。
ffmpeg一个比较入门的教程,很适合来学习。
这些参数,很多如果不给,就是采用原视频里面的。
这里还不错的一些相关的ffmpeg的参数。# 一定先去看,有你需要的
开发官方学习文档。推拉流,代码上的一些实现,可以看看这个博客。
注意:
-y
则表示如果输出文件已存在就同意覆盖;加-n
则不同意覆盖,相当于什么也没做。这样子外部调用命令就会执行完,不会卡在那里。参数说明:
ffmpeg -encoders
:可以查看ffmpeg支持的所有的视频、音频、字幕等编解格式。
一、==主要选项==:
二、==视频选项==:
-vframes 200 (output) 设置输出文件的帧数,跟 -frames:v 是一个意思。
ffmpeg -i keypoint_result.mp4 -frames:v 200 out.mp4 # 意思就是输出200帧后就停止,out.mp4多长,取决于输入流的fps
-r 25 (input/output,per-stream)设置帧率
-vn (output)禁止输出视频,跟-an禁止音频一样
-vcodec libx264 (output)设置视频编码器,这是 -codec:v 的别名,跟上面的-vframes一个意思。
-aspect “4:3” (output)指定视频的纵横比,常用参数值 “4:3”、”16:9”、”1.3333”、”1.7777”。写成小数也是OK的,1280/720=1.777777
-s 640×480 (output)指定视频画面的大小,用*代替×也是OK的。
三、==音频选项==:
-frames:a 200 (output)设置输出文件的帧数,到了200就停,(音频的帧数是人为抽象的概念)
-ar 44.1k (input/output,per-stream)设置音频采样率44.1kHz,默认是输出等同于输入。默认输出会有输入相同的音频通道。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。
-ar 采样率,每秒采样多少次,一般( 44.1kHz=44100 48kHz 以及 80kHz)
采样率大大于原声波频率的2倍,人耳能听到的最高频率是20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz,更高为48kHz,人耳听觉频率范围[20Hz, 20kHz]
-aq q (output)设置音频品质(编码指定为VBR)(我暂时不知道q应该给什么参数),也可以写作 -q:a , 老版本为qscale:a
-ac 2 (input/output,per-stream)设置音频通道,默认是输出等同于输入。默认输出会有输入相同的音频通道。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。
-an (output)禁止输出音频。
-acode aac (intput/output)设置音频解码/编码的编解码器,也可写作 -codec:a (可用ffmpeg -encoders查看支持哪些格式)
三、==字幕选项==:
字幕不多写了,地址放这里。
作用 | 按键 |
---|---|
退出 | q, ESC |
暂停 | p, 空格 |
全屏 | f |
逐帧显示 | s |
跳转到指定位置 (根据鼠标位置相对屏幕的宽度计算) |
鼠标右键点击屏幕 |
向后10s/向前10s | 左方向键/右方向键 |
向后1min/向前1min | 上方向键/下方向键 |
向后10min/向前10min | page down/page up |
显示音频波形 | w |
对应的PotPlayer的一些常用快捷键:
作用 | 按键 |
---|---|
增加播放速度 | C |
减慢播放毒素 | X |
回到一倍速 | Z |
复制当前画面到剪切板 | Ctrl+Alt+C |
旋转画面 (注意下次打开会记住这次旋转的情况) |
Alt+K |
播放时也可以参照ffmpeg来添加图片、文字水印。
ffpaly -window_title “hello” 456.mp4 # 默认是用文件名当窗口名,这是自己命名窗口名
其它参数:
-x 200 强制设置视频显示窗口的宽度
-y 300 强制设置视频显示窗口的高度
-s 设置视频显示的宽高(暂时没试成功)
-fs 强制全屏显示
-an 屏蔽音频
-vn 屏蔽视频
-Sn 屏蔽字幕
-ss 根据设置的秒进行定位拖动 -t 设置播放视频/音频长度
-autorotate 自动旋转视频,加了,但没看到啥效果
还有其它设置要播放的视频流、音频流之类的,还可以挂载字幕等,就不多写了
让视频播放时右上角显示系统当前时间:
ffplay -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:x=W-tw:fontcolor=red:fontsize=30:text='%{localtime\:%H\\\:%M\\\:%S}'"
-show_frames:查看视频没一帧的格式,ffprobe -show_frames 456.mp4 # 每一帧的数据都会输出,是不是关键帧之类的(带音频的话,一帧数据就是音视频数据都有)(结果中 key_frame=1 代表是关键帧,具体网上看其它参数含义吧)
都可以加上参数==-print_format xml/json/csv/ini/flat==用更方便的格式查看,ffprobe -show_streams 01.mp4 -print_format json,还可以再加上 > out.json 重定向保存下来。
windows:
linux:
注意:dshow是win上特有的,linux上是不行的,linux上要用“x11grab”(这一般是用来录屏),可用ffmpeg -devices
去查看支持的格式,具体输入输出可是可看这里。
下面是一些内置变量,不同功能可能有些区别,然后也不一定完全对,其它功能也可以来尝试用别的变量,试试先。
添加图片水印时:
ffmpeg -i 01.mp4 -vf "movie=05.jpg[my_name];[in][my_name]overlay=W/2-w/2:H/2-h/2[out]" out.mp4
给视频加文字水印时:(下面的一些函数上面应该也能用)
text_w 或 tw 文本宽度(像素)
视频拆成图片:ffmpeg -i input.flv -r 1 -f image2 image-%4d.jpg
# 还可以在 -f image2 加上 -q:v 2 图片的质量会增加
-i : 指定输入文件
-r : 就是1秒r张, -r 3 就是1秒3张
-f : 指定格式化的格式为image2
生成的结果 image-%4d.jpg %4d是指4位数字
获取封面:ffmpeg -i a.mp4 -y -f image2 -frames 1 a.jpg
获取更高质量:ffmpeg -i a.mp4 -y -f image2 -q:v 2 -frames 1 a.jpg
反过来图成视频就是: ffmpeg -f image2 -i image-%4d.jpg out.mp4
将多个图转成视频:ffmpeg -f image2 -r 20 -i "./images/img_%d.jpg" ./out.mp4
视频片段截取(-t
和-to
):
ffmpeg -ss 6 -t 30 -i ./LOL.mp4 temp.mp4
# 从6秒开始截取30s,存为temp.mp4
ffmpeg -ss 6 -to 30 -i ./LOL.mp4 temp.mp4
# 这里就是从6秒开始,截取到30s,共24S注意:这样子会自适应降低视频码率,会较大的压缩视频大小(注重质量还是像下面一样带个 -c copy)
ffmpeg -ss 00:00:06 -to 00:10:25 -i ./sample.mp4 -c copy output.mp4
// -c copy 代表会个各种格式都按照原视频来,也不用重新编解码,速度快很多。
截取视频的一个注意事项:(如从第10秒截取到第15秒)
注:如果截取的原视频很大,尽量把-ss放-i前面,这样它会先去大概定位,就很快;如果是-i在前,上来就打开,一点点去找,就很慢。
获取视频指定时间的截图:ffmpeg -ss 8 -t 0.001 -i 01.mp4 -f image2 -s 100x100 res11.jpg
视频转gif:ffmpeg -ss 8 -t 15 -i 11.mp4 -s 600*400 -r 15 res.gif
# *可以用小写字母x代替
图片转:ffmpeg -i image-%4d.jpg -r 5 test.gif
ffmpeg -i 01.mp4 -vf crop=200:400:0:120 -threads 4 -preset ultrafast -strict -2 02.mp4
ultrafast
、superfast
、veryfast
、faster
、fast
、medium
、slow
、slower
、veryslow
或placebo
。速度越快,CPU使用率越高,但压缩效率可能会降低,也可能会牺牲视频质量。说明:这里里西安机芯装配视频来说的,原始视频是用小米11pro用1080p,30fps拍摄,假设为“input.mp4”
下面用一些方法来压缩视频
两种方式:
直接使用:ffmpeg -i input.mp4 output.mp4
这就自动降码率了,其它参数还是一样,但可能用压缩后视频去截取骑部分长度的画,截取结果可能会有开头黑屏一两秒的问题。
指定 -crf 参数:ffmpeg -i input.mp4 -crf 20 output.mp4
上面是自动选择的压缩后的码率,下面这是弄动态壁纸的记录:
视频的原码率是 2.1Mb/s ,压缩为 1.5Mb/s
ffmpeg -i Desktop/1.mov -b:v 1.5M -r 30 Desktop/1.mp4 # 还可以添加r参数,把原来的帧率改成30(一般是从大减小)
ffmpeg -i .\out.avi -b:v 3.6M 123_1.mp4 # 还可以以此来转换视频格式(opencv只能avi格式写入,且码率很大很大,可以这样把它转换成mp4,减小码率,减小所占空间)
-b:v
:指定视频的码率 1.5M 应该也是能写成 1500k 的
-b:a
:指定音频的码率
1.5M:码率的值 1.5M 表示 1.5Mb/s
码率越小,视频清晰度就降低,然后大小也会变小,然后就达到了压缩的目的
avi的码率会很大,用这个做动态壁纸会比较吃资源,然后可以直接.avi转成.mp4,它会自己找一个合适和码率去转,不用降低帧率,占用差不多。
ffmpeg -i input.mp4 -c:v libx265 -crf 20 -r 24 -vf scale=1280:-1 -y output.mp4
-c:v libx265:代表以265的格式编码, -c:v是指定编码器,编码器列表可以使用ffmpeg -codecs查看;
比如在转格式时(做动态壁纸时),avi转mp4,其它什么都不指定,选择默认:
ffmpeg -i input.avi out.mp4 # 一般码率会比avi减小(但不会特别多),占用空间减小
ffmpeg -i input.avi -c:v libx265 out.mp4 # 码率会比avi小很多很多(比上面那个还小),占用的空间也会小很多倍
-crf 20:上面提到过了,主要是改变码率;
-r 24:指定帧率为24,建议跟原视频保持一致,从30到24后,画面看起来偶尔像是会有卡顿;
-vf scale:指定输出视频的宽高,高-1代表按照比例自动适应,也可以直接 =640:480这样指定一个特定的。上面命令scale=1280:-1就可以将1080p(1920*1080)的视频转成720p(1280*720)
ffplay播放时也可加这些,命令参数赋值过去就行。
注:在给视频加gif图片水印(别去添加gif水印,问题很大,在gif的-i前设置 -ignore_loop 0 就是让其一直循环,那生成视频的过程会无限下去,因为它要保持最长的一致,不加这个参数,gif循环一次就完了,用别的方式,可能视频又变得跟gif一样短)。
ffmpeg -i 01.mp4 -vf "movie=05.jpg[my_name];[in][my_name]overlay=50:60[out]" out.mp4
# 核心区别是 movie 参数
ffmpeg -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:text='hello world':x=W/2:y=150:fontsize=24:fontcolor=yellow:shadowy=2" res.mp4
核心区别是 drawtext 参数
#3366BB
视频播放右上角显示系统当前时间:ffplay -i sintel_trailer-480p.webm -vf "drawtext=fontfile=simhei.ttf:x=W-tw:fontcolor=white:fontsize=30:text='%{localtime\:%H\\\:%M\\\:%S}'"
ffmpeg -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:text='hello world':x=(mod(2*n\,w+tw)-tw):y=10:fontcolor=#FF6600:fontsize=30" -f mp4 out.mp4
ffmpeg -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:text='hello world':x=W-t*W/10:y=10:fontcolor=#FF6600:fontsize=30" -f mp4 out.mp4
ffmpeg -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:text='hello world':x=W/2:y=H/2:fontcolor=red:fontsize=60:enable=lt(mod(t\,5)\,2)" -f mp4 out.mp4
mp3的编码格式:-acodec libmp3lame
ffmpeg -i input.mp4 -vn -c:a copy output.aac
# 注意是.aac
-c:a libmp3lame
导出mp3格式的音频.-b:a 128k
指定音频的码率是128kb/s,-ar 44k
指定音频的采样频率为44kHz,完整命令如下:ffmpeg -i input.mp4 -vn -b:a 128k -ar 44k -c:a mp3 output.mp3ffmpeg -i input_file -an -vcodec copy output_file_name
# 就是视频消声:
ffmpeg -i ./LOL.mp4 -an -vcodec copy 1.mp4
# 原视频是LOL.mp4,会创建一个副本1.mp4ffmpeg -i 0.wav -i 1.wav -filter_complex "[0:a:0] [1:a:0] concat=n=2:v=0:a=1 [a]" -map "[a]" output0.wav
ffmpeg -i input.wav -ar 8000 -ab 12.2k -ac 1 output.amr
参数解释:
-i input.wav:指定输入的WAV文件。
-ar 8000:设置音频的采样率为8000赫兹。
-ab 12.2k:设置音频的比特率为12.2kbit/s,这是AMR-NB格式的标准比特率。
-ac 1:设置音频的通道数为1,表示单声道。
output.amr:输出的AMR文件名。
wav音频格式转pcm格式的说明: 这个、这个,两个搭配起来看,。然后第转的时候,注意参数的值,可以先用ffprobe example.wav的格式再转
方向旋转、翻转:
倒放音视频:
ffmpeg -i 01.mp4 -filter_complex [0:v]reverse[v] -map [v] -preset superfast out.mp4
加/减速音视频:调整倍数范围[0.24, 4]
在画面上左右、上下合并视频,要注意两个视频的size,跟array合并是一个意思
横向合并:ffmpeg -i 01.mp4 -i 02.mp4 -lavfi hstack out.mp4
时间维度上的拼接:
把要合并的视频放到一个文件夹里,然后把文件名写到txt,像这样:(假设下面就是merge.txt
的内容)(只能是视频名称不能给绝对路径)
file video_1.mp4 file video_2.mp4 file video_3.mp4 file video_4.mp4 file video_5.mp4
ffmpeg -f concat -i merge.txt output.mp4
看要不要-c copy
或者ffmpeg -i "concat:1.ts|2.ts|3.ts" -acodec copy -vcodec copy out.mp4
# 可能会报错,要设置一下编码格式
镜面倒影特效:地址,没试了:ffmpeg -i 01.mp4 -vf "split[up][down];[up]pad=iw:ih*2[up];[down]vflip[down];[up][down]overlay=0:h out.mp4"
这个效果:
上面教程视频还涉及到:(用到了iw、ih这些变量,是值输入视频的尺寸嘛?)
画中画overlay:ffmpeg -i big.mp4 -i little.mp4 -filter_complex overlay=main_w-overlay_w-20:0 out.mp4
九宫格拼接视频:结果好像只有一个音频,
ffmpeg -re -i 001.mp4 -re -i 002.mp4 -re -i 003.mp4 -re -i 004.mp4
-filter_complex
"nullsrc=size=640x480[base];
[0:v]setpts=PTS-STARTPTS,scale=320x240[uperleft];
[1:v]setpts=PTS-STARTPTS,scale=320x240[uperight];
[2:v]setpts=PTS-STARTPTS,scale=320x240[lowerleft];
[3:v]setpts=PTS-STARTPTS,scale=320x240[lowerright];
[base][uperleft] overlay=shortest=1[tmp1]; # 先覆盖一个到base上,得到tmp1,再把tmp1当做base来
[tmp1][uperight] overlay=shortest=1:x=320[tmp2];
[tmp2][lowerleft] overlay=shortest=1:y=240[tmp3];
[tmp3][lowerright] overlay=shortest=1:x=320:y=240"
-c:v libx264 out.mp4
m3u8切片:ffmpeg -i sintel_trailer-480p.webm -fflags flush_packets -max_delay 2 -flags -global_header -hls_time 5 -hls_list_size 0 -vcodec libx264 -acodec aac -r 30 -g 30 out_.m3u8
结果会是 out_.m3u8 索引文件,然后得到的视频片段名字会自动成为 out_1.ts、out_2.ts这种。
用flv.js来播放m3u8:用一个flv.js进行网页的播放,教程,还是很麻烦,要http-flv推流,还要用nginx配置跨域问题。
一般来说,.mkv格式视频中是带有字幕流的,但是用windows自带的播放器是没有字幕的,如果要让它能播,可以把字幕文件直接融到视频中去:(.ass是一种字幕文件)
看视频有哪些流,使用ffprobe命令。
推荐使用:ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -map 0:s:1 -c copy output.mkv
# 一瞬就完成了
-map 0:v:0
: 选择第一个视频流(从输入文件的第一个流开始计数);-map 0:a:0
: 选择第一个音频流(因为音频流一般就一个,那就是0);-map 0:s:1
: 选择第2个字幕流(老友记的视频一共有7个流,1个视频流,1个音频流,5个字幕流,我们要的是第2个字母流,那它就是1)。
这里的索引0都是代表各自流的第一个,不是总流来算的视频转码相关:(但未测试),视频地址,
提取264码流:ffmpeg -i demo.mp4 -vcodec copy -an -bsf: h264_mp4toannexb -f h264 temp.264
说是本地的mp4,就一个头部,而流为了稳定,及随时能打开,就要每隔一段就有一个头,所以 h264_mp4toannexb 就是这样的格式,具体看是看上面教程