ffmpeg
を使用して品質を下げることでビデオのサイズを小さくするにはどうすればよいですか(可能な限り最小限に抑えて、モバイルデバイスで実行する必要があるため十分な空き容量があります)?
動画で字幕(* .srtまたは* .sub)を使用できる場合は、変換した動画ファイルのパラメーターに合わせて字幕も変換したいことを忘れていました。
this の回答を参照してください。便宜上、以下を引用します。
1 GBを秒単位のビデオの長さで割って、必要なビットレートを計算します。したがって、長さが16:40(1000秒)のビデオの場合、1000000バイト/秒のビットレートを使用します。
ffmpeg -i input.mp4 -b 1000000 output.mp4
検討する価値のある追加のオプションは、一定のビットレートを設定することです。これは、平均ビットレートを下げますが、より良い品質を保持します。 CRFを18から24の間で変化させます—低いほど、ビットレートは高くなります。
ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4
必要に応じてコーデックを変更します-libx265が使用できない場合は、結果のファイルサイズがわずかに大きくなりますが、libx264が使用できる場合があります。
私のユースケースでもある、モバイルデバイスにより多くのビデオを収めるためにファイルサイズを小さくしたいとおっしゃいました。ここでの答えはすべて圧縮品質を下げることですが、ビデオフレームサイズを減らすことについては誰も言及していません。私の経験では、再圧縮よりも約3〜5倍速くなっています。詳細は scaling のffmpegドキュメントを参照してください。
ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv
特定のビットレートを探しているのでない限り、-crf
オプションをお勧めします。これはx264
エンコーディングで最も一般的に使用されます: http://slhck.info/articles/crf
つまり、CRFが23の場合は「DVD」品質の映画(700MB〜1GB)になり、CRF値が低いほど品質が高くなります(ファイルが大きくなります)。
この質問に対する他の提案された回答のほとんどをテストしました。テストデータの結論は以下のとおりです。これらは私がテストした提案された答えです:
(BR)以下を使用してビットレートを変更します。
ffmpeg -i $infile -b $bitrate $newoutfile
(CR)以下を使用して、定数レート係数を変化させます。
ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile
(SZ)次を使用して、ビデオの画面サイズを変更します(たとえば、ピクセルサイズの半分に)。
ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile
(BL)次のコマンドを使用して、H.264プロファイルを「ベースライン」に変更します。
ffmpeg -i $infile -profile:v baseline $outfile
(DF)以下を使用して、デフォルトのffmpeg処理を使用します。
ffmpeg -i $infile $outfile
[〜#〜] data [〜#〜]
(BL)の目標ビットレートを、提案された方法を使用して計算しました。
===ファイルA-方法NodeがAngular-Fnbixa7Ts6M.mkvを推進するのに役立つ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 64152 kb 214% 76% 40% 83% 76%
bitrate 411 kb/s 883 313 165 342 313
definition 1920x1080 1920x1080 1920x1080 960x540 1920x1080 1920x1080
convert -- 648 509 225 427 510
===ファイルB-Angular _でGraphQLを使用する-By-Lee Costello-OGyFxqt5INw.mkv ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 410301 kb 33% 109% 28% 143% 109%
bitrate 2687 kb/s 880 2920 764 3843 2920
definition 3840x2160 3840x2160 3840x2160 1920x1080 3840x2160 3840x2160
convert -- 2307 3188 1116 2646 3278
[〜#〜]結論[〜#〜]
(SZ)メソッドは間違いなく最も速い方法です。 2倍から4倍高速でした。他の方法はすべて、ビデオの実際の長さよりも変換に時間がかかったため、これは高解像度ビデオでは非常に問題になる可能性があります。たとえば、(CR)メソッドでは、21分のビデオを変換するのに53分かかりました。
(SZ)メソッドは、ビデオの定義がそれを表示する画面の定義よりも大きい場合、間違いなく最良の方法です。たとえば、スマートフォンで1080pの画像しか表示できない場合、3840x2160のビデオを送信しても無駄です。サイズを半分にして1080pにするのが最適です。
提案された回答の一部は、一部のビデオのサイズを実際に増加させました。たとえば、(BR)メソッドでは、1080pサンプルのサイズが2倍以上になりました。ただし、2160pサイズは3分の1になりました。高解像度サンプルの場合、(CR)、(BL)、(DF)メソッドはすべてビデオのサイズを大きくしました。
正解(または最良)回答
最初に解像度をターゲットディスプレイでサポートされている最大値まで下げることが常に最善です。
ファイルサイズをさらに小さくしたい場合は、個人の選択によって異なります。情報の内容を減らすか、圧縮率を上げることができます。
解像度が気にならない場合は、解像度をさらに下げることができます。
ビデオに高速アクションシーンが含まれていない場合は、フレームレートを下げることができます。
強力なプロセッサーを使用していて、スペースのみが問題である場合は、圧縮率を上げることができます。
ビットレートは複数の要素の組み合わせです。したがって、ffmpegにビットレートを下げるように指示するだけでは、期待する結果が得られない場合があります。
情報量を減らす別の方法は、色深度を下げることです。これを行う方法はまだ議論されていません。
ffmpeg
alreadyはオプションなしで実行したときに最適化を実行するようです。そのため、理解できない設定を使用する前に、または明示的に情報を失うことを決定する前に、デフォルトの変換:
ffmpeg -i input.mp4 output.mp4
私の場合、ビデオとオーディオの両方のビットレートが低下しました(ffprobe
を実行して入力ファイルと出力ファイルを確認および比較できます)。700Mbのビデオを、見かけ上同じ品質の60 Mbに変換しました。 。
40分のHDビデオプレゼンテーションを505MBから183MBに圧縮しました
これは、100MB→36MBのようになります。
元のビデオはHDであり、出力にはほとんど違いがありませんでした。
これはビデオファイルです「残しておきたいのですが、HDはやりすぎです。」
私が使用したコマンドは次のとおりです。
ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4
-n
:avoid出力ファイルの上書き(テストしてからバッチ処理する方が安全)-loglevel error
:エラーを表示し、進行状況の行と行を非表示にします-i inputfile.mp4
:入力ファイル名-vcodec libx264
: 上記のトップアンサーからスワイプ/-crf 28
:わずかな違いがあるシングルパス圧縮( "0 =ロスレス、23 =デフォルト、51 =最悪、主観的に健全な範囲は17 –28 ") ref docs-preset faster
:外観は、「中」のデフォルトのエンコード時間より2倍高速です ref docs-tune film
:入力がHQビデオであることを指定します(他のオプションには「cartoon」、「stillimage」などがあります。) ref docsoutputfilename.mp4
:出力ファイル名ビデオファイルのディレクトリの場合:
for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done
問題:
.webm
ファイルはコマンドでは機能しません。交換する必要がありました"cc${i}"
→"${i%.*}.mp4"
古いカメラが生成するMotion JPEGビデオ(各フレームはJPEGイメージ全体なので非常に大きなビデオです)をh264に変換するために、私が最初に偽造したレシピがあります。ここでは、他の種類のビデオ(コースなど)に適応しています。
私はffmpegを使用していないですが、mplayerおよびmencoderです。まず、オーディオをmplayerで逆多重化する必要があります。
mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
-vo null
および-ao null
パラメータは、mplayerにビデオを抽出しないように指示します。次のステップでは、mencoderを使用して3パス圧縮を行います。最初のパスでは、適切な一定品質モード圧縮(crf パラメータ)を開始点として:
mencoder <video> -ovc x264 \
-x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
-nosound -o video1.h264
あなたは付け加えられます slow_firstpass パラメータに -x264encopts あなたがビデオの最終的な品質に偏執的である場合。 Mencoderマニュアルによると、このオプションは、「最終パスの品質にほとんどまたはまったく影響を与えずに、エンコード速度を大幅に向上させる」いくつかのパラメーターを無効にします。したがって、最後のステップでのみ使用してください。
あなたはいくつかの値を試す必要があります crf — 25から始めて、結果のビデオにアーティファクトが見つかるまで値を増やしていきます(値が大きいほど圧縮率が高くなります)。後続のエンコードパスにより、選択した品質が向上することに注意してください crf。
の代替 非常に遅い プリセットは もっとゆっくり、 スロー、 中 完全なリストについては、mencoderマニュアルを参照してください。
レート ビットレートの変動を制御します—ここで正しいことを行っているかどうかはわかりませんが、メンコーダーが各シーンに適切なビットレートを選択できるように、最大値に設定します。
最初のパスの後、最後の行には次のステップで使用する平均ビットレートが表示されることに注意してください。
(...)
x264 [info]: kb/s:526.43
変更 crf 最初のパスで推奨されるパラメータ ビットレート、後続のパスで必要:
mencoder <video> -ovc x264 \
-x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
-nosound -o video2.h264
この2番目のパスのエンコードは、圧縮を最適化するために、最初のパスで生成された統計(divx2pass.log
およびdivx2pass.log.mbtree
)を読み取ります。
最初のパスで生成されたものではなく、同じビデオ入力を使用することに注意してください。最初のパスの出力ビデオは、初期品質を確認する場合にのみ役立ちます。
また、pass=3
(notpass=2
)は新しい統計ファイルを生成するので、最後の手順を何度でも繰り返すことができます。私は通常pass=3
を2回行い、常に結果のビットレートに注意を払います。
その間、lame
またはoggenc
を使用してオーディオも圧縮できます。
oggenc -q<n> <audio_pcm.wav>
最後に、オーディオとビデオを再多重化します
mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
-of lavf -lavfopts format=mp4 -o <video>.mp4
-of lavf -lavfopts format=mp4
は、lavoptsマルチプレクサを使用してmp4
ファイル形式を生成します。品質を極端に低下させることなく、指定されたファイルサイズ(ビットレート)内でビデオを「フィット」するには、2パスエンコーディングを使用する必要があります。これは非常に詳細なトピックです: http://web.archive.org/web/20171130050515/http://www.mpabo.com/2014/12/14/ffmpeg-and-x264-encoding-guide /
ビデオのサイズを縮小し、自動的に異なるcrf値を試すためのbashスクリプトを作成しました。
基本的には
これは、達成したいサイズ制限があり、それを実行できるようにするcrf値がわからない場合に非常に便利です。
これが誰かの役に立つことを願っています。私は私の同僚と共有し、誰もがそれが役に立ったと感じました。
#!/bin/bash
# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
これは2パスの例です。かなりハードコーディングされていますが、それは本当に圧迫されます#!/bin/bash ffmpeg -y -i "$1" -c:v libvpx-vp9 -pass 1 -deadline best -crf 30 -b:v 664k -c:a libopus -f webm /dev/null && ffmpeg -i "$1" -c:v libvpx-vp9 -pass 2 -crf 30 -b:v 664k -c:a libopus -strict -2 "$2"