ffmpeg
1 布景常识
一个视频文件是由视频 音频 字幕等重要部分组成的。视频格局,例如咱们常见的mp4
,mkv
,mov
,flv
,avi
,wmv
等等,他们其实都是容器,这个容器里边包裹了视频流
,音频流
,字幕
,其他流
等内容,当然不一定一切的部分都有数据,例如或许没有字幕。
多条:关于同一种流,也或许有多条,例如某些电影文件就有多条音频流,中文和英文的音轨,也或许有多个言语的字幕。
编码:关于每一种流,他们本质上都是文件的字节码,所以需求有一种规定好的编码方法,事先声明在特定的方位,这样播放器才干用专门的解码器播放。常见的视频编码例如h264
,h265(又叫hevc)
,vp9
等等,常见的音频编码例如aac
,mp3
等等,常见的字幕有SRT
,ASS
等。
容器中各部分的编码不是随意调配的,一种容器一般支撑不止一种编码方法,可是也不是任意编码都能支撑的,有如下调配。
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编码的。
例如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
这儿的libx264
和libmp3lame
怎么来的呢,能够经过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 左右。
2.2 多音轨/字幕操作
很多电影有多个音轨或者字幕。例如这儿有一个mkv
文件,含有2个音轨,都是ac3。
咱们将mkv转mp4,其间视频流部分咱们直接copy(节省时刻),音频的编码很快不必copy。
$ ffmpeg -i in.mkv -c:v copy out.mp4
从log中咱们发现,只有stream0:0
和stream0:1
被转化了,这俩是原来的视频和其间一个音频流。stream0:1
是指输入文件的第0个文件中的第1个流,由于咱们input就只有一个文件,所以第一位一直是0。
即,默许情况下,视频的转化会只转化一个视频流和一个音频流,假如有多个音频流的话,只会转化第一个,同时默许情况下,字幕流不会被转化。
这是原本有字幕的视频
转化完,没有了字幕
怎么保存多个音轨、字幕,一般能够运用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 -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。
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。