FFmpeg kullanarak her çift veya tek kareyi bırak?


14

Ham video çekmek ve ondan yalnızca tek kare veya çift kare içeren yeni bir video çıkarmak için doğru bir yol var mı?

Örneğin:

400 kare (0-399) ile "blah.yuv" var. 1-399 (1,3,5,7 ... 399) kareleri içeren "blahOdd.yuv" ve 0-398 (0,2,4,6 ... 398 karelerini içeren "blahEven" oluşturmak istiyorum ).

Herhangi bir fikir sadece FFmpeg kullanarak nasıl?

Yanıtlar:


11

Doğru şekilde çalışmak için, önce videoyu RAW YUV bit akışına (zaten değilse) şu şekilde dönüştürün:

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

Sonraki adım: selectfiltre alır bir ifade , nçerçeve sayısıdır.

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

Sahip olmak ffmpegdeğil yinelenen kareleri, doğrudan giriş yapmanız frame oranının kuvvet yarısına sahip - ayarladığınız yüzden "2" çıkışına giriş ve "1" olarak. Ham bit akımının bu bilgileri taşıyan bir başlığı olmadığından Gxy'yi klibinizin gerçek boyutlarıyla değiştirmeyi unutmayın.

Yukarıdakilerin yerine setpts, çıkış için yeni zaman damgaları ayarlamak üzere filtre eklemek başka bir olasılık olabilir . Ancak çerçeveleri doğru bir şekilde düşürmediğinden dikkatli olun. Burada 25, istediğiniz gerçek çıktı kare hızıdır:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv

Elbette başka bir piksel formatı (herhangi biri ffmpeg -pix_fmts) seçebilirsiniz . Dosyayı okurken piksel boyutunu ve piksel biçimini bildiğinizden emin olun:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …

Teşekkürler, FFMPEG'in yeni sürümleri için -filter yerine -vf olmalıdır: v. Buna ek olarak mod (n-1 \, 2) olmalıdır, çünkü n sayısı 1'den başlarken kare sayısı 0'dan başlar (aksi takdirde ilk kare 3 kez çoğaltılır). Ama yine de bir sorun var, onlardan kurtulmak için çerçeveleri çoğaltır - örneğin son klip çerçevelerin sadece yarısını içerir.
Mark

-vfbir takma adıdır -filter:v. Şimdi güvenilir bir şekilde test edemiyorum, ancak daha sonra makineme geri döndüğümde buna bakacağım. Belki tinterlacefiltre de aynısını yapabilir?
Mart'ta

'-R 2 -i blah.yuv -r 1' denedim ama bana bir hata gösterir Seçenek framerate bulunamadı.
Mark

Ah üzgünüm .. Scratch, bu işe yaramıyor (artık?) Ve sadece görüntüler için.
Mart'ta

1
@AnmolSinghJaggi Hayır, bu sadece kareleri düşürüyor, ancak bu kadar belirleyici olduğundan emin değilim (yani, her garip kareyi düşürür). Doğru olmayabilecek zaman kodlarına dayanacaktır.
slhck

2

Eğer ffmpeg'iniz AviSynth bayrağıyla oluşturulmuşsa, bir dosyayı aktarabileceğinize inanıyorum.avs .

Sen çalıştırarak kontrol edebilirsiniz ffmpegve arayan --enable-avisynthiçinde yapılandırma verileri. enable-avisynth

E? Er orada o kadar gibi kullanabilirsiniz: ffmpeg -i blahEven.avs blahEven.yuv.

blahEven.avsBasitçe nerede :

ffvideosource ( "blah.yuv"). SelectEven ()

Tek çerçeveler için kullanın SelectOdd().

Daha ileri düzeyde kullanım için SelectEvery belgelerine bakın.


Bu mükemmel bir alternatif, ama bahsettiğim gibi - sadece ffmpeg kullanmakla sınırlıyım. Bunun nedeni, yalnızca .bat dosyaları oluşturacak, AVS ekleme imkanı olmayan otomatik bir sistemin bir parçasıdır.
Mark

@ Mark, eğer --enable-avisynthorada olsaydı , AviSynth'in ffmpeg'e kurulduğu anlamına geldiğini düşünüyordum , ama bundan emin değilim.
Louis
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.