web-dev-qa-db-ja.com

ffmpeg / avconvでビデオのサイズを変更して静的サイズのプレーヤーに合うようにする

私は幅700ピクセル、高さ400ピクセルのHTML 5ビデオプレーヤーを持っています。私はavconvを使ってffmpegを使って(縦横比を保ちながら)リサイズし、それが私のプレーヤーに合うようにしています。

入力は任意のサイズのファイルにすることができるので、大きいものはサイズ変更し、小さいものは黒いバーで中央揃えする必要があります。今まで試したことがあります:-s-aspectpad-vfスイッチと一緒に使用されているのを見ましたが、必要なものを得るのにそれがどのように機能するのか理解していません。

Images

これは私が何を必要としているかの大まかな考えです。それがさらに可能かどうかはわかりません。それはCSSのmax-width/max-heightとほとんど同じです。私はこれが単なる言葉のごちゃ混ぜになるかもしれないことを理解していますが、誰かが私が話していることを理解しているならば、私は助けを感謝します、ありがとう。

avconvコマンド:

avconv -y -i control.avi -vcodec libx264 -b 2000k -bufsize 20M -acodec aac -strict experimental -ar 44100 -ab 256k bigbuck_out.mp4

59
Jamie Taylor

簡単な方法は、 スケールフィルタforce_original_aspect_ratioオプションを使うことです。

original image
元の画像640 x 480、4:3の縦横比のビデオを表します。

これらの例では、オリジナルの画像は、オリジナルのアスペクト比を維持しながら16:9のアスペクト比の出力に収まるように拡大縮小されます。これを行うには、次のいずれかを行います。

ピラーボックスまたはレターボックス

pillarboxed image
ピラーボックス画像640 x 480(4:3)入力を1280 x 720(16:9)出力に合わせる。

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • これにより画像が拡大されます。拡大を避けたい場合は、以下の例を参照してください。

  • 入力アスペクト比が出力アスペクト比よりも広い場合は、代わりにレターボックス化が行われます。たとえば、アスペクト比が2.35:1の入力を16:9の出力に合わせると、レターボックス化されます。

上記と同じですがアップスケーリングなし

no upscaling
アップスケーリングなしで640 x 480(4:3)入力を1280 x 720(16:9)出力に入力。

ffmpeg -i input -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output

切り抜き

enter image description here
画像をトリミングしました。 4:3の入力アスペクト比、16:9の出力アスペクト比。

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output
46
llogan

固定幅の出力にピラーボックスまたはレターボックスを追加するコマンドです。少し長いですが、パディングを何らかの方法で指定する必要があります。

まず、シェルで出力幅と高さを定義します。

width=700
height=400

次にコマンドを実行します。

ffmpeg -i in.mp4 -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" out.mp4

これは、サイズ変更やパディングに必要な最低限の要素には欠けています。必要に応じて他のビデオやオーディオのオプションを追加してください。ほとんどのコーデックで機能するためには、widthheightの数値は2で割り切れる必要があります。

これが何が起こっているかの説明です。

  • スケーリング:
    • まず、幅と高さのどちらで拡大縮小するかを決める必要があります。
    • これを行うには、出力幅を入力幅で、出力高さを入力高さで割ります。これにより、各次元の倍率がわかります。
    • 次に、どちらが低いかを(min()で)確認し、サイズ変更のためにその要素だけを選択します。
    • 最後に、入力幅と高さの両方にその係数を掛けます(iw*min(…):ih*min(…))。
  • パディング:
    • $width:$heightは出力の幅と高さです
    • 結果のビデオを配置する場所を判断するには、最大出力幅から拡大縮小幅を、最大出力高さから拡大縮小高さを引く必要があります。
    • スケールされた幅と高さはscaleフィルタからの式です。
    • 両側に境界線を追加するために、結果のオフセットを2で割ります。
60
slhck

私には、これを3つのステップで実行する必要があるようです。

  1. 入力縦横比を確認する
  2. DAR> 7/4の幅方向でビデオを拡大縮小し(幅を700に変更し、縦横比を維持するために高さを拡大縮小し)、DAR <7/4の高さ方向で拡大縮小
  3. 700:400のスペースに収まるようにビデオを埋めます。

FFmpeg/avconvは、ビデオフィルタによるスケーリング/パディングを1回のステップで実行できます。トランスコーディングは1回だけです。たとえば、16:9のビデオを撮影するには、幅方向に拡大縮小してから結果をレターボックスに配置します。

ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4

...しかし、最初のステップ(アスペクト比を検出し、それを必要な7:4と比較する)では、何らかの種類のスクリプトを使用する必要があります。

ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*/\1/p'

...ビデオの縦横比が「16:9」または「4:3」のようになります。 bashスクリプトでは、次のように使用します。

#!/bin/bash

##  Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*/\1/p' | sed 's|:|/|')
##  use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')

##  ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
    ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
    ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi

exit 0

明らかにあなたのニーズに合わせて調整する必要があります。

8
evilsoup