ffmpeg

1 布景常识

一个视频文件是由视频 音频 字幕等重要部分组成的。视频格局,例如咱们常见的mp4,mkv,mov,flv,avi,wmv等等,他们其实都是容器,这个容器里边包裹了视频流,音频流,字幕,其他流等内容,当然不一定一切的部分都有数据,例如或许没有字幕。

多条:关于同一种流,也或许有多条,例如某些电影文件就有多条音频流,中文和英文的音轨,也或许有多个言语的字幕。

编码:关于每一种流,他们本质上都是文件的字节码,所以需求有一种规定好的编码方法,事先声明在特定的方位,这样播放器才干用专门的解码器播放。常见的视频编码例如h264,h265(又叫hevc),vp9等等,常见的音频编码例如aac,mp3等等,常见的字幕有SRT,ASS等。

容器中各部分的编码不是随意调配的,一种容器一般支撑不止一种编码方法,可是也不是任意编码都能支撑的,有如下调配。

ffmpeg运用指南

ffmpeg运用指南

2 运用ffmpeg转码

ffmpeg的装置十分简略,官网即可下载二进制文件。

ffmpeg最常见的功用便是用来转码,他能够修改容器格局,也能够修改某一个流的编码方法。

例如最常见的指令如下,将mkv文件转mp4

$ ffmpeg -i in.mkv out.mp4

假如想检查当时文件的信息,例如用了什么编码,分辨率等,则去掉out.mp4即可

$ ffmpeg -i in.mkv

例如下面输出显现片头.mov文件有两个stream分别是一个视频流1080P60FPS,码率是301kb,编码是264编码;还有一个音频流是48k采样率,127kb码率,aac编码的。

ffmpeg运用指南

例如pr软件不支撑mkv格局的素材,能够用该指令转化。但该指令会将视频流和音频流都从头编码一遍,假如是电影的话,编码时刻或许要好久。

2.1 指定编码方法-c

比如mkv文件的视频流或许原本便是H264编码的,由于mp4容器也支撑该编码,所以不需求对视频流从头编码的,此时能够指定更详细的对音视频流的编码参数。

# -c:v指定视频流编码器 copy是指不从头编码直接copy源视频流
$ ffmpeg -i in.mkv -c:v copy out.mp4

假如不指定编码的情况下,会用mp4这种容器的默许音视频编码器进行编码。

当然假如有指定编码的要求的话,也能够在指定,下面便是视频用264,音频用mp3,终究拼成mp4容器。

$ ffmpeg -i in.mkv -c:v libx264 -c:a libmp3lame out.mp4

这儿的libx264libmp3lame怎么来的呢,能够经过ffmpeg -codecs来检查当时机器支撑的编解码器,或许会十分多能够挑选一下。例如想知道能nv显卡加快的编码有哪些,能够过滤nvenc来检查。

$ ffmpeg -codecs|findstr nvenc
DEV.L. av1                  Alliance for Open Media AV1 (decoders: libdav1d libaom-av1 av1 av1_cuvid av1_qsv ) (encoders: libaom-av1 librav1e libsvtav1 av1_nvenc av1_qsv av1_amf )
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_qsv h264_cuvid ) (encoders: libx264 libx264rgb h264_amf h264_mf h264_nvenc h264_qsv )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_cuvid ) (encoders: libx265 hevc_amf hevc_mf hevc_nvenc hevc_qsv )

咱们发现264和265都能够用nv显卡加快(当然你得是有nv显卡的机器才干显现上面,否则是没有),上面的后面括号中展示了编码器和解码器的名字,咱们之前便是用的libx264编码器,这儿咱们将之前的指令改为nv显卡的编码

$ ffmpeg -i in.mkv -c:v h264_nvenc -c:a libmp3lame out.mp4

我的显卡由于比较老在运用hevc_nvenc时报错B frames as references are not supported,需求封闭B frame:

$ ffmpeg -i in.mkv -c:v hevc_nvenc -c:a libmp3lame  -b_ref_mode 0 out.mp4

例如咱们将之前展示的片头.mov依照h265 mp3转码后输出如下,能够看到视频流和音频流编码都发生了对应的改动,而对应的实际转化耗时,能够经过最后一行speed=7.21x换算,由于time=00:00:23即23s,转化速度是7.21倍播放速度,所以转化时刻 = 23/7.21 = 3s 左右。

ffmpeg运用指南

