note

如果一些关键字参数搜索不到,去另一个文件试试。

ffmpeg一个比较入门的教程,很适合来学习。

这些参数,很多如果不给,就是采用原视频里面的。

这里还不错的一些相关的ffmpeg的参数。# 一定先去看,有你需要的

开发官方学习文档。推拉流,代码上的一些实现,可以看看这个博客

注意:

参数说明:


一、命令行常用的通用选项

ffmpeg -encoders:可以查看ffmpeg支持的所有的视频、音频、字幕等编解格式。

一、==主要选项==:

  1. -f flv (input/output)指定输入或者输出文件格式(封装格式,视频容器)。常规可省略而使用依据扩展名(或是文件的前几百K的内容,智能分析)的自动指定,但一些选项需要强制明确设定。
  2. -i 01.mp4 (input)指定输入文件。
  3. -y (global)默认自动覆盖输出文件,而不再询问确认。
  4. -n (global)不覆盖输出文件,如果输出文件已经存在则立即退出。
  5. -ss position (input/output)
    • 如果是在-i前(一般也用在-i前),表示定位输入文件到position指定的位置;
    • 注意可能一些格式是不支持精确定位的,所以ffmpeg,可能是定位到最接近position(在之前)的可定位点。position可以是以秒为单位的数值或者hh:mm:ss[.xxx]格式的时间值(如 12:15:23.314)。
  6. -t duration (input/output)限制输入/输出的时间。(注意-to和-t是互斥的,-t有更高优先级)
    • 如果是在-i前面,就是限定从输入中读取多少时间的数据;
    • 如果是在-i后面,用于限定输出文件,则表示写入多少时间数据后就停止;
    • duration可以是以秒为单位的数值或者 hh:mm:ss[.xxx]格式的时间值(如 12:15:23.314)。
  7. -to position (output)只写入position时间后就停止
    • position可以是以秒为单位的数值或者hh:mm:ss[.xxx]格式的时间值。
    • 注意-to和-t是互斥的,-t有更高优先级。(-t是截取那么多,-to是截取到那么多)
  8. -threads 0 默认值是0,用所有核心,还可以给1、2

二、==视频选项==:

  1. -vframes 200 (output) 设置输出文件的帧数,跟 -frames:v 是一个意思。

    ffmpeg -i keypoint_result.mp4 -frames:v 200 out.mp4 # 意思就是输出200帧后就停止,out.mp4多长,取决于输入流的fps

  2. -r 25 (input/output,per-stream)设置帧率

  3. -vn (output)禁止输出视频,跟-an禁止音频一样

  4. -vcodec libx264 (output)设置视频编码器,这是 -codec:v 的别名,跟上面的-vframes一个意思。

  5. -aspect “4:3” (output)指定视频的纵横比,常用参数值 “4:3”、”16:9”、”1.3333”、”1.7777”。写成小数也是OK的,1280/720=1.777777

  6. -s 640×480 (output)指定视频画面的大小,用*代替×也是OK的。


三、==音频选项==:

  1. -frames:a 200 (output)设置输出文件的帧数,到了200就停,(音频的帧数是人为抽象的概念)

  2. -ar 44.1k (input/output,per-stream)设置音频采样率44.1kHz,默认是输出等同于输入。默认输出会有输入相同的音频通道。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。

    • -ar 采样率,每秒采样多少次,一般( 44.1kHz=44100 48kHz 以及 80kHz)

    • 采样率大大于原声波频率的2倍,人耳能听到的最高频率是20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz,更高为48kHz,人耳听觉频率范围[20Hz, 20kHz]

  3. -aq q (output)设置音频品质(编码指定为VBR)(我暂时不知道q应该给什么参数),也可以写作 -q:a , 老版本为qscale:a

  4. -ac 2 (input/output,per-stream)设置音频通道,默认是输出等同于输入。默认输出会有输入相同的音频通道。对于输入进行设置,仅仅通道是真实的设备或者raw数据分离出并映射的通道才有效。

  5. -an (output)禁止输出音频。

  6. -acode aac (intput/output)设置音频解码/编码的编解码器,也可写作 -codec:a (可用ffmpeg -encoders查看支持哪些格式)

    • 如果是要mp3的格式,要写作 -acode libmp3lame

