メールなどで送信できるように動画サイズを小さくしたいです。私はこの質問を見ました。ffmpegを使用してビデオサイズを縮小する方法は?そこで私はそれを減らす方法について良いアドバイスを得ました。問題は、ビットレートを手動で計算する必要があることです。そしてこの作業をしながら手動で試行錯誤を経なければなりません。
ffmpeg
ビデオサイズを縮小するために使用したり、他のツールを使用したりするための良い方法はありますか?ターゲットサイズ?
Frostschutzのコメントを参照してください。
サイズが心配すぎてビデオの長さ/解像度/フレームレート/コンテンツに関係なく、固定ファイルサイズを選択すると、ほとんど満足のいく結果が得られません。メールリンクを介してどこかにアップロードします。エンコードする必要がある場合は、品質レベルを設定してビットレートを動的に保ちます。サイズ要件を満たしていないことがわからない場合は、エンコードをキャンセルして品質レベルを調整してください。すすぎ、繰り返します。
全体的に良いアドバイスですが、私のユースケースには合いません。外部リンクへのアップロードは技術的な制限のためのオプションではありません。
また、私が探しているものではないことを明らかにすることもできます。正確に私が指定したサイズ。私が望む値に非常に近い場合(5%または10%低くなる可能性があります)、十分ですがそうではないことを保証する必要があります。超過私の目標制限。
答え1
@philip-coulingの答えは似ていますが、いくつかの部分がありません。
- ビットレートを取得するには、必要なサイズ(MB)に8を掛ける必要があります。
- ビットレートの場合、1 Mb / s = 1000 kb / s = 1000000 b / s;乗数は1024ではありません(1024B / sのKiB / sという別のプレフィックスがありますが、ffmpegではそれを使用しないようです)。
- 整数以外の数字を切り捨てたり丸めたりすると
length
(正確な値を使用したり丸めたりする代わりに)、ファイルサイズがターゲットサイズをわずかに超えてしまいます。 - この
-b
フラグは平均ビットレートを指定します。実際、エンコーダはビットレートをわずかに上げ、結果は目標サイズを超える可能性があります。ただし、以下を使用して-maxrate
最大ビットレートを指定できます。-bufsize
私のユースケースでは、ハードコーディングされたオーディオビットレートを持ち、それに応じてビデオを調整したいと思います。 (これもより安全なようです。ffmpeg-b
のフラグがビデオストリームとオーディオストリームのビットレートを一緒に指定するかどうかは100%不明です。)
これらすべてを考慮して25MBに厳密に制限されています。
file="input.mp4"
target_size_mb=25 # 25MB target size
target_size=$(( $target_size_mb * 1000 * 1000 * 8 )) # target size in bits
length=`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file"`
length_round_up=$(( ${length%.*} + 1 ))
total_bitrate=$(( $target_size / $length_round_up ))
audio_bitrate=$(( 128 * 1000 )) # 128k bit rate
video_bitrate=$(( $total_bitrate - $audio_bitrate ))
ffmpeg -i "$file" -b:v $video_bitrate -maxrate:v $video_bitrate -bufsize:v $(( $target_size / 20 )) -b:a $audio_bitrate "${file}-${target_size_mb}mb.mp4"
-maxrate
最大ビットレートを制限すると、-bufsize
平均ビットレートが必ず減少するため、私のテストでは、ビデオはターゲットサイズより5〜10%低くなります(さまざまなターゲットサイズの20秒ビデオで)。の値が-bufsize
重要です。上記で使用した計算値(ターゲットサイズに基づいて)が私が推測した最高の値です。小さすぎると品質が大幅に低下し、目標サイズより約50%ほど小さくなりますが、大きすぎると目標サイズを超える可能性があると思いますか?
-maxrate
厳密な最大ファイルサイズがない場合と削除すると、エンコーダに柔軟性を高めるために品質が向上しますが、テストの結果、ビデオがターゲットサイズを-bufsize
5%を超える可能性があります。詳しくはマニュアルをご覧ください。、ここに次の警告が表示されます。
注:ビデオをエンコードするのが難しい場合は、ビットレートを制限すると出力品質が低下する可能性があります。ほとんどの場合(たとえば、アーカイブファイルの保存)、エンコーダに適切なビットレートを選択させるのは、一定の品質またはCRFベースのエンコーディングです。
次のコードを使用して、再利用可能なbash関数を宣言できます。
ffmpeg_resize () {
file=$1
target_size_mb=$2 # target size in MB
target_size=$(( $target_size_mb * 1000 * 1000 * 8 )) # target size in bits
length=`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file"`
length_round_up=$(( ${length%.*} + 1 ))
total_bitrate=$(( $target_size / $length_round_up ))
audio_bitrate=$(( 128 * 1000 )) # 128k bit rate
video_bitrate=$(( $total_bitrate - $audio_bitrate ))
ffmpeg -i "$file" -b:v $video_bitrate -maxrate:v $video_bitrate -bufsize:v $(( $target_size / 20 )) -b:a $audio_bitrate "${file}-${target_size_mb}mb.mp4"
}
ffmpeg_resize file1.mp4 25 # resize `file1.mp4` to 25 MB
ffmpeg_resize file2.mp4 64 # resize `file2.mp4` to 64 MB
答え2
コメントするほど評判が悪いです。 Windows / Dosバッチファイルとして機能するように上記の@tobekコードを調整しました。
@echo off
setlocal
if "%~1" == "" (
echo Usage:
echo.
echo %0 filename.mp4
echo or
echo %0 filename.mp4 25
echo (25 = 25MB^)
goto end
)
set target_mb=%2
if "%~2" == "" (
rem # default
set target_mb=25
)
set file=%1
set /a target_size=%target_mb% * 1000 * 1000 * 8
for /f %%c in ('ffprobe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%file%"') do set length=%%c
for /f "tokens=1 delims=." %%n in ('echo %length%') do set length_round_up=%%n
set /a length_round_up=%length_round_up% + 1
rem # 128k bit rate
set /a audio_bitrate=128 * 1000
set /a total_bitrate=%target_size% / %length_round_up%
set /a video_bitrate=%total_bitrate% - %audio_bitrate%
set /a bufsize=%target_size% / 20
for %%f in ("%file%") do (
set filedrive=%%~df
set filepath=%%~pf
set filename=%%~nf
set fileextension=%%~xf
)
set file_output=%filedrive%%filepath%%filename%-out%fileextension%
ffmpeg -i "%file%" -b:v %video_bitrate% -maxrate:v %video_bitrate% -bufsize:v %bufsize% -b:a %audio_bitrate% "%file_output%"
:end
答え3
免責事項:完璧ではないようです。やや大きくなります。
他の2つの答えを組み合わせることは比較的簡単です。
ffprobe
期間を探し、シェルで計算を実行するために使用できる10 MBファイル(10485760バイト)が必要であるとします。
ffprobeは小数点以下の桁数を報告するため、シェル算術エラーが発生する可能性があるため注意してください。私は小数点以下の桁数を削除しようとしました${length%.*}
:
size=10485760
length=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4)
ffmpeg -i input.mp4 -b $(( $size / ${length%.*} )) output.mp4
答え4
メガバイト(MiB)は8,388.608 k =(1024^2)/(1000/8)と同じです。ソース:ffmpeg ドキュメント。
2時間分のビデオ、オーディオ256kbit、目標2000MiB(テレグラムアップロード制限)
8,388.608 * 2000 / 7200 - 256
= 2074kのビットレートの計算例
したがって、コマンドを組み合わせると、video_bitrateフラグは次のようになります。-b:v 2074K