ffmpeg

发布时间 2023-10-11 20:27:44作者: dongye95

参考:https://zhuanlan.zhihu.com/p/455572544

ffmpeg介绍

ffmpeg 是一个处理媒体文件的命令行工具 (command line based) 。它是一个拥有非常多功能的框架,并且因为他是开源的,很多知名的工具如 VLC,YouTube, iTunes 等等,都是再其之上开发出来的。

ffmpeg最吸引我的地方就是它可以用非常简练的方式(通过一两个命令)完成许多的处理任务,当然,作为一个强大的工具,他也有很多较为复杂的使用方式,有些时候甚至可以代替一个完整的视频处理流程。

安装

mac

brew install ffmpeg

基础使用

命令

使用 ffmpeg 命令基本形式是:

ffmpeg [全局参数] {[输入文件参数] -i 输入文件地址} ... {[输出文件参数] 输出文件地址} ...

要注意的是,所有的参数仅仅对仅接下来的文件有效(下一个文件得把参数再写一遍)。

所有没有使用 -i 指定的文件都被认为是输出文件。 Ffmpeg 可以接受多个输入文件并输出到您指定的位置。你也可以将输入输出都指定为同一个文件名,不过这个时候要在输出文件前使用用 -y 标记。

注意: 你不应该将输入和输出混淆,先指定输入,再指定输出文件

获得媒体文件的信息

ffmpeg 最简单的使用就是用来 显示文件信息 。不用给输出,只是简单的写:

ffmpeg -i file_name

视频和音频文件都可以使用:

ffmpeg -i video_file.mp4 
ffmpeg -i audio_file.mp3

通过ffmpeg查看文件属性

命令会输出很多与您文件无关的信息(ffmpeg本身的信息),虽说这个蛮有用的,你可以使用 -hide_banner 来隐藏掉它们:

ffmpeg -i video_file.mp4 -hide_banner 
ffmpeg -i audio_file.mp3 -hide_banner

转换媒体文件

ffmpeg 最让人称道常用的恐怕就是你轻而易举的在不同媒体格式之间进行自由转换了。你是要指明输入和输出文件名就行了, ffmpeg 会从后缀名猜测格式,这个方法同时适用于视频和音频文件

下面是一些例子:

ffmpeg -i video_input.mp4 video_output.avi 
ffmpeg -i video_input.webm video_output.flv 
ffmpeg -i audio_input.mp3 audio_output.ogg 
ffmpeg -i audio_input.wav audio_output.flac

你也可以同时指定多个输出后缀:

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

这样会同时输出多个文件.

想看支持的格式,可以用:

ffmpeg -formats

同样的,你可以使用 -hide_banner 来省略一些程序信息。

你可以在输出文件前使用 -qscale 0 来保留原始的视频质量:

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

进一步,在 FFmpeg 中,"-c:a" 选项用于指定要使用的音频编码器,"-c:v" 选项用于指定要使用的视频编码器。这些选项可以在转码过程中重新编码音频和视频流,以更改编码格式、码率、分辨率、帧率等参数。

例如,"-c:a libmp3lame" 将使用 LAME MP3 编码器来压缩音频流;而 "-c:v libx264" 将使用 x264 编码器来压缩视频流。如果使用 "-c:a copy" 和 "-c:v copy",则会使用与源文件相同的编码器,而不会对音频和视频进行重新编码。

ffmpeg -i video_input.mp4 -c:v copy -c:a libvorbis video_output.avi
 
这条命令使用FFmpeg将"video_input.mp4"视频文件转换为"video_output.avi"视频文件,同时保留视频流("-c:v copy")并且将音频流转换为Vorbis编码("-c:a libvorbis")

注意: 这样做会让文件后缀使人困惑,所以请避免这么做。

从视频中抽取音频

为了从视频文件中抽取音频,直接加一个 -vn 参数就可以了:

ffmpeg -i video.mp4 -vn audio.mp3

这会让命令复用原有文件的比特率,一般来说,使用 -ab (音频比特率)来指定编码比特率是比较好的:

ffmpeg -i video.mp4 -vn -ab 128k audio.mp3

一些常见的比特率有 96k, 128k, 192k, 256k, 320k (mp3也可以使用最高的比特率)。

其他的一些常用的参数比如 -ar (采样率: 22050, 441000, 48000), -ac (声道数), -f (音频格式, 通常会自动识别的). -ab 也可以使用 -b:a 来替代. 比如:

ffmpeg -i video.mov -vn -ar 44100 -ac 2 -b:a 128k -f mp3 audio.mp3
"-i video.mov": 指定要转换的源文件为 "video.mov"。
"-vn": 告诉 FFmpeg 只转换音频流,而不转换视频流。
"-ar 44100": 设置音频采样率为 44100 Hz。
"-ac 2": 设置音频通道数为 2。
"-b:a 128k": 设置音频比特率为 128 kbps。
"-f mp3": 指定输出文件格式为 MP3。
"audio.mp3": 指定输出文件名为 "audio.mp3"。
  