三、==字幕选项==:

字幕不多写了,地址放这里

二、ffplay相关

2.1. ffplay快捷键

作用 按键
退出 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

2.2. ffplay播放增强参数

播放时也可以参照ffmpeg来添加图片、文字水印。

ffpaly -window_title “hello” 456.mp4 # 默认是用文件名当窗口名,这是自己命名窗口名

其它参数:


让视频播放时右上角显示系统当前时间: ffplay -i 01.mp4 -vf "drawtext=fontfile=simhei.ttf:x=W-tw:fontcolor=red:fontsize=30:text='%{localtime\:%H\\\:%M\\\:%S}'"

2.3. ffprobe查看详细格式

都可以加上参数==-print_format xml/json/csv/ini/flat==用更方便的格式查看,ffprobe -show_streams 01.mp4 -print_format json,还可以再加上 > out.json 重定向保存下来。

2.4. 列举打开本地摄像头

windows:

linux: 注意:dshow是win上特有的,linux上是不行的,linux上要用“x11grab”(这一般是用来录屏),可用ffmpeg -devices去查看支持的格式,具体输入输出可是可看这里

三、实际操作示例

3.1. 一些内置变量、函数

下面是一些内置变量,不同功能可能有些区别,然后也不一定完全对,其它功能也可以来尝试用别的变量,试试先。

添加图片水印时:


给视频加文字水印时:(下面的一些函数上面应该也能用)

3.2. 视频/图相关

3.2.1 视频拆成图

  1. 视频拆成图片: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位数字

  2. 获取封面: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

  3. 反过来图成视频就是: ffmpeg -f image2 -i image-%4d.jpg out.mp4

  4. 将多个图转成视频:ffmpeg -f image2 -r 20 -i "./images/img_%d.jpg" ./out.mp4

    • -r 20:代表帧数设置为20,也可以写做 -framerate 20 是一个意思
    • 还可以加一个参数:-vcodec libx264 # 代表以264格式编码
    • 特别注意,路径里面有空格、几级目录这些,用引号括起来
    • 还可在在合成过程中添加音频,参看这里
    • 注意:opencv把图片存为视频,真有点奇怪啊,它最后保存的是视频总帧数始终只有图片数量的一半,无论保存图片时fps设置为多少,所以时长也只有ffmpeg转的一半。

3.2.2 视频片段截取

视频片段截取(-t-to):

注意:这样子会自适应降低视频码率,会较大的压缩视频大小(注重质量还是像下面一样带个 -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在前,上来就打开,一点点去找,就很慢。

3.2.2 获取指定时间的截图

获取视频指定时间的截图:ffmpeg -ss 8 -t 0.001 -i 01.mp4 -f image2 -s 100x100 res11.jpg

3.2.3 视频转gif(片段截取)

视频转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

3.2.4 部分画面截取

ffmpeg -i 01.mp4 -vf crop=200:400:0:120 -threads 4 -preset ultrafast -strict -2 02.mp4

3.3. 压缩视频

说明:这里里西安机芯装配视频来说的,原始视频是用小米11pro用1080p,30fps拍摄,假设为“input.mp4”

下面用一些方法来压缩视频

3.3.1 改变码率

两种方式:

  1. 直接使用:ffmpeg -i input.mp4 output.mp4

    • 压缩后视频码率:4389kbps
    • 压缩后视频大小:1.60GB

    这就自动降码率了,其它参数还是一样,但可能用压缩后视频去截取骑部分长度的画,截取结果可能会有开头黑屏一两秒的问题。

  2. 指定 -crf 参数:ffmpeg -i input.mp4 -crf 20 output.mp4

    • -crf 20:设置CRF值(常量速率因子)。CRF值范围从0(无损)到51(最糟),通常使用18到28的值。较低的CRF值会导致更好的质量,但文件会更大。

上面是自动选择的压缩后的码率,下面这是弄动态壁纸的记录:

视频的原码率是 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,减小码率,减小所占空间)

avi的码率会很大,用这个做动态壁纸会比较吃资源,然后可以直接.avi转成.mp4,它会自己找一个合适和码率去转,不用降低帧率,占用差不多。

