ビデオを特定のサイズに合わせる方法はありますが、FFmpegでアップスケールしないのですか?


13

アスペクト比を維持しながら、ビデオを640x360(スマートフォンのプレーヤーが処理できる最大値)に合わせる必要がありますが、ビデオが640x360 より小さい場合でも、ビデオを変更しないでください(結局のところ、拡大しても意味がありません)。

ffmpegのコマンドラインを使用してこの動作を取得する方法はありますか?


これをffmpegだけで行うことはできないと思いますが、スクリプトを作成するつもりであれば、確実に行うことができます。
evilsoup 2013年

すでにスクリプトを作成しましたが、不要になった場合に備えてコードをクリーンアップしたいと思いました。
sashoalm 2013年

次のような関数を使用するスケールフィルターでおそらく可能ですがmin(…)、ディメンションを解析する単純なスクリプトを使用すると、間違いなく簡単になります。何ができるかの例については、ここに私のコマンドを参照してください:superuser.com/questions/547296/...
slhck

回答:


9

新しいffmpegバージョンでは、scaleフィルターのforce_original_aspect_ratioオプションを使用できます。たとえば、アップスケーリングせずにビデオを1280×720に収めるには(詳細はこの投稿を参照):

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

ここではscale、入力ビデオがそれよりも大きい場合、フィルターは1280×720にスケーリングされます。小さい場合は拡大されません。padフィルタは、ターゲット・サイズのケースで1280×720に、そのアスペクト比またはサイズが異なるが、出力ビデオを持参する必要があります。


古いffmpegバージョンでは、多少ハックな回避策があります。まず、出力の幅、高さ、アスペクト比を定義します。これにより、タイピングの手間が省けます。

width=640; height=360
aspect=$( bc <<< "scale=3; $width / $height") # <= floating point division

ここで、ジムウォラルが書いた超複雑なフィルターコマンドを適用してみましょう。

ffmpeg -i input.mp4 -vf "scale = min(1\,gt(iw\,$width)+gt(ih\,$height)) * (gte(a\,$aspect)*$width + \
lt(a\,$aspect)*(($height*iw)/ih)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*iw : \
min(1\,gt(iw\,$width)+gt(ih\,$height)) * (lte(a\,$aspect)*$height + \
gt(a\,$aspect)*(($width*ih)/iw)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*ih" \
output.mp4

私はこれが何をしているのかを説明するつもりはありませんが、基本的にはどんな動画でもフィードできます。準備ができている場合は、フィルターを個々の表現に分解できます。これを短くすることは可能かもしれませんが、それも同様に機能します。


1
+1しかし、それは本当に恐ろしいコマンドです:P
evilsoup '19年

私は当然知っている?私はそれを論理的な部分に分割するために10分間費やし、いくつかの値を挿入しましたが、あきらめました。少し古くて、これよりもずっと簡潔に書けるかもしれません。
slhck 2013年

13

より読みやすいバージョンは次のようになります。

-filter_complex "scale=iw*min(1\,min(640/iw\,360/ih)):-1"

640 / iwは水平方向のスケーリング係数で、360 / ihは垂直方向のスケーリング係数です

スケーリングされた画像を出力ボックス内に収め、(ストレージ)アスペクト比を維持したいとします。これを行うには、最小関数を使用して最小の倍率を選択します:min(640 / iw、360 / ih)

アップスケーリング(つまり、スケーリング係数> 1.0)を防ぎたいので、別の最小関数を追加します:min(1、min(640 / iw、360 / ih))

次のステップは、スケーリング係数に入力幅と入力高さを乗算して出力解像度を計算することです。
出力幅= iw * min(1、min(640 / iw、360 / ih))
output-height = ih * min(1、min(640 / iw、360 / ih))

最後のステップは、filterコマンドを作成することです。出力の高さを指定する必要はありません。-1を指定すると、ffmpegは幅と同じ倍率を適用してアスペクト比を維持します。


A +はそのまま使用できます。選択された回答のソリューションはアスペクト比を維持しませんでした。それはフレームを圧迫しました。
287352

5

私も同じ問題を抱えていましたが、640x640の正方形にビデオを収めることで解決しました(スマートフォンで作成された縦型ビデオのため)。

だからimmerziロジックといくつかの研究を使って、私はこれで終わります:

-vf "scale=iw*min(1\,if(gt(iw\,ih)\,640/iw\,(640*sar)/ih)):(floor((ow/dar)/2))*2"

最後の部分は、多くのエンコーダーで必要な高さを2で割り切れるようにするためのものです。

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