ffmpeg -i video.mov -vn -acodec pcm_s16le -ar 8000 -ac 1 audio.wav
"ffmpeg":FFmpeg 命令行工具的名称。
"-i test.mp3":指定要转换的源文件为 "test.mp3"。
"-acodec pcm_s16le":设置音频编码器为无损的 PCM,采样大小为 16 位,小端字节序。
"-ac 1":将音频通道数设置为 1(单声道)。
"-ar 8000":将音频采样率设置为 8000 Hz。
"output.wav":指定输出文件名为 "output.wav"。

让视频静音

和之前的要求类似,我们可以使用 -an 来获得纯视频(之前是 -vn).

ffmpeg -i video_input.mp4 -an -video_output.mp4

注意: 这个 -an 标记会让所有的音频参数无效,因为最后没有音频会产生。

从视频中提取图片

这个功能可能对很多人都挺有用,比如你可能有一些幻灯片,你想从里面提取所有的图片,那么下面这个命令就能帮你:

ffmpeg -i video.mp4 -r 1 -f image2 image-%3d.png

"-i video.mp4":指定要处理的源文件为 "video.mp4"。
"-r 1":设置输出视频的帧率为 1 帧每秒。这将使 FFmpeg 每秒只输出一帧图像。默认25。
"-f image2":-f 代表了输出格式,image2 实际上上 image2 序列的意思。合起来表示将输出文件格式设置为图像序列。
"image-%3d.png":指定输出文件名的格式。"%3d" 表示输出文件名中的数字部分应该显示为三位数字。例如,第一张图像的文件名将是 "image-001.png",第二张图像的文件名将是 "image-002.png",以此类推。".png" 表示输出文件格式为 PNG。也可以用 %2d (两位数字) 或者 %4d (4位数字)

更改视频分辨率或长宽比

ffmpeg 来说又是个简单的任务,你只需要使用 -s 参数来缩放视频就行了:

ffmpeg -i video_input.mov -s 1024x576 video_output.mp4

如果不指定音频编码器,则 FFmpeg 默认会将音频流转换为 AAC 格式并使用 libfdk_aac 编码器进行编码。如果源文件没有音频流,则输出文件仍将包含一个空的音频流,其大小可能非常大。因此,如果源文件没有音频流,最好使用 "-an" 选项禁用音频流,以避免输出文件包含不必要的空的音频流。完整命令如下:

ffmpeg -i video_input.h264 -s 640x480 -an video_output.mov

如果源文件 "video_input.h264" 中包含音频流,但没有指定音频编码器 ("-c:a" 选项),则 FFmpeg 默认会将音频流转换为 AAC 格式并使用 libfdk_aac 编码器进行编码。输出文件 "video_output.mov" 包含编码后的音频流和视频流。如果源文件中的音频流已经压缩或编码过,再对其进行重新编码可能会导致音频质量损失和文件大小增加。

如果您知道源文件中的音频流已经是所需的编码和格式,可以使用 "-c:a copy" 选项将音频流直接复制到输出文件中,而无需进行重新编码。这将保留原始音频流的质量和格式,并且可以显著减少处理时间和输出文件的大小。完整命令如下:

ffmpeg -i video_input.h264 -s 640x480 -c:a copy video_output.mov

其中 -c:a copy 可以简写 为 -c:a
ffmpeg -i video_input.h264 -s 640x480 -c:a video_output.mov

你也可是使用-aspect 来更改长宽比:

ffmpeg -i video_input.mp4 -aspect 4:3 video_output.mp4

为音频增加封面图片

有个很棒的方法把音频变成视频,全程使用一张图片(比如专辑封面)。当你想往某个网站上传音频,但那个网站又仅接受视频(比如YouTube, Facebook等)的情况下会非常有用。

下面是例子:

ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4
  
-loop 1:循环使用单个输入图像,这里的值 "1" 表示只使用一次。
-i image.jpg:指定输入图像文件名。
-i audio.wav:指定输入音频文件名。
-c:v libx264:指定使用 libx264 编码器进行视频编码。
-c:a aac:指定使用 AAC 编码器进行音频编码。
-strict experimental:启用实验性特性。如果你使用一个较新的ffmpeg版本(4.x),你就可以不指定 -strict experimental
-b:a 192k:设置音频比特率为 192 kbps。
-shortest:在输入文件的长度不同时,将输出文件的长度截断为最短的输入文件的长度。
output.mp4:指定输出文件名。

为视频增加字幕

另一个常见又很容易实现的要求是给视频增加字母,比如一部外文电源,使用下面的命令将一个 MP4 视频文件 "video.mp4" 与一个 SRT 格式的字幕文件 "subtitles.srt" 结合,生成一个包含字幕的 MP4 文件 "output.mp4"

ffmpeg -i video.mp4 -i subtitles.srt -c:v copy -c:a copy -preset veryfast -c:s srt -map 0 -map 1 output.mp4

  
-i video.mp4:指定输入视频文件名。
-i subtitles.srt:指定输入字幕文件名。
-c:v copy:复制视频流,不进行重新编码。
-c:a copy:复制音频流,不进行重新编码。
-preset veryfast:指定视频编码器的预设参数,这里设置为 "veryfast"。
-c:s srt:指定使用 srt 字幕编码器进行字幕编码。
-map 0:将第一个输入文件(视频文件)映射到输出文件。
-map 1:将第二个输入文件(字幕文件)映射到输出文件。
  

