FFmpeg学习记录

基本概念

编解码

编码:通过一定协议或规则把一段声音或图像转化成计算机数字文件的过程
解码:把编码过的媒体文件重新转化成声音或图像
编码器”(Coder 或 Encoder):用来执行编码工作的软件
解码器”(Decoder):用来执行解码工作的软件
“编码器”与“解码器”合称“编解码器”(“Codec”)
又根据处理对象分为音频(audio)/视频(video)编解码器
“音频编码器”编码出单个音频文件,
“视频编码器”编码出单个视频文件,
“音频解码器”单独对音频文件进行解码还原,
“视频解码器”单独对视频文件进行解码还原。

编码格式

视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。
常见的视频编码格式:

H.262 H.264 H.265

常见的音频编码格式:

mp3 aac

ffmpeg -codecs
#查看 FFmpeg 支持的编码格式

编码器

编码器(encoders)是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。
以下是一些 FFmpeg 内置的视频编码器。

libx264:最流行的开源 H.264 编码器
NVENC:基于 NVIDIA GPU 的 H.264 编码器
libx265:开源的 HEVC 编码器
libvpx:谷歌的 VP8 和 VP9 编码器
libaom:AV1 编码器

音频编码器:

libfdk-aac aac

合成

混流(muxing):将视频流、音频流甚至是字幕流捆绑到一个单独的文件中,作为一个信号进行传输
**分流(demuxing)*将视频、音频或字幕分解出来各自进行解码和播放。
在 muxing 与 demuxing 的整个过程,都不对原来的视频、音频或字幕重新编码。混流(封装、打包)后的文件,可以通过分离(分解、解包)操作,获得与原始素材一模一样的独立的视频、音频和字幕文件。

所谓“合成”,只是把音频流和视频流用一个容器文件(Container)封装起来,其实里面还是各自独立的。我们在播放视频文件的时候总是先调用分离器(Splitter),将封装合成的视频“分离”成独立的音频和视频码流,然后才调用解码器对这些独立的音频流和视频流进行解码输出。
播放一个视频的过程如下:

  1. 播放器打开视频源文件
  2. 播放器调用分离器将视频文件分解为单独的音频流和视频流
  3. 播放器调用音频解码器对音频流进行解码,同时调用视频解码器对视频流进行解码
  4. 播放器依据同样的时间线将解码后的音频流和视频流输出到播放窗口并使之保持同步。

滤镜

分离器,视频解码器和音频解码器的统称
碰到有声无画或者有画无声,就应该自己从解码器着手,替换一个试试。

容器

视频文件本身其实是一个容器(container),里面包括了视频和音频,也可能有字幕等其他内容。常见的容器格式有以下几种。

mp4, mkv, webm, avi

ffmpeg -formats
# 查看 FFmpeg 支持的容器

FFmpeg

usage

ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
ffmpeg \
-y \ # 全局参数
-c:a libfdk_aac -c:v libx264 \ # 输入文件参数
-i input.mp4 \ # 输入文件
-c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数
output.webm # 输出文件

-y                  overwrite output files
-c codec            codec name

如果不指明编码格式,FFmpeg 会自己判断输入文件的编码, 例如

ffmpeg -i input.avi output.mp4

常用命令行参数

-c:指定编码器
-c copy:直接复制,不经过重新编码(这样比较快)
-c:v:指定视频编码器
-c:a:指定音频编码器
-i:指定输入文件
-an:去除音频流
-vn: 去除视频流
-preset:指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。
-y:不经过确认,输出时直接覆盖同名文件。

常见用法

查看视频文件的元信息

比如编码格式和比特率,可以只使用-i参数

ffmpeg -i ganjam.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ganjam.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2015-11-04T04:20:32.000000Z
  Duration: 00:26:09.21, start: 0.000000, bitrate: 699 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 97 kb/s (default)
    Metadata:
      creation_time   : 2015-11-04T04:20:32.000000Z
      handler_name    : Core Media Audio
    Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709, progressive), 854x480, 599 kb/s, SAR 1:1 DAR 427:240, 24 fps, 24 tbr, 24 tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2015-11-04T04:20:32.000000Z
      handler_name    : Core Media Video

ffmpeg -i input.mp4 -hide_banner 
#只显示元信息

转换编码格式(transcoding)

转换编码格式(transcoding)指的是, 将视频文件从一种编码转成另一种编码。
比如转成 H.264 编码,一般使用编码器libx264,所以只需指定输出文件的视频编码器即可。

ffmpeg -i qq.mp4 -c:v libx265 qq265.mp4
video:924kB audio:50kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 0.659506%
x265 [info]: frame I:      2, Avg QP:30.29  kb/s: 10513.08
x265 [info]: frame P:     20, Avg QP:30.85  kb/s: 4784.32 
x265 [info]: frame B:     71, Avg QP:34.17  kb/s: 1554.15 
x265 [info]: Weighted P-Frames: Y:45.0% UV:30.0%
x265 [info]: consecutive B-frames: 13.6% 0.0% 9.1% 4.5% 72.7% 

encoded 93 frames in 31.51s (2.95 fps), 2441.48 kb/s, Avg QP:33.37

这时的文件扩展名很具有欺骗性

转换容器(transmuxing)格式

将视频文件从一种容器转到另一种容器

ffmpeg -i qq.mp4 -c copy output.webm

