切り抜きとサイズ変更により、ビデオを固定画面サイズに変換します


22

私は自分でこれを理解しようとしましたが、無数のオプションが私を困惑させます。

私は理想的には、ffmpegまたはmencoder(または何か他のものですが、私が働いていると知っている2つ)を使用して、着信ビデオを固定画面サイズに変換します。

ビデオが幅が広いか短すぎる場合は、ビデオを中央で切り抜きます。サイズが適切でない場合は、画面サイズを正確に固定するためにサイズを変更します。

最後に必要なのは、MP3オーディオトラックを備えたXVid AVIの720x480です。

最大解像度にサイズ変更する方法を示すページをたくさん見つけましたが、ビデオを正確にその解像度にする必要があります(余分な部分は切り取られ、黒いバーはありません)。

実行するコマンドラインを誰にでも教えてもらえますか?複数のコマンドラインが必要な場合(Xを実行して解像度を取得し、この計算を実行してから、その計算の出力でYを実行します)、スクリプトを作成できます。


ビデオデバイスは、Mpeg4およびXVid AVIで動作するようです。
アンディジェフリーズ

回答:


19

私はffmpegの第一人者ではありませんが、これでうまくいくはずです。

まず、次のような入力ビデオのサイズを取得できます。

ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width in.mp4

かなり最近のffmpegを使用すると、次のオプションでビデオのサイズを変更できます。

ffmpeg -i in.mp4 -vf scale=720:480 out.mp4

ビデオのサイズを変更してアスペクト比を維持-1するために、幅または高さを設定できffmpegます。実際、-2計算された値は偶数になるはずなので、より良い選択です。次のように入力できます:

ffmpeg -i in.mp4 -vf scale=720:-2 out.mp4

ビデオを取得すると、高720x480さをffmpeg計算できるため、予想よりも大きくなる可能性があるため、トリミングする必要があります。これは次のように実行できます。

ffmpeg -i in.mp4 -filter:v "crop=in_w:480" out.mp4

最後に、次のようなスクリプトを作成できます(簡単に最適化できますが、読みやすくするために単純にしました)。

#!/bin/bash

FILE="/tmp/test.mp4"
TMP="/tmp/tmp.mp4"
OUT="/tmp/out.mp4"

OUT_WIDTH=720
OUT_HEIGHT=480

# Get the size of input video:
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${FILE})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}

# Get the difference between actual and desired size
W_DIFF=$[ ${OUT_WIDTH} - ${IN_WIDTH} ]
H_DIFF=$[ ${OUT_HEIGHT} - ${IN_HEIGHT} ]

# Let's take the shorter side, so the video will be at least as big
# as the desired size:
CROP_SIDE="n"
if [ ${W_DIFF} -lt ${H_DIFF} ] ; then
  SCALE="-2:${OUT_HEIGHT}"
  CROP_SIDE="w"
else
  SCALE="${OUT_WIDTH}:-2"
  CROP_SIDE="h"
fi

# Then perform a first resizing
ffmpeg -i ${FILE} -vf scale=${SCALE} ${TMP}

# Now get the temporary video size
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${TMP})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}

# Calculate how much we should crop
if [ "z${CROP_SIDE}" = "zh" ] ; then
  DIFF=$[ ${IN_HEIGHT} - ${OUT_HEIGHT} ]
  CROP="in_w:in_h-${DIFF}"
elif [ "z${CROP_SIDE}" = "zw" ] ; then
  DIFF=$[ ${IN_WIDTH} - ${OUT_WIDTH} ]
  CROP="in_w-${DIFF}:in_h"
fi

# Then crop...
ffmpeg -i ${TMP} -filter:v "crop=${CROP}" ${OUT}

シナリオを見逃してしまうというおかしな感じがしましたが、大量のビデオファイルを試してみましたが、ビデオを正しく切り取り、サイズを絶対的な正しいサイズに変更しているようです-よくできました!
アンディジェフリーズ

CROP_SIDEの決定に何らかの誤りがあるようです。

`#実際のサイズと希望のサイズの間のレートを取得w_rate = echo "scale=3; ${in_width}/${out_width}*1000"| bc | awk '{printf "%d", $0}' h_rate = echo "scale=3; ${in_height}/${out_height}*1000"| bc | awk '{printf "%d", $0}' #短い側を見てみましょう。ビデオは少なくとも希望のサイズと同じ大きさになり、#長い側を切り取ります:crop_side = 'n' if [$ {w_rate} -gt $ {h_rate}]; 次にscale = "-2:$ {out_height}" crop_side = 'w' else scale = "$ {out_width}:-2" crop_side = 'h' fi `
経典

