FFmpeg - Arch Linux 中文维基

跳至內容

# FFmpeg

出自 Arch Linux 中文维基

相關文章

- Convert FLAC to MP3#With FFmpeg

翻譯狀態：

- 本文（或部分內容）譯自 FFmpeg，最近一次同步於 2024-01-19，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

摘自項目主頁：

  FFmpeg 是一個完整的跨平台音視頻錄製、轉換及串流方案。它包含了 libavcodec - 業界領先的音視頻編解碼器庫。

## 安裝

注意：你可能會碰到像是 libav 或是 avconv 這樣的 FFmpeg 分支，可以參考博客 FFmpeg/Libav 現狀一文來了解各項目區別及 FFmpeg 的現狀。

安裝 ffmpeg包 包。

如需開發版本，可安裝 ffmpeg-gitAUR。同時另有 ffmpeg-fullAUR，它儘可能地提供了所有可用的的可選特性。

## 編碼案例

注意：

- 將參數按順序排列非常重要（像是 輸入，視頻，過濾器，音頻，輸出）。不這麼做可能導致參數被略過，或是使 FFmpeg 無法運行。
- FFmpeg 應該自動使用所有 CPU 線程。但你也可以通過 `-threads number` 參數指定使用的線程數。

參考 FFmpeg 編碼維基和 ffmpeg(1) § EXAMPLES。

### 屏幕捕獲

FFmpeg 包含了 x11grab 及 ALSA 虛擬設備，可用於捕獲用戶的全部音頻及顯示輸入。

使用如下命令創建截圖 `screen.png`：

    $ ffmpeg -f x11grab -video_size 1920x1080 -i $DISPLAY -vframes 1 screen.png

其中 `-video_size` 指定了截圖區域大小。

使用如下命令創建無損編碼且不含音頻的錄屏 `screen.mkv`：

    $ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -c:v ffvhuff screen.mkv

這裡使用了 Huffyuv 編碼器，速度很快，但輸出文件體積非常大。

使用如下命令創建有損編碼且包含音頻的錄屏 `screen.mp4`：

    $ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac screen.mp4

這裡使用了 x264 編碼器及最快編碼速度選項。你也可以使用其它編碼器；如果由於磁碟速度低或是編碼速度慢導致幀寫入速度太慢，幀率將會下降，導致輸出的視頻出現卡頓。

If the video stream should not be saved as a file, but used as a virtual webcam for screen sharing purposes, see v4l2loopback#Casting X11 using FFmpeg.

另外可參考官方文檔。

### 錄製攝像頭

FFmpeg 包含了 video4linux2 及 ALSA 虛擬設備，可用於捕獲攝像頭及音頻輸入。

假設攝像頭位於 `/dev/video0`，下面的命令將會錄製攝像頭的輸入到 `webcam.mp4`，不包含音頻：

    $ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -c:v libx264 -preset ultrafast webcam.mp4

其中 `-video_size` 指定了來自攝像頭的最大圖像大小。

上述命令將生成一個無聲視頻。如果要從攝像頭錄製視頻和聲音到 `webcam.mp4`：

    $ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac webcam.mp4

這裡使用了 x264 編碼器及最快編碼速度選項。你也可以使用其它編碼器；如果由於磁碟速度低或是編碼速度慢導致幀寫入速度太慢，幀率將會下降，導致輸出的視頻出現卡頓。

另外可參考官方文檔。

### VOB to any container

Concatenate the desired VOB files into a single stream and mux them to MPEG-2:

    $ cat f0.VOB f1.VOB f2.VOB | ffmpeg -i - out.mp2

### x264

#### 無損

ultrafast 預設提供了最快的編碼速度，適用於快速捕獲（例如錄屏）：

    $ ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 -c:a copy output

與之相反，veryslow 的編碼速度比 ultrafast 慢，但生成文件會更小：

    $ ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 -c:a copy output

上述兩個實例都提供一致的輸出質量。

提示：如果你的電腦能實時處理 `-preset superfast`，就不要使用 `-preset ultrafast`。Ultrafast 的壓縮效率遠低於 superfast。