2.2 多音轨/字幕操作

很多电影有多个音轨或者字幕。例如这儿有一个mkv文件,含有2个音轨,都是ac3。

ffmpeg运用指南

咱们将mkv转mp4,其间视频流部分咱们直接copy(节省时刻),音频的编码很快不必copy。

$ ffmpeg -i in.mkv -c:v copy out.mp4

从log中咱们发现,只有stream0:0stream0:1被转化了,这俩是原来的视频和其间一个音频流。stream0:1是指输入文件的第0个文件中的第1个流,由于咱们input就只有一个文件,所以第一位一直是0。

ffmpeg运用指南

即,默许情况下,视频的转化会只转化一个视频流和一个音频流,假如有多个音频流的话,只会转化第一个,同时默许情况下,字幕流不会被转化。

这是原本有字幕的视频

ffmpeg运用指南

转化完,没有了字幕

ffmpeg运用指南

怎么保存多个音轨、字幕,一般能够运用map参数,-map 0:v是指第0个input文件的视频流转到output,-map 0:a:0便是第0个文件的第0个音频流搞过来,这样就把俩音轨都搞过来了。

$ ffmpeg -i input.mkv -map 0:v -map 0:a:0 -map 0:a:1 -c:v copy -c:a copy output.mp4

ffmpeg运用指南

更详细的咱们还能够分别对每个音轨指定编码和比特率

$ ffmpeg -i input.mkv 
-map 0:v -c:v copy 
-map 0:a:0 -c:a:0 libmp3lame 
-map 0:a:1 -c:a:1 libvorbis -b:a:1 128k  
-map 0:s:0 -c:s:0 srt 
output.mp4

当然咱们需求留意,新的容器得能支撑对应的格局和功用,尤其是字幕功用,很多容器的支撑是比较有限的,假如从mkv这种很强的字幕支撑度,到比较弱的格局需求有些调整。

3 分辨率 比特率 帧率调整

-s参数直接指定目标输出的分辨率,-r则是帧率,-b是比特率,在上面现已见过了,需求分别对音视频指定。

$ ffmpeg -i input.mp4 -s 720x480 -r 30 -b:v 2M -b:a 128k output.mp4

-s的分辨率是等比扩缩,怎么要截断的话,则需求用filter这个在后面介绍。

# scale指定宽高,还有原点方位,ow oh是输出文件的宽高,iw ih则是输入文件宽高。
$ ffmpeg -i input.mp4 -filter:v "scale=800:600:x=ow/2:y=0" output.mp4

4 提取音频

直接指定输出的文件格局就能够提取音频。

$ ffmpeg -i in.mkv out.mp3

5 视频截取与拼接

截取,-ss指定截取开始的时刻,-t指定继续时长。

$ ffmpeg -i input.mp4 -ss 00:00:20 -t 00:00:05 -c copy output.mp4

关于多个视频拼接,则需求先预备一个input.txt

file 'input1.mp4'
file 'input2.mp4'

然后指定该文件为输入,-f指定concat按顺序拼接,需求留意的是,要拼接的视频文件的编码器和格局必须相同,否则拼接或许会失利,所以拼接还是比较麻烦的。

$ ffmpeg -f concat -i input.txt -c copy output.mp4

6 filter

filter我并不会常用,所以这儿只贴一个简略的介绍,遇到需求的时候再问chatGPT。

ffmpeg运用指南

7 ffmpeg的输入

-i能够接本地视频文件,txt格局的视频列表,还能接直播流

$ ffmpeg -i rtmp://example.com/live/stream -c copy output.mp4

还能够录制屏幕

$ ffmpeg -f gdigrab -framerate 30 -i desktop -f dshow -i audio="麦克风 (Realtek High Definition Audio)" -c:v libx264 -preset ultrafast -c:a aac -b:a 128k output.mp4

gdigrab是用于在windows上获取屏幕图像的设备,dshow则是展示设备,-i audio=xxx能够指定录音设备,同时录制音频。 -i desktop便是整个桌面,也能够替换为某一个windows下的窗口-i title=WindowName-preset ultrafas是以性能优先的预设。

这儿没有录制电脑自己的声响,假如还要录制电脑声响,则还得把电脑声响虚拟成一个设备,需求下载一个虚拟器,一般obs都自带了,所以假如有真实杂乱的录制屏幕需求,请直接用图形化工具obs,他底层也是ffmpeg。