23
ffmpeg -i input.file -vf "scale=(iw*sar)*max(720/(iw*sar)\,480/ih):ih*max(720/(iw*sar)\,480/ih), crop=720:480" -c:v mpeg4 -vtag XVID -q:v 4 -c:a libmp3lame -q:a 4 output.avi

「input.file」を入力ファイルの名前に置き換えます。


ffprobeの呼び出しを必要としないため、これが一番の答えになるはずです。コマンド内のバックスラッシュコンマシーケンスに注意してください。C / JavaScript / PHP文字列にコマンドを配置する場合は、バックスラッシュをエスケープする必要があります。
クレオン

いいね、ブライアン。ビデオフィルターの部分もまさに私が必要としていたものです。(つまり、古い4:3ビデオを16:9に変換します)!
デイブ

1
天才!すべてを1つにまとめました。
ソリ

2
上記のスクリプトよりもずっときれいです。XVID / MP3が必要ない場合は、2番目の引用符の後のタグを次のように変更するだけでよいことに注意してください-c:a copy scaled_result.mp4
Nick

7

一度に切り抜きと拡大縮小を行いたい場合は、次のように切り抜きと拡大縮小のフィルターチェーンを作成できます。

ffmpeg -i SomeInput.mp4 -vf "crop=in_h*9/16:in_h,scale=-2:400" -t 4 SomeOutput.mp4

上記は、最初にビデオを16:9の縦長にトリミングし、次に高さ400px x適切な(偶数)幅にスケーリングします。


1

私はffmpegを初めて使用しますが、VB.NETには素敵な小さなコンバーターがあり、SDカードにアクセスできるが、複雑なビデオをデコードするのに十分な電力がない小さなデバイスで使用するさまざまな出力形式の生ムービーを作成します。

サイズ変更とトリミングの際の動作方法のため、手動でコーディングしてパラメーターを作成する必要がありました。基本的に、結果の幅と高さを知る必要があります。

私はオプションのための2つのチェックボックスを持っています:-

アスペクト比を保持(X)すべてのピクセルを塗りつぶす(X)

入力として必要な変数は4つだけです(1)元のビデオの幅、(2)元のビデオの高さ、(3)デバイスの幅、(4)デバイスの高さ。

VB.NETの場合、どの言語にも非常に簡単に適応できます。

    Dim crop As String = "" ' will build this in ffmpeg format for -s or scale and crop

    If cbAspectRatio.Checked = False Then
        m_dest_output_w = sz._w
        m_dest_output_h = sz._h

        ' scale to w * h - simple
        crop = " -s " & m_dest_output_w & ":" & m_dest_output_h
    Else
        Dim ratio As Double = CDbl(m_video_width) / CDbl(m_video_height) ' this is aspect ratio of original unsized video

        If cbFillPixels.Checked = False Then ' shrink to fit
            If sz._w * ratio <= m_video_height Then
                m_dest_output_w = sz._w
                m_dest_output_h = sz._w / ratio
            Else
                m_dest_output_h = sz._h
                m_dest_output_w = sz._h / ratio
            End If

            ' no cropping just resizing to a non-filled area that fits

            crop = " -s " & m_dest_output_w & ":" & m_dest_output_h ' no cropping needed as letterboxed

        Else ' expand / fill --- cropping needed
            If sz._w * ratio >= m_video_height Then
                m_dest_output_w = sz._w
                m_dest_output_h = sz._w * ratio

                crop = ",crop=" & sz._w & ":" & sz._h & ":0:" & Math.Abs((m_dest_output_h - sz._h)) \ 2
            Else
                m_dest_output_h = sz._h
                m_dest_output_w = sz._h * ratio

                crop = ",crop=" & sz._w & ":" & sz._h & ":" & Math.Abs((m_dest_output_w - sz._w)) \ 2 & ":0"
            End If

            crop = " -vf scale=" & m_dest_output_w & ":" & m_dest_output_h & crop

            m_dest_output_w = sz._w
            m_dest_output_h = sz._h
        End If
    End If
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.