#### 恆定速率因子

在需要特定輸出質量時使用，通常在輸出質量可接受的情況下使用儘可能高的 `-crf` 值。值越低質量越高：0 代表無損，18 為視覺上無損，默認為 23，正常使用的範圍為 18~28。在你有耐心的情況下可以使用最慢的 `-preset`。詳細信息可參考 x264 編碼指南。

    $ ffmpeg -i video -c:v libx264 -tune film -preset slow -crf 22 -x264opts fast_pskip=0 -c:a libmp3lame -aq 4 output.mkv

`-tune` 選項可用於匹配正在編碼的媒體類型及內容。

#### 二次編碼（非常高質量）

第一次編碼僅記錄視頻分析數據，因此在輸入中禁用音頻：

    $ ffmpeg -i video.VOB -an -vcodec libx264 -pass 1 -preset veryslow \
    -threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 -f rawvideo -y /dev/null

容器格式將被自動檢測，並混合到輸出文件擴展名（`.mkv`）中：

    $ ffmpeg -i video.VOB -acodec aac -b:a 256k -ar 96000 -vcodec libx264 \
    -pass 2 -preset veryslow -threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 video.mkv

#### 視頻消抖

視頻消抖將用到 vid.stab 插件，其需要使用二次編碼。

##### 第一次編碼

第一次編碼將消抖參數記錄到文件和/或測試視頻中以用於視覺分析。

- 使用該命令僅將消抖參數記錄到文件中：

      $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf -f null -

- 使用該命令將消抖參數記錄到文件中，並創建名為「output-stab」的測試視頻用於視覺分析：

      $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf output-stab

##### 第二次編碼

第二次編碼將應用第一次編碼生成的參數，並輸出「output-stab_final」文件。你可能需要在該階段應用其它濾鏡以避免後續轉碼，從而儘可能地提高視頻質量。

- `unsharp` 由 vid.stab 的作者建議，在這裡我們使用默認的 5:5:1.0:5:5:1.0
- 提示：fade=t=in:st=0:d=4
  在文件開頭加入4秒從黑色淡入
- 提示：fade=t=out:st=60:d=4
  在第60秒加入4秒淡出到黑色
- `-c:a pcm_s16le` 使用 XAVC-S 編碼器以 pcm_s16be 格式錄製，即有損轉碼為 pcm_s16le

    $  ffmpeg -i input -vf vidstabtransform=smoothing=30:interpol=bicubic:input=transforms.trf,unsharp,fade=t=in:st=0:d=4,fade=t=out:st=60:d=4 -c:v libx264 -tune film -preset veryslow -crf 8 -x264opts fast_pskip=0 -c:a pcm_s16le output-stab_final

### x265

Example command showing the defaults when libx265 is invoked without any parameters (Constant Rate Factor encoding):

    ffmpeg -i input -c:v libx265 -crf 28 -preset medium -c:a libvorbis output.mp4

See FFmpeg H.265/HEVC Video Encoding Guide for more information.

### Single-pass MPEG-2 (near lossless)

Allow FFmpeg to automatically set DVD standardized parameters. Encode to DVD MPEG-2 at ~30 FPS:

    $ ffmpeg -i video.VOB -target ntsc-dvd output.mpg

Encode to DVD MPEG-2 at ~24 FPS:

    $ ffmpeg -i video.VOB -target film-dvd output.mpg

### 字幕

#### 提取

字幕被嵌入到像 MPEG-2 和 Matroska 這樣的容器文件中，可以被提取和轉換成 SRT，SSA，WebVTT 等字幕格式 [1]。

- 檢查文件是否包含字幕流：

    $ ffprobe -hide_banner foo.mkv

    ...
    Stream #0:0(und): Video: h264 (High), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
      Metadata:
      CREATION_TIME   : 2012-06-05 05:04:15
      LANGUAGE        : und
    Stream #0:1(und): Audio: aac, 44100 Hz, stereo, fltp (default)
     Metadata:
     CREATION_TIME   : 2012-06-05 05:10:34
     LANGUAGE        : und
     HANDLER_NAME    : GPAC ISO Audio Handler
    Stream #0:2: Subtitle: ssa (default)

