隨著自媒體興起,許多人會自拍視頻或者找視頻素材裁剪,配上背景音樂或解說,加上各種特效邊框,處理後再生成新的視頻文件,發布到各大平台。生成的原始視頻文件都很大,我們需要轉換格式或者壓縮大小,便於上傳或者在其他如手機等設備上分享。
FFmpeg 介紹
FFmpeg是一款開源免費的多媒體視頻處理工具,功能包括視頻採集功能、視頻格式轉換、視頻抓圖、給視頻加水印等。它提供了錄製、轉換以及流化音視頻的完整解決方案。
FFmpeg項目在開源界的影響力也是數一數二的。幾乎你所見到的視頻轉換軟體或播放器中用到的功能或編碼/解碼都基於FFmpeg。它採用LGPL或GPL許可證,曾今國內某些知名播放器使用FFmpeg源碼未聲明,被FFmpeg釘在歷史的恥辱柱上。
FFmpeg 安裝
FFmpeg提供源碼,可自行編譯。幾乎所有發行版Linux倉庫中已有FFmpeg,可以直接安裝。
# debian/ubuntu
apt install ffmpeg
# redhat/centos/fedora'
yum install ffmpeg
或
dnf install ffmpegFFmpeg官方也提供二進位包:ffmpeg.org/download.html
推薦使用FFmpeg官方static二進位包,無需額外動態庫,僅一個可執行文件官網下載後的FFmpeg解壓後有三個可執行文件:ffmpeg、ffprobe、ffplay。
FFmpeg 使用
官網下載後的FFmpeg解壓後有三個可執行文件:
- ffmpeg:音視頻文件處理轉換
- ffprobe:讀取視頻文件信息
- ffplay:一個簡易的播放器
ffmpeg命令:
ffmpeg -i video.wma ./video.mp4
把 video.wma 視頻文件轉換成 mp4 格式。ffmpeg mp4 格式默認使用h264編碼
ffmpeg -i video.wma -c:v libx265 video.mp4
把 video.wma 視頻文件轉換成 h265 編碼的 mp4 格式。
h265比h264編碼有更高的壓縮率,在低碼率下生成的文件更小。
也就是說,相同質量下的h265編碼比h264更清晰。相同大小的視頻文件,h265編碼比h264編碼的視頻文件體積更小。但是當視頻碼率到達一定大小時,兩者清晰度區別不大。
h264比h265有更好的兼容性,有些手機默認不支持h265編碼的視頻文件,需要藉助軟體解碼。
視頻轉換,h265編碼比h264編碼用時會更長,更消耗CPU資源。
ffmpeg -i video.mp4 -s 1280×720 video2.mp4
將視頻壓縮到1280×720解析度。
ffmpeg -i video.mp4 -ss 00:00:10 -i video.mp4 -t 00:00:30 -c:v copy -c:a copy cut.mp4
不改變視頻和音頻的編碼截剪視頻,保留從視頻10秒之後開始30秒,因為音頻視頻編碼指定參數值copy,不會影響視頻質量。
使用ss參數一定要在-i之前,如果寫在-i之後,ffmpeg會理解為起始點是作用於輸出文件。
ffmpeg -i video.mp4 -metadata:s:v rotate=”90″ -c:v copy -c:a copy out.mp4
不改變視頻和音頻的質量將視頻翻轉90度。把橫屏變豎屏。
ffmpeg -f x11grab -r 30 -i :0.0 -f alsa -i hw:0,0 -acodec aac -vcodec libx264 out.mkv
使用FFmpeg錄像,該命令在Linux上有效。每秒30幀,音頻格式使用 aac,視頻格式使用h264,輸出mkv格式。
vcodec 與 c:v 參數一樣,指定視頻編碼,如:libx264,libx265
acodec 與 c:a 參數一樣,指定音頻編碼,如:aac,mp4,flac
FFmpeg還有很多其他用法,比如調整碼率,幀數等。使用 ffmpeg –help 可以看到全部參數說明。
GPU加速
FFmpeg默認使用CPU編碼。執行ffmpeg命令時,資源管理器可以看到CPU使用率升高。

如果使用GPU運算,轉換速度能成倍提高,特別是轉換h265編碼視頻。
查看ffmpeg支持視頻編碼格式:
ffmpeg -codecs找到 hevc ,也就是h265編碼:

- hevc_qsv:intel核顯
- hevc_nvenc:nvidia顯卡
- hevc_amf:amd顯卡
如果使用h264編碼,使用 h264_qsv / h264_nvenc 。
ffmpeg -i ./video.mp4 -c:v hevc_qsv ./out.mp4
使用GPU編碼,運行以上ffmpeg命令,可以看到GPU佔用率升高。

使用GPU加速視頻轉換速度快了很多,我僅使用核顯速度也比CPU轉碼也能快數倍。
ffprobe命令
ffprobe ./video.mp4
查看視頻文件信息。

從輸出信息可以看到該視頻文件是使用h264編碼,解析度1280×720,視頻平均碼率921kbps,24幀。視頻的音頻使用aac編碼,採樣率44100Hz,碼率128kpbs。
ffprobe -v error -show_streams -print_format json ./video.mp4
使用json格式輸出視頻信息。

ffplay命令
ffplay ./video.mp4
播放視頻文件。這時會彈出一個播放器。

ffplay命令還有很多控制參數。不過我覺得用處不大,畢竟圖形化播放器更好用,功能也更強大。
開發集成
使用FFmpeg命令,我們可以用程序或腳本完成視頻自動轉換。也可以讓我們開發的系統擁有視頻轉碼,或讀取視頻信息的功能。以Java示例:
public static int doWaitFor(Process process) {
  InputStream in = null;
  InputStream err = null;
  int exitValue = -1; // returned to caller when p is finished
  try {
    in = process.getInputStream();
    err = process.getErrorStream();
    boolean finished = false; // Set to true when p is finished
    while (!finished) {
      try {
        while (in.available() > 0) {
          // Print the output of our system call
          Character c = new Character((char) in.read());
          System.out.print(c);
        }
        while (err.available() > 0) {
          // Print the output of our system call
          Character c = new Character((char) err.read());
          System.out.print(c);
        }
        // Ask the process for its exitValue. If the process
        // is not finished, an IllegalThreadStateException
        // is thrown. If it is finished, we fall through and
        // the variable finished is set to true.
        exitValue = process.exitValue();
        finished = true;
      } catch (IllegalThreadStateException e) {
        // Process is not finished yet;
        // Sleep a little to save on CPU cycles
        Thread.currentThread().sleep(500);
      }
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    try {
      if (in != null) {
        in.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    if (err != null) {
      try {
        err.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  return exitValue;
}Java調用外部命令使用 Runtime.getRuntime().exec(command) 。
在使用調用ffmpeg命令時,必須要讀取執行命令輸出流中的內容,程序才不會阻塞。否則緩衝讀滿後,進程會卡住。
視頻轉換會非常耗時,取決於硬體性能。在實際應用中,我們也可以開啟線程去處理。
FFmpeg還提供C調用,公共庫集成。以上方法並不是最優解決方案,僅提供一種參考。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/213645.html
 
 微信掃一掃
微信掃一掃  支付寶掃一掃
支付寶掃一掃 