3.3.2 改变画面大小(分辨率)、fps、h265编码

ffmpeg -i input.mp4 -c:v libx265 -crf 20 -r 24 -vf scale=1280:-1 -y output.mp4

3.4. 图片、文字水印

ffplay播放时也可加这些,命令参数赋值过去就行。

​ 注:在给视频加gif图片水印(别去添加gif水印,问题很大,在gif的-i前设置 -ignore_loop 0 就是让其一直循环,那生成视频的过程会无限下去,因为它要保持最长的一致,不加这个参数,gif循环一次就完了,用别的方式,可能视频又变得跟gif一样短)。

3.5. 声画分离、合成、改视频音量大小

mp3的编码格式:-acodec libmp3lame



音频格式转换

  1. MP3、wav之间:
    • mp3转wav:ffmpeg -i 123.mp3 -f wav out.wav # wav转mp3也是一样
    • wav/mp3文件的切分:ffmpeg -i out.wav -f segment -segment_time 30 -c copy output%03d.wav
    • wav/mp3文件的拼接:ffmpeg -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 -ss 00:15:05 -to 00:15:35 -i .\20220110.mp3 -c copy out.mp3 # 注意如果是wav格式的切出来就是空的,那就先转成mp3格式
    • mp3 to wav and change rate:ffmpeg -i song.mp3 -acodec pcm_u8 -ar 22050 song.wav
  2. wav转amr (安全帽调试里用到过,amr格式的音频文件会特别小,适合通过网络给终端设备发送)

wav音频格式转pcm格式的说明: 这个这个,两个搭配起来看,。然后第转的时候,注意参数的值,可以先用ffprobe example.wav的格式再转

3.6. 旋转、镜像等

方向旋转、翻转:

3.7. 音视频的倒放

倒放音视频:

3.8. 倍速播放

加/减速音视频:调整倍数范围[0.24, 4]

3.9. 视频拼接(纵/横/时间轴)

在画面上左右、上下合并视频,要注意两个视频的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 # 可能会报错,要设置一下编码格式

3.10. 镜面倒影,scale尺寸变换

镜面倒影特效:地址,没试了:ffmpeg -i 01.mp4 -vf "split[up][down];[up]pad=iw:ih*2[up];[down]vflip[down];[up][down]overlay=0:h out.mp4" 这个效果: image-20240808212135489

上面教程视频还涉及到:(用到了iw、ih这些变量,是值输入视频的尺寸嘛?) image-20240808212305421

3.11. 画中画,九宫格

画中画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

3.12. 对视频进行m3u8切片

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


用flv.js来播放m3u8:用一个flv.js进行网页的播放,教程,还是很麻烦,要http-flv推流,还要用nginx配置跨域问题。

3.13. 存网络流为本地视频

  1. 把rtsp流存成ts流:ffmpeg -i “rtsp://192.168.108.136:554/user=admin&password=&channel=1&stream=0.sdp?” -c copy -f mpegts ts.ts
    • 注意这种,.ts 流的封装格式 -f mpegts
  2. 网络资源下载:ffmepg -i https://xxx.xxx.xx -c copy -f mp3 out.mp3
  3. 或是:ffmpeg -i http://xxx.xx.m3u8 -c copy -movflags+faststart test.mp4 # m3u8转mp4,说是点播非常有用,讲解地址

3.14 mkv中提取字幕

一般来说,.mkv格式视频中是带有字幕流的,但是用windows自带的播放器是没有字幕的,如果要让它能播,可以把字幕文件直接融到视频中去:(.ass是一种字幕文件)


看视频有哪些流,使用ffprobe命令。

推荐使用:ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -map 0:s:1 -c copy output.mkv # 一瞬就完成了

3.14. h264流相关

视频转码相关:(但未测试),视频地址

提取264码流:ffmpeg -i demo.mp4 -vcodec copy -an -bsf: h264_mp4toannexb -f h264 temp.264

说是本地的mp4,就一个头部,而流为了稳定,及随时能打开,就要每隔一段就有一个头,所以 h264_mp4toannexb 就是这样的格式,具体看是看上面教程