- `foo.mkv` 嵌入了一個 SSA 字幕，可以被提取到單獨的文件中：

    $ ffmpeg -i foo.mkv foo.ssa

使用 `-c:s srt` 可以將字幕保存為目標格式，以 SubRip 為例：

    $ ffmpeg -i foo.mkv -c:s srt foo.srt

在處理多個字幕時，你可能需要使用 `-map key:stream` 參數指定要提取的流：

    $ ffmpeg -i foo.mkv -map 0:2 foo.ssa

#### 硬字幕嵌入

（以下操作基於 FFmpeg 維基的 HowToBurnSubtitlesIntoVideo 一文）

硬字幕嵌入將把字幕整合到視頻中。硬字幕無法被編輯，也無法切換語言。

- 將 `foo.ssa` 整合到 `foo.mpg` 中：

    $ ffmpeg -i foo.mpg -vf subtitles=foo.ssa out.mpg

### 音量增益

可以通過 ffmpeg 的過濾器功能來修改音量增益。首先通過 `-af` 或是 `-filter:a` 參數選定音頻流，然後選擇 volume 過濾器，後接你要將流改成的目標值。例如：

    $ ffmpeg -i input.flac -af volume=1.5 ouput.flac

在這一例子中，`volume=1.5` 指 150% 音量增益，也可以使用 0.5 將音量減半。也可以對音量過濾器使用分貝值，例如 `volume=3dB` 可以將音量提升 3dB，`volume=-3dB` 可以將音量降低 3dB。

注意：將文件的音量增益增倍與增倍其音量不同。你需要通過試驗才能找出合適的音量。
提示：可以通過 volumedetect 過濾器查看當前文件的平均及最大音量：`ffmpeg -i input.flac -af volumedetect -f null -`。然後可以將目標值與當前值相減，把結果輸入到 volume 過濾器來達到目標增益。

### Volume normalization

A given average and peak volume can also be achieved through normalization using the loudnorm filter. To normalize the perceived loudness of a file using fmpeg's default values for target average, peak and range loudness (respectively -24 LUFS, -2 dBTP and 7 LU), use:

    $ ffmpeg -i input.flac -af loudnorm output.flac

To obtain a different loudness profile, use the `i`, `tp` and `lra` parameters of the filter to indicate respectively the integrated, true peak and loudness range. For example for a higher perceived loudness than the default, use:

    $ ffmpeg -i input.flac -af loudnorm=i=-16:tp=-1.5:lra=11:print_format=summary output.flac

In this example, `print_format=summary` is also added to display the input and output loudness values of the audio file.

注意：The filter also supports two-pass mode, extracting the measured loudness values from a first run and using them in a second run to perform a linear normalization. See ffmpeg loudnorm documentation for more information.
提示：To know the current loudness measures of a file, use `ffmpeg -i input.flac -af loudnorm=print_format=summary -f null -`.

### Extracting audio

    $ ffmpeg -i video.mpg output.ext

    ...
    Input #0, avi, from 'video.mpg':
      Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
        Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
        Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
        Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
        Stream #0.3: Audio: dts, 48000 Hz, 5.1 768 kb/s
    ...

Extract the first (`-map 0:1`) AC-3 encoded audio stream exactly as it was multiplexed into the file:

    $ ffmpeg -i video.mpg -map 0:1 -acodec copy -vn video.ac3

Convert the third (`-map 0:3`) DTS audio stream to an AAC file with a bitrate of 192 kb/s and a sampling rate of 96000 Hz:

    $ ffmpeg -i video.mpg -map 0:3 -acodec aac -b:a 192k -ar 96000 -vn output.aac

`-vn` disables the processing of the video stream.

Extract audio stream with certain time interval:

    $ ffmpeg -ss 00:01:25 -t 00:00:05 -i video.mpg -map 0:1 -acodec copy -vn output.ac3

`-ss` specifies the start point, and `-t` specifies the duration.

