Ffmpeg / avconv ile videoları statik boyutlu oynatıcıya sığdırmak için yeniden boyutlandırma


65

700 piksel genişliğinde, 400 piksel yüksekliğinde bir html 5 video oynatıcım var. avconvYeniden boyutlandırmak için ffmpeg kullanmaya çalışıyorum (en boy oranını koruyarak) ve oynatıcımla uyumlu olduğundan emin olmak için.

Giriş, herhangi bir boyutta bir dosya olabilir, bu yüzden daha büyük olanları yeniden boyutlandırmam gerekiyor, ancak daha küçük olanları siyah çubuklarla ortalamam gerekiyor. Şimdiye kadar denedim: -sve -aspect, anahtarla padkullanıldığını gördüm , -vfancak ihtiyacım olanı elde etmek için nasıl çalıştığını anlamadım.

Görüntüler

Bu ihtiyacım olan şey hakkında kabaca bir fikir. Mümkün mü bile olsa emin değilim. Neredeyse CSS'nin maksimum genişlik / maksimum yükseklik gibi. Bunun sadece bir karmaşa olabileceğinin farkındayım, ancak herhangi biri neden bahsettiğimi anlarsa, yardımına minnettar olurum, Teşekkürler.

avconv komutu:

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


4
Daha sonra bir cevap yazacağım, ancak şunu söyleyeceğimi düşündüm: Videoyu yalnızca sabit sütun eklemek için yeniden kodlamak ya da posta kutusu göndermek korkunç bir fikir. Sadece bu süreçte kalitenizi kaybetmezsiniz (veya gereksiz yere dosya boyutunu da arttırırsınız), aynı zamanda daha sonra parmaklıklardan kurtulmanızı imkansız hale getirirsiniz. İdeal olarak, oynatıcınız yalnızca bununla ilgilenmeli ve görüntülerken videoyu yeniden boyutlandırmalıdır. Sorabilirsem, senin kullanım davası nedir?
slhck

Orijinal dosyayı bir S3 kovasında saklıyoruz, bu yüzden sorun yok ve yine de geniş bir video türü kapsamı kabul ettiğimizde yeniden kodlama yapıyoruz. bir tarayıcı. Yani videoyu yeniden boyutlandırıp html / css ayağı / letterbox'ları yapmayı önerebilirsin Teşekkürler
Jamie Taylor

1
Kabul edilen cevabın sahibi olarak, gönderimi kabul etmemenizi ve bunun yerine LordNeckbeard'in cevabını kabul etmenizi öneririm.
slhck

@slhck, bunu düşünüyordum, kutsamanla birlikte, başaracağım.
Jamie Taylor

Yanıtlar:


52

Ölçek filtresindeforce_original_aspect_ratio seçeneği kullanmak basit bir yöntemdir .

orijinal görüntü
Orijinal görüntü. 640x480, 4: 3 en boy oranı videoyu temsil eder.

Bu örneklerde, orijinal görüntü, orijinal görüntü oranını koruyarak 16: 9 görüntü oranına sığacak şekilde ölçeklendirilecektir. Bunu yapmak için şunları yapabilirsiniz:

Pillarbox veya letterbox

ayağı kutulu resim
Pillarboxed görüntüsü. 640x480 (4: 3) girişin 1280x720 (16: 9) çıkışa takılması.

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • Bu görüntüyü yükseltir. Yükseltme yapmaktan kaçınmak istiyorsanız aşağıdaki örneğe bakın.

  • Girdi en boy oranı çıktı en boy oranından daha genişse, letterboxing gerçekleşir. Örneğin, 2.35: 1 en boy oranına sahip bir giriş 16: 9 çıkışa uygun bir giriş posta kutucuğuna neden olur.

Yukarıdakiyle aynı, ancak yükseltme olmadan

yükseltme yok
640x480 (4: 3), 1280x720 (16: 9) çıkışına, yükseltme yapmadan giriş yapar.

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

ekin

görüntü tanımını buraya girin
Kırpılmış görüntü. 4: 3 giriş görünüş oranı, 16: 9 çıkış görünüş oranı.

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

Ve benim için boş bir dolgu ekleyeyim?
Tiago Ferezin

@TiagoFerezin "Boş dolgu" nedir?
llogan

ah üzgünüm, siyah yerine başka bir renkle doldur, örneğin
Tiago Ferezin

2
@TiagoFerezin Ah, evet. Yapması kolay. Ped filtresini kullanan örneklerde, (veya isterseniz onaltılık kullanabilirsiniz) colorgibi bir seçenek ekleyebilirsiniz pad=1280:720:(ow-iw)/2:(oh-ih)/2:color=red. Renklerin listesine bakınız .
llogan

61

İşte sabit çıkış genişliği için sütun ya da posta kutusu ekleyen komut. Biraz uzun, ama dolguyu bir şekilde belirtmen gerekecek.

İlk olarak, kabuğunuzda çıktı genişliğini ve yüksekliğini tanımlayın:

