Bir videoyu belirli bir boyuta nasıl sığdırabilirim, ancak FFmpeg ile yükseltmeyin?


13

En boy oranını korurken videoları 640x360'a (telefonumun oynatıcısının işleyebileceği maksimum değer) sığdırmam gerekiyor , ancak 640x360'tan küçükse videonun da değişmesini istiyorum (sonuçta yukarı ölçeklemede bir nokta yok).

Bu davranışı ffmpeg komut satırını kullanarak almanın bir yolu var mı?


Bunun sadece ffmpeg'de yapılabileceğini sanmıyorum, ama senaryoyu yazmak istiyorsanız kesinlikle yapılabilir.
evilsoup

Zaten komut dosyası yazdım, ancak gerekmediği takdirde kodumu temizlemek istedim.
sashoalm

min(…)Boyutları ayrıştıran basit bir komut dosyasıyla, ancak gibi işlevleri kullanan bir ölçek filtresiyle muhtemelen mümkündür . Ne yapılabileceğine dair bir örnek için
komutuma bakın

Yanıtlar:


10

Daha yeni ffmpeg sürümlerinde scalefiltrenin force_original_aspect_ratioseçeneğini kullanabilirsiniz. Örneğin, bir videoyu yükseltme yapmadan 1280 × 720 boyutuna sığdırmak için (daha fazla bilgi için bu gönderiye bakın ):

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

Burada, scalegiriş videosu bundan daha büyükse filtre 1280 × 720 olarak ölçeklendirilir. Daha küçükse, ölçeklendirilmez. En padboy oranının veya boyutunun hedef boyuttan farklı olması durumunda, çıkış videosunu 1280 × 720'ye getirmek için filtre gereklidir.


Eski ffmpeg sürümlerinde, biraz hileli bir geçici çözüm var. İlk olarak, çıktınızın genişliğini, yüksekliğini ve en boy oranını tanımlayın. Bu bize biraz tasarruf sağlayacaktır.

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

Şimdi Jim Worrall'ın yazdığı süper karmaşık filtre komutunu uygulayalım :

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

Tüm bunların ne yaptığını açıklamaya gerçekten girmeyeceğim, ancak temelde herhangi bir videoyu besleyebilirsiniz ve sadece ölçeksiz, lüks değil. Eğer hazırsanız, filtreyi kendi ifadelerine ayırabilirsiniz. Bunu kısaltmak mümkün olabilir, ancak aynı şekilde çalışır.


1
+1 ama bu gerçekten korkunç bir komut: P
evilsoup

Doğruyu biliyorum? On dakikayı mantıksal parçalara ayırmaya çalıştım ve sonra bazı değerler ekledim ama vazgeçtim. Biraz eski ve belki de bundan daha kısaca yazmak mümkün olabilir.
Mart'ta slmck

14

Daha okunabilir bir sürüm aşağıdaki gibi görünebilir:

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

640 / iw yatay ölçeklendirme faktörü ve 360 ​​/ ih dikey ölçeklendirme faktörüdür

Ölçekli görüntüyü çıkış kutusunun içine sığdırmak ve (depolama) en boy oranını korumak istiyorsunuz. Bunu, minimum işlevle en küçük ölçeklendirme faktörünü seçerek yaparsınız: min (640 / iw, 360 / ih)

Başka bir minimum işlev eklemek için yukarı ölçeklendirmeyi (yani ölçeklendirme faktörü> 1.0) engellemek istiyorsunuz: min (1, min (640 / iw, 360 / ih))

Bir sonraki adım, ölçekleme faktörünü giriş genişliği ve giriş yüksekliği ile çarparak çıkış çözünürlüğünü hesaplamaktır:
çıkış genişliği = iw * min (1, min (640 / iw, 360 / ih))
çıkış yüksekliği = ih * min (1, min (640 / iw, 360 / ih))

Son adım, filtre komutunu oluşturmaktır. Çıkış yüksekliğini belirtmeye gerek yoktur, -1 belirtebilirsiniz ve ffmpeg, genişlikle aynı ölçeklendirme faktörünü uygulayarak en boy oranını koruyacaktır.


A + Kutudan çıkar çıkmaz çalışır. Seçilen Cevabım çözüm yoktu değil boy oranı korunur. Çerçeveleri sıktı.
287352

5

Ben de aynı sorunu yaşadım, ancak videoyu 640x640 kare (akıllı telefonlar ile yapılan dikey videolar nedeniyle) takarak çözüldü.

Yani immerzi mantığı ve bazı araştırmaları kullanarak bununla sonuçlanırım :

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

son kısım, birçok enkoderin ihtiyaç duyduğu 2'ye bölünebilen bir yüksekliğe sahip olmak içindir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.