### Stripping audio

1. Copy the first video stream (`-map 0:0`) along with the second AC-3 audio stream (`-map 0:2`).
2. Convert the AC-3 audio stream to two-channel MP3 with a bitrate of 128 kb/s and a sampling rate of 48000 Hz.

    $ ffmpeg -i video.mpg -map 0:0 -map 0:2 -vcodec copy -acodec libmp3lame \
    -b:a 128k -ar 48000 -ac 2 video.mkv

    $ ffmpeg -i video.mkv

    ...
    Input #0, avi, from 'video.mpg':
      Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
        Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
        Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s

注意：Removing undesired audio streams allows for additional bits to be allocated towards improving video quality.

### Splitting files

You can use the `copy` codec to perform operations on a file without changing the encoding. For example, this allows you to easily split any kind of media file into two:

    $ ffmpeg -i file.ext -t 00:05:30 -c copy part1.ext -ss 00:05:30 -c copy part2.ext

### 硬體加速

可以使用硬體加速 API 來提升編解碼性能，但只有特定編解碼器受支持，且輸出與軟體編碼相比不一定每次都一樣。

#### VA-API

VA-API適用於 Intel CPU（需要安裝 intel-media-driver包 或 libva-intel-driver包）及部分使用開源 AMDGPU 驅動的 AMD GPU（需要安裝 libva-mesa-driver包），可用於編碼及解碼。 詳細可用參數及受支持平台清單可參考 FFmpeg 文檔。

以使用受支持的 H.264 編解碼器進行編碼為例：

    $ ffmpeg -threads 1 -i file.ext -vaapi_device /dev/dri/renderD128 -vcodec h264_vaapi -vf format='nv12|vaapi,hwupload' output.mp4

注意： 只要檢測到了 libva包 （應為 FFmpeg 的依賴之一）包含的相關頭文件及庫，VA-API 通常在構建階段就被通過 ffmpeg包 的自動檢測功能啟用。

作為參考，可以使用如下命令生成固定質量的編碼：

    $ ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf 'format=nv12,hwupload' -c:v hevc_vaapi -f mp4 -rc_mode 1 -qp 25 output.mp4

如果使用 hevc_vaapi，可以將 -qp 參數提到 25（視覺上相同）及以上（從 28 開始視覺上損失極小）。如果使用 h264_vaapi，可以調整到 18（視覺上相同）及以上（從 20 開始視覺上損失極小）。另外，hevc_vaapi 似乎編碼速度比 h264_vaapi 高 50%。

#### NVIDIA NVENC/NVDEC

在通過 nvidia-utils包 安裝私有的 NVIDIA 驅動後，可以使用 NVENC 和 NVDEC 進行編/解碼加速。最低支持的 GPU 為 600 系列，詳情可參考硬體視頻加速#NVIDIA。

這個舊 gist 提供了一些技巧。NVENC 似乎與 CUDA 類似，因此它甚至可以在命令行會話中被調用。按照硬體不同，NVENC 可以比 Intel 的 VA-API 編碼器速度快上幾倍。

可以使用如下命令查看可用選項（也可使用 `hevc_nvenc`）：

    $ ffmpeg -help encoder=h264_nvenc

用例：

    $ ffmpeg -i source.ext -c:v h264_nvenc -rc constqp -qp 28 output.mkv

#### Intel QuickSync (QSV)

Intel® Quick Sync Video 利用了 Intel GPU 的媒體處理能力加速編解碼，使得處理器可忙於其它任務，提升系統響應。

這一功能需要安裝 libmfx 運行時實現。 libmfx 是一個調度庫，可根據所在硬體平台實時加載對應的實現。

在 Iron Lake（Gen5）到 Ice Lake（Gen10）GPU 上運行時，它會加載 intel-media-sdk包 作為運行時實現。

在 Tiger Lake（Gen11）及更新的 GPU 上運行時，libmfx 會加載 vpl-gpu-rt包。另外可參考 oneVPL-intel-gpu system-requirements。

