FFMPEG保持檔案大小的最佳參數

FFMPEG保持檔案大小的最佳參數

所以我的想法是:我想將 1 TB 硬碟中的 every.single.video 轉換為我的 Chromecast 可以播放的格式(https://developers.google.com/cast/docs/media),我很樂意讓我的不太新的電腦工作幾天(幾週?)來完成這項工作。太棒了,FFMPEG 來拯救了。

一點背景知識:我是 Android/Java 開發人員(在 StackOverflow 中非常活躍),我知道在某些時候我只需要編寫一些批次腳本或快速 java 命令列(因為我對 Java 更熟悉) )來完成這項工作,但我仍然不確定在FFMPEG 命令列中使用哪些參數。

所以我的需求是: - 視訊編解碼器:H.264 High Profile Level 5 - 音訊編解碼器:HE-AAC、LC-AAC、MP3 中的任何一個(老實說,我不知道其中的區別,也許一些AAC 會更好?

以上所有內容是我在教程和手冊上看到的如何實現的,現在我真的不確定如何實現的部分:

我希望最終文件大小與原始文件大小大致相同。這是因為驅動器大約已滿 80%,我不想透過簡單地轉換內容來填滿它。在腳本中,我將重新編碼文件並刪除原始文件,以便一切順利進行。

那麼如何從檔案大小獲取視訊位元率和音訊位元率並將其放入腳本中?

PS:如果有人知道如何完成同樣的工作,我同樣樂意使用手煞車。

先謝謝您的幫忙。

答案1

您需要的 ffmpeg 指令類似於:

ffmpeg -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -an -pass 1 output.bar;
ffmpeg -y -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -b:a $audiobitrate -pass 2 output.bar

libx264 是 h264 編碼器,所有選項都從 ffmpeg 傳遞給它,它們非常不言自明。第一遍不需要音頻,因此 -an。如果需要,您可以將輸出通過管道傳輸到 /dev/null,但無論如何。我只是在第二遍中使用 -y 開關,因此它會在不詢問的情況下覆蓋臨時檔案。預設情況下,音訊編解碼器是 aac,因此您不必指定它。

ff探針可以幫助您取得 $videobitrate 和 $audiobitrate 的值(我假設是 posix 環境,否則它將是 %videobitrate% 和 %audiobitrate%)。您將必須執行一些 sed、awk 或 perl voodoo 才能將值轉換為您可以使用的形式。這是 ffprobe 在我的機器上的隨機 mp4 上的輸出:

ffprobe version 2.1.3 Copyright (c) 2007-2013 the FFmpeg developers
  built on Feb 12 2014 22:10:38 with Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/2.1.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libvpx --enable-librtmp --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-aacenc --enable-libass --enable-ffplay --enable-libspeex --enable-libschroedinger --enable-libfdk-aac --enable-openssl --enable-libopus --enable-frei0r --enable-libcaca --enable-libopenjpeg --extra-cflags='-I/usr/local/Cellar/openjpeg/1.5.1/include/openjpeg-1.5 '
  libavutil      52. 48.101 / 52. 48.101
  libavcodec     55. 39.101 / 55. 39.101
  libavformat    55. 19.104 / 55. 19.104
  libavdevice    55.  5.100 / 55.  5.100
  libavfilter     3. 90.100 /  3. 90.100
  libavresample   1.  1.  0 /  1.  1.  0
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'loop.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.19.104
  Duration: 00:00:19.56, start: 0.000000, bitrate: 201 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 400x226 [SAR 226:225 DAR 16:9], 129 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 75 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

煩人的是 ffprobe 將所有內容轉儲到 stderr,因此您需要將其重定向到 stdout。我不會告訴你如何吸雞蛋,你的 sed-fu 可能比我的好,但是對於那些遲到的人,要取得上面範例中整個 shebang 的位元率,您可以執行以下操作:

videobitrate=$(ffprobe input.foo 2>&1|grep bitrate |sed "s/.*bitrate: \([0-9]*\) \([km]*\).*/\1\2/")

對於音訊:

audiobitrate=$(ffprobe input.foo 2>&1|grep Audio|sed "s/.* \([0-9]*\) \([km]*\)b\/s.*/\1\2/")

不確定為什麼指定了音訊的位元率而不是視訊的位元率,可能是因為我通常使用恆定速率因子(恆定品質而不是恆定位元率)進行壓縮。您必須檢查電影上的 ffprobe 輸出。從那裡開始,您就可以將其轉換為您需要的變數。請注意,ffmpeg 將解析 100k 或 3m 等數字。

相關內容