width=700
height=400

Ardından komutu çalıştırın:

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

Bu, yeniden boyutlandırmak ve değiştirmek için gerekli olan temel özelliklere göre çıkarılmıştır; diğer video ve ses seçeneklerinizi uygun gördüğünüz şekilde ekleyin. İçin numaralar unutmayın widthve heighten codec'leri için çalışmak üzere 2'ye bölünebilen olmak zorunda.

İşte neler olup bittiğinin açıklaması:

  • ölçekleme:
    • Öncelikle genişliğe mi, boyuta göre mi ölçekleneceğini bulmamız gerekir.
    • Bunu yapmak için çıkış genişliğini giriş genişliğine ve çıkış yüksekliğini giriş yüksekliğine böleriz. Bu bize her boyut için ölçek faktörlerini verecektir.
    • Daha sonra hangisinin düşük olduğunu kontrol min()ederiz ve yeniden boyutlandırma için sadece bu faktörü seçeriz.
    • Son olarak, giriş genişliğini ve yüksekliğini bu faktörle ( iw*min(…):ih*min(…)) çarpıyoruz .
  • Dolgu malzemesi:
    • $width:$height çıkış genişliği ve yüksekliği
    • Sonuçlanan videonun nereye yerleştirileceğini bulmak için, ölçeklendirilmiş genişliği maksimum çıktı genişliğinden ve ölçeklendirilmiş yüksekliği maksimum çıktı yüksekliğinden çıkarmamız gerekir.
    • Ölçeklenmiş genişlikler ve yükseklikler, scalefiltreden yapılan ifadelerdir .
    • Her iki tarafa sınır eklemek için sonuçtaki ofseti 2'ye böleriz.

3
@JamieTaylor slhck örneğine eklemeyi düşünün -movflags +faststart. Aşamalı olarak indirilen videonuzun tamamen indirilmeden önce oynatılmaya başlamasını sağlar ve ayrıca daha fazla kodlama talimatları ve örnekler için FFmpeg ve x264 Kodlama Kılavuzu ile FFmpeg ve AAC Kodlama Kılavuzu'na bakın.
llogan

Ped filtresini bu şekilde kısaltabilirsin, sanırım:pad=$width:$height:(ow-iw)/2:(oh-ih)/2"
jdi

1
@jdi Eğer küçültüyorsanız bu işe yaramaz, çünkü bunun için negatif değerler ortaya çıkar ow-iw.
slhck

Başlangıç ​​noktası için teşekkürler! Bununla birlikte, örnek en boy oranına sahip videolarda uygun en boy oranını elde etmek için! = 1, "iw" nin her oluşumunun "sar" ile çarpılması gerekir, bu nedenle "iw" nin HER oluşumu "(sar * iw)" ile değiştirilir. Filtrede ifade benim için çalışıyor.
schieferstapel

@slhck Hey, android deniyorum ama çalışıyor gibi görünmüyor, bana yardımcı olabilir misiniz !!! ffmpeg -i girişi.mp4-filtresi: v ölçeği = 640 * dak (700 / 640,400 / 360): 360 * dak (700 / 640,400 / 360), ped = 700: 400: (700-640 * dak (700 / 640,400) / 360)) / 2: (400-360 * dak (700 / 640.400 / 360)) / 2 çıktı.mp4
Nisarg

8

Bana öyle geliyor ki bunu üç adımda yapmanız gerekiyor:

  1. Giriş en boy oranını kontrol edin
  2. DAR> 7/4 genişliğinde videoları ölçeklendirin (genişliği 700 olarak değiştirin ve en boy oranını korumak için yüksekliği ölçeklendirin) ve DAR <7/4 boyunda olanları ölçeklendirin
  3. Videoyu, 700: 400 aralığına sığacak şekilde kaydırın.

FFmpeg / avconv, ölçekleme / dolguyu video filtrelerle tek bir adımda yapabilir, sadece bir kez kod dönüştürür. Örneğin, 16: 9 video çekmek için genişlikle ölçeklendirin ve ardından sonuçları posta kutusuna yerleştirin:

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

... ama ilk adım için (en boy oranını tespit etmek ve ihtiyaç duyduğunuz 7: 4 ile karşılaştırmak) bir çeşit senaryo kullanmak zorunda kalacaksınız.

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

... size videonun '16: 9 'veya' 4: 3 'gibi görünecek olan en boy oranını gösterecektir. Bir bash betiğinde şöyle bir şey kullanırdım:

#!/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

Açıkçası bunu ihtiyaçlarınıza göre uyarlamanız gerekecek.


1
Bunu tek adımda yapmak mümkün, cevabımı görün.
slhck

@slhck Şimdi daha kolay. Gitar kefalının cevabına bakınız.
lgagan

@ LordNeckbeard Teşekkürler! Geçenlerde bu seçeneği gördüm, gerçekten çok daha kolay.
slhck
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.