在只有單個 Intel GPU 的設備上無法更改或選擇運行時實現，且在運行時需已安裝對應的實現。

未安裝運行時將產生如下報錯：

    [AVHWDeviceContext @ 0x558283838c80] Error initializing an MFX session: -3.
    Device creation failed: -1313558101.

QuickSync 的用法已在 FFmpeg 維基中描述。建議使用 VA-API [2] 搭配 iHD 或 i965 驅動，而不是直接使用 libmfx，詳情可參考 FFmpeg 維基中 Hybrid transcode 部分的編碼示例，以及通過硬體視頻加速#Configuring VA-API 了解驅動配置。

#### AMD AMF

AMD 通過 AMDGPU PRO 專有包為 Linux 僅提供了 H.264 使用 AMD Video Coding Engine（GPU 編碼）進行視頻編碼的支持，ffmpeg 另外添加了 AMF 視頻編碼支持。因此，如果要使用 h264_amf 視頻編碼器進行編碼，需要安裝 amf-amdgpu-proAUR。你可能需要將 AMDGPU PRO 包提供的 ICD 文件以變量形式進行連結，否則 ffmpeg 可能會使用開源 AMDGPU 的 ICD 文件，使得無法使用該視頻編碼器。編碼的命令示例如下：

    $ VK_DRIVER_FILES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mkv -c:v h264_amf -rc 1 -b:v 8M h264_amf_8M.mp4

作為參考，可以使用如下命令生成固定質量的編碼：

    $ VK_DRIVER_FILES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mp4 -c:v h264_amf -f mp4 -rc 0 -qp_b 22 -qp_i 22 -qp_p 22 -quality 2 output.mp4

可以將三個 -qp_(b|i|p) 參數同時提到 18（視覺上相同）及以上（從 22 開始視覺上損失極小）。

### Animated GIF

Whilst animated GIFs are generally a poor choice of video format due to their poor image quality, relatively large file size and lack of audio support, they are still in frequent use on the web. The following command can be used to turn a video into an animated GIF:

    $ ffmpeg -i input.mp4 -vf "fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop -1 output.gif

See http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html for more information on using the palette filters to generate high quality GIFs.

## 預設文件

將默認預設文件放入 `~/.ffmpeg`：

    $ cp -iR /usr/share/ffmpeg ~/.ffmpeg

參考如下方法創建新配置文件或修改現有默認預設文件：

    ~/.ffmpeg/libavcodec-vhq.ffpreset

    vtag=DX50
    mbd=2
    trellis=2
    flags=+cbp+mv0
    pre_dia_size=4
    dia_size=4
    precmp=4
    cmp=4
    subcmp=4
    preme=2
    qns=2

### 使用預設文件

在聲明要使用的 `-vcodec` 後啟用 `-vpre` 選項

#### libavcodec-vhq.ffpreset

- `libavcodec` = 音/視頻編解碼器名稱
- `vhq` = 要調用的預設名稱
- `ffpreset` = FFmpeg 預設文件後綴

## Tips and tricks

### Reduce verbosity

Use a combination of the following options to reduce verbosity to the desired level:

- `-hide_banner`: prevents ffmpeg from outputting its copyright notice, build options and library versions
- `-loglevel`: modulates verbosity (fine-tuning options are available), e.g. `-loglevel warning`
- `-nostats`: disables printing of encoding progress/statistics

### Output the duration of a video

    $ ffprobe -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 file.ext

### Output stream information as JSON

    $ ffprobe -v quiet -print_format json -show_format -show_streams file.ext

### Create a screen of the video every X frames

    $ ffmpeg -i file.ext -an -s 319x180 -vf fps=1/100 -qscale:v 75 %03d.jpg

## 參考

- FFmpeg 文檔 - 官方文檔
- FFmpeg 維基 - 官方維基
- 使用 x264 編碼器進行編碼 - MEncoder 文檔
- H.264 編碼指南 - Avidemux 維基
- 使用 FFmpeg - Linux 教程頁
- 受支持的音頻及視頻流列表

分類：​

- 音頻
- 視頻

FFmpeg
新增話題