上面例子中,只是转一下容器,内部的编码格式不变,所以使用-c copy指定直接拷贝,不经过转码,这样比较快。
(ps。[webm @ 0x55822287de80] Only VP8 or VP9 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM. av_interleaved_write_frame(): Invalid argument Error writing trailer of qq.webm: Invalid argument

ffmpeg -i audio_input.wav audio_output_1.mp3 audio_output_2.ogg

将输入转成多个格式的输出文件

ffmpeg -i video_input.wav -qscale 0 video_output.mp4

在输出文件前加-qscale 0来保存文件之类

调整码率(transrating)

改变编码的比特率,一般用来将视频文件的体积变小。下面的例子指定码率最小为964K,最大为3856K,缓冲区大小为 2000K。

ffmpeg -i qq.mp4 -minrate 946K -maxrate 3856K -bufsize 2000K qq_rate.mp4

可正常播放
音频 -b:a / -ab

ffmpeg -i audio_input.mp3 -ab 128k audio_output.mp3
ffmpeg -i audio_input.mp3 -b:a 192k audio_output.mp3

视频

ffmpeg -i video_input.mp4 -b:v 1000k -bufsize 1000k video_output.mp4

Constant Rate Factor 越低码率越高,一般20-30

ffmpeg -i video_input.mp4 -c:v libx264 -crf 28 video_output.mp4

改变帧率

ffmpeg -i video_input.mp4 -r 24 video_output.mp4

改变分辨率(transsizing)

 Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, smpte170m), 1920x1080, 20333 kb/s, SAR 1:1 DAR 16:9, 29.81 fps, 30 tbr, 90k tbn, 180k tbc (default)

原先是1080P,现在改成480P

ffmpeg -i qq.mp4 -s 640*480 qq_480.mp4
#成功
-s  specify a new resolution

ffmpeg -i qq.mp4 -aspect 4:3  qq_480.mp4
-aspect 修改纵横比
ffmpeg -i qq.mp4 -vf scale=480:-1 qq_480p.mp4
-vf filter_graph    set video filters
swscaler @ 0x562c532a0380] deprecated pixel format used, make sure you did set range correctly
[libx264 @ 0x562c52a5e8c0] height not divisible by 2 (480x853)
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[aac @ 0x562c52a5ace0] Qavg: 5343.219
[aac @ 0x562c52a5ace0] 2 frames left in the queue on closing
Conversion failed!

提取音频(demuxing)

ffmpeg  -i qq.mp4 -vn -c:a copy qq_audio.acc
-vn                 disable video

[NULL @ 0x5563cf396580] Unable to find a suitable output format for 'qq_audio.acc'
qq_audio.acc: Invalid argument

ffmpeg -i qq.mp4 -vn qq.mp3
# 成功,默认和源文件的码率相同 可选参数:
 -ab (audio bit rate)  -ab 128k,can also be replaced by -b:a
 -ar (audio frequency: 22050, 441000, 48000)
  -ac (number of audio channels
  -f (audio format, although normally automatically detected).
  
 

添加音轨

$ ffmpeg \
-i input.aac -i input.mp4 \
output.mp4

有音频和视频两个输入文件,FFmpeg 会将它们合成为一个文件。

截图

ffmpeg -y -i qq.mp4 -ss 00:00:01 -t 00:00:01 output_%3d.jpg

-ss time_off        set the start time offset
-t duration         record or transcode "duration" seconds of audio/video
从视频的第一秒,连续对1s的视频进行截图

在这里插入图片描述

 ffmpeg -ss 00:00:02 -i qq.mp4 -vframes 1 output.jpg
-vframes number     set the number of video frames to output
ffmpeg -y -ss 00:00:02 -i qq.mp4 -vframes 1 -q:v 3 output.jpg
-q:v 2表示输出的图片质量,一般是1到5之间(1 为质量最高)。
ffmpeg -i video.mp4 -r 1 -f image2 image-%3d.png

-r 指定提取图像的帧率
-f 指定输出格式
%3d命名 001 002
也可以将一系列图片转换成video/slideshow

裁剪

截取原始视频里面的一个片段,输出为一个新视频。可以指定开始时间(start)和持续时间(duration),也可以指定结束时间(end)

$ ffmpeg -ss [start] -i [input] -t [duration] -c copy [output]
$ ffmpeg -ss [start] -i [input] -to [end] -c copy [output]
ffmpeg -ss 00:00:01 -i qq.mp4 -t 3.5 -c copy qq_part.mp4

不指定-ss的话,默认从最开始算
duration有两种格式,一个数字(s),或HH:MM:SS

为音频加封面

有些视频网站只允许上传视频文件。如果要上传音频文件,必须为音频添加封面,将其转为视频,然后上传。

下面命令可以将音频文件,转为带封面的视频文件。


$ ffmpeg \
-loop 1 \
-i cover.jpg -i input.mp3 \
-c:v libx264 -c:a aac -b:a 192k -shortest \
output.mp4
#上面命令中,有两个输入文件,一个是封面图片cover.jpg,另一个是音频文件input.mp3。-loop 1参数表示图片无限循环,-shortest参数表示音频文件结束,输出视频就结束。

高级用法[3]

包含
将一个视频拆解成多个视频
将多个视频合并成一个视频(扩展名一致)
将多个图片合并成一个视频(扩展名一致)
录屏(需要安装xserver)
通过webcam或其他设备录像
录音
视频缩放
视频裁剪Video Cropping
视频旋转
音频频道重映射
音频扩大音量
改变视频/音频播放速度

关于音视频的一些知识(demux、filter等
FFmpeg 视频处理入门教程
The Complete Guide for Using ffmpeg in Linux

你可能感兴趣的:(FFmpeg学习记录)