在 FFmpeg 中,视频编码器的 "-preset" 选项可以用于设置编码器的编码速度和输出质量之间的权衡。不同的预设参数会影响编码器的速度和输出质量。以下是一些常用的预设参数:

  • ultrafast:最快的编码速度,但输出质量较低。
  • superfast:非常快的编码速度,输出质量略低于 ultrafast。
  • veryfast:快速的编码速度,输出质量略低于 superfast。
  • faster:比 veryfast 慢一些,但输出质量更好。
  • fast:比 faster 慢一些,输出质量更好。
  • medium:默认预设,输出质量和编码速度相对平衡。
  • slow:比 medium 慢一些,输出质量更好。
  • slower:比 slow 慢一些,输出质量更好。
  • veryslow:最慢的编码速度,但输出质量最好。

这些预设参数会影响编码器的速度和输出质量,选择哪个预设参数应该根据实际需求进行权衡。例如,如果需要快速地对视频进行编码,可以选择较快的预设参数(如 ultrafast 或者 superfast)。如果需要更好的输出质量,可以选择较慢的预设参数(如 slow 或者 veryslow)。

在 FFmpeg 中,字幕编码器的 "-c:s" 选项用于指定输出字幕的编码方式。以下是常用的字幕编码器及其选项:

  • srt:SRT 字幕编码器,选项为 srt。使用 SRT 格式对字幕进行编码,生成的字幕文件后缀为 .srt。
  • ass:ASS 字幕编码器,选项为 ass。使用 ASS 格式对字幕进行编码,支持更多的字幕效果和布局控制,生成的字幕文件后缀为 .ass。
  • subrip:SubRip 字幕编码器,选项为 subrip。使用 SubRip 格式对字幕进行编码,与 SRT 类似,生成的字幕文件后缀为 .srt。
  • webvtt:WebVTT 字幕编码器,选项为 webvtt。使用 WebVTT 格式对字幕进行编码,支持多语言和多轨字幕,生成的字幕文件后缀为 .vtt。
  • mov_text:MOV_TEXT 字幕编码器,选项为 mov_text。使用 MOV_TEXT 格式对字幕进行编码,支持多语言和多轨字幕,生成的字幕文件后缀为 .mov。

选择字幕编码器时,应根据实际需求和字幕文件格式进行选择。例如,如果需要与其他软件兼容,可以选择 SRT 或 SubRip 字幕编码器;如果需要更丰富的字幕效果和控制,可以选择 ASS 字幕编码器;如果需要在 Web 上播放,可以选择 WebVTT 字幕编码器;如果需要与 QuickTime 兼容,可以选择 MOV_TEXT 字幕编码器。

压缩媒体文件

压缩文件可以极大减少文件的体积,节约存储空间,这对于文件传输尤为重要。通过ffmepg,有好几个方法来压缩文件体积。

注意: 文件压缩的太厉害会让文件质量显著降低。

首先,对于音频文件,可以通过降低比特率(使用 -b:a-ab):

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

再次重申,一些常用的比特率有: 96k, 112k, 128k, 160k, 192k, 256k, 320k.值越大,文件所需要的体积就越大。

对于视频文件,选项就多了,一个简单的方法是通过降低视频比特率 (通过 -b:v):

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

你也可以使用 -crf 参数 (恒定质量因子). 较小的crf 意味着较大的码率。同时使用 libx264 编码器也有助于减小文件体积。这里有个例子,压缩的不错,质量也不会显著变化:

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

crf 设置为20 到 30 是最常见的,不过您也可以尝试一些其他的值。

降低帧率在有些情况下也能有效(不过这往往让视频看起来很卡):

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

-r 指示了帧率 (这里是 24)。

你还可以通过压缩音频来降低视频文件的体积,比如设置为立体声或者降低比特率:

ffmpeg -i video_input.mp4 -c:v libx264 -ac 2 -c:a aac -strict -2 -b:a 128k -crf 28 video_output.mp4

"-i video_input.mp4":指定输入视频文件,即要进行转换的原始视频文件。
"-c:v libx264":指定视频编码器为 libx264,使用 H.264 视频编码算法对视频进行压缩。
"-ac 2":指定输出音频为立体声,即两个声道。
"-c:a aac":指定音频编码器为 aac,使用 AAC 音频编码算法对音频进行压缩。
"-strict -2":指定不使用严格的 AAC 编码模式进行编码,以避免一些兼容性问题。
"-b:a 128k":指定音频码率为 128 kbps,控制音频文件大小和音质的平衡。
"-crf 28":指定视频编码质量,CRF(Constant Rate Factor)值越小,视频质量越高,文件大小越大。通常在 18 到 28 之间选择,此处为 28。

裁剪媒体文件(基础)