Görev ve neden göründüğünden daha karmaşık olduğu
"Bana bu klipten saniyede bir kare ver" en yaygın video işlerinden biridir. Bir QA test uzmanının, bir hata raporuna eklemek için eşit aralıklı ekran görüntülerine ihtiyacı vardır. Bir araştırmacının, açıklama aracını beslemek için örneklenmiş bir görüntü dizisine ihtiyacı vardır. Bir sosyal editörün zaman çizelgesini elle temizlemeden iki dakikalık bir kesitten yirmi aday fotoğrafa ihtiyacı var.
Görevin kendisi basittir. Bunu karmaşık hale getiren şey, yakından baktığınızda "saniyede bir kare"nin belirsiz olmasıdır. Oynatma süresinin her saniyesi için bir kare mi, yoksa her Hkaresinden ziyade kodlanmış kareye mi ayarlandı? Bunlar farklı şeyler: 24 fps'lik bir klip ve 60 fps'lik bir klip, ilk okumada aynı sayıyı, ikinci okumada ise tamamen farklı sayıları üretir. Yanlış olanı seçerseniz ya neredeyse kopyalardan oluşan bir klasör elde edersiniz ya da kullanışlı olamayacak kadar seyrek bir sekans elde edersiniz.
Aşağıdaki her iki yaklaşım da aynı pikselleri üretir. İstediğinizi ifade etme şekliniz ve yanlış ifade ettiğinizi ne kadar çabuk anladığınız açısından farklılık gösterirler.
Yöntem 1: FFmpeg, parametre parametre
Kurallı komut kısadır:
ffmpeg -i input.mp4 -vf fps=1 -q:v 2 frame_%04d.jpg
Her parçası önemlidir:
-i input.mp4— kaynak dosya. FFmpeg baştan sona bir kez okur; her zaman damgasını ayrı ayrı aramaz.-vf fps=1— asıl işi yapan video filtresi.fps=1bu, saniye başına bir çıktı karesi oynatma süresinekaynak kare hızından bağımsız olarak. Kullanımfps=1/5her beş saniyede bir kare veyafps=2saniyede iki kare. Bu, oynatma süresi okumasıdır.-q:v 2— 2'nin neredeyse kayıpsız olduğu ve 31'in yoğun şekilde sıkıştırıldığı ters bir ölçekte JPEG kalitesi. Bunu atlarsanız FFmpeg'nun çoğu insanın beklediğinden çok daha yumuşak olan varsayılan değerini elde edersiniz. Kayıpsız çıktı istiyorsanız, yazınframe_%04d.pngbunun yerine bu bayrağı tamamen bırakın.frame_%04d.jpg— çıktı modeli.%04dsayacı dört haneye kadar sıfırlar:frame_0001.jpg,frame_0002.jpg. Dolgu kozmetik değildir; aşağıdaki numaralandırma problemine bakın.
Diğer okumaları istiyorsanız - her Hkodlanmış akışın her H saniyede - filtre değişir:
ffmpeg -i input.mp4 -vf "select=not(mod(n\,10))" -vsync vfr frame_%04d.png
Bu, kareleri, kare indeksinin olduğu yerde tutar n 10'a bölünebilir ve -vsync vfr FFmpeg'nun sabit bir çıktı hızı sağlamak için kareleri çoğaltmasını durdurur. Bu işareti devre dışı bırakırsanız, istediğinizden çok daha fazla dosya alırsınız; bu, yaygın ve kafa karıştırıcı bir ilk sonuçtur.
İşi bir bölümle sınırlamak için, put -ss önce -i böylece FFmpeg, kodu çözüp atmak yerine kod çözmeden önce arar:
ffmpeg -ss 00:01:30 -to 00:02:15 -i input.mp4 -vf fps=1 frame_%04d.png
Yöntem 2: Tarayıcıda aynı iş
bu sitedeki kare çıkarıcı aynı iki okumayı eşleştirir; belirsizlik bir filtre dizesinde gizlenmek yerine arayüzde açıkça belirtilir.
- Dosyayı bırakın. Diskten doğrudan tarayıcı belleğine okunur - yükleme yoktur, bu nedenle 3 GB'lık bir kaynak aktarımdan sonra değil hemen işlenmeye başlar.
- Çıkartma yöntemini seçin. "Zaman Aralığı" eşdeğerdir
fps=1/N— boşluğa saniyeler içinde girersiniz. "Kare Hızı (FPS)" şuna eşdeğerdir:select/modfiltresi — konuşma kafası veya ekran kaydı için girersiniz H her Hinci kare. - Çıkartmadan önce kare sayısı ipucunu okuyun. Bu, en çok zaman kazandıran kısımdır. Arayüz, mevcut ayarlarınızın kaç resim üreteceğini gösterir önce her şey çalışır, dolayısıyla 4.000 dosyalık hata, keşfettiğiniz bir klasör yerine gördüğünüz bir sayıya dönüşür.
- Biçim ve kaliteyi ayarlayın. Kayıpsız için PNG, boyut önemli olduğunda %10-100 kaydırıcıyla JPG veya WebP. Kaydırıcı konumu, çerçeveler analize veya düzenlemeye beslendiğinde
-q:vkontroller, çoğu insanın onun hakkında nasıl düşündüğünü ifade eder. - Gerekirse aralığı kırpın. Çift tutamaçlı kaydırıcı
-ss/-toeşdeğerdir, siz sürükledikçe zaman damgaları gösterilir. - Dışa aktarın. Çerçeveler önizleme ızgarasında görünür; tek başına kaydetmek için birine tıklayın veya tüm seti tek bir ZIP olarak alın.
Bir aralık seçmek için temel kural: , her 2-5 saniyede bir 1 kare yakalar her anlamlı durum değişikliği. Spor veya hızlı hareket eden herhangi bir şey için saniyede 2-5 kare. Gerçek kare doğruluğu analizi için "her kareyi" ayırın. Dakikada 60 fps, 3.600 görüntü ve birkaç gigabayt PNG anlamına gelir.
İnsanların zamanına mal olan üç sorun
1. Çıktı binlerce birbirine yakın karedir
Neredeyse her zaman bir birimler karışır: "her 10. karede" demek istediniz ve şunu yazdınız: fps=10, bu on kare anlamına gelir çıkış modeli — saf beklentiden 3 kat daha az değil, 3 kat daha fazla görüntü olan 30 fps'lik bir kaynakta.
Herhangi bir şeyi çalıştırmadan önce, oynatma süresi modunu yapın: duration ÷ interval. Çerçeve indeksi modu: duration × source_fps ÷ N. "Her 10. karede" 10 dakikalık 30 fps'lik bir klip 600 × 30 ÷ 10 = 1.800 görüntüdür. Bu sayı sizi şaşırttıysa, başlamadan önce ayarlama yapın. Tarayıcı aracında aralık alanının altında aynı şekil otomatik olarak görünür.
2. Uzun bir videonun ortasında çıkarma işlemi duruyor
Her iki tarafta farklı nedenler olduğundan düzeltme de farklıdır.
FFmpeg'da duraklama genellikle diskle ilgilidir; binlerce PNG gelir bir dizin ve kod çözücü değil dosya sistemi darboğaz haline gelir. Yeni ve boş bir dizine yazın, kayıpsız ihtiyacınız olmadığında JPG'yu tercih edin ve çok uzun kaynakları -ss/-to.
Tarayıcıda sınır RAM'dir: çıkarılan her kare siz ZIP indirilene kadar bellekte tutulur. Birkaç yüz 4K PNG birkaç gigabayttır ve bunun için bir sekme kapatılabilir. Güvenilir model parçalar halinde çalışmaktır; 0:00–2:00 almak için zaman aralığı kaydırıcısını kullanın, ZIP'yu indirin ve ardından aralığı 2:00–4:00'a taşıyın. Büyük bir işten önce diğer sekmeleri kapatmak gerçekten yardımcı olur ve %85-90 kalitede JPG, çoğu kullanımda görünür bir fark olmadan bellek basıncını birkaç kat azaltır.
3. Çerçeve numaralandırması içe aktarma sırasını bozar
Bu, dışa aktarma iyi göründüğünde ısırır. Dosya adlarını metin olarak sıralayan araçlar (ve çoğu bunu yapar) frame_10.png önce frame_2.pngçünkü "1", karakter bazında "2"den önce sıralanır. Diziniz şifreli olarak oynatılıyor ve bunun nedeni açık değil.
Düzeltme sıfır dolguludur, şimdiye kadar yapabileceğiniz en büyük sayıma yetecek kadar geniştir üretmek. Bu, %04d içindir; use %05d 9.999 kareyi aşabilirseniz. Tarayıcı aracı otomatik olarak dolgu yapar, bu da çıktısının yeniden adlandırılmadan doğrudan bir görüntü dizisi içe aktarıcısına düşme eğiliminde olmasının ana nedenidir.
FFmpeg hâlâ doğru çağrı olduğunda
Çoğu zaman. Bu, tarayıcının her açıdan kazandığı bir durum değildir:
- Komut dosyasıyla yazılmış veya planlanmış her şey. Bir cron işi, bir CI adımı, bir sunucu tarafı boru hattı; bir tarayıcı bunlara hiçbir şekilde katılamaz.
- Birçok dosyada gruplar. 200 klipten fazla kabuk döngüsü FFmpeg'da önemsizdir ve başka yerlerde sıkıcıdır.
- Tarayıcının kodunu çözemeyeceği codec bileşenleri. ProRes, DNxHD, raw kamera formatları, alışılmadık kapsayıcılar. Tarayıcı onu oynatamazsa, ondan çıkaramaz. FFmpeg neredeyse her şeyin üstesinden gelir.
- Ekstraksiyon sırasında filtreleme. Taramalı tarama, ölçekleme, renk alanı dönüştürme, kırpma, sahne değişikliği algılama — hepsi aynı geçişte filtreler olarak kullanılabilir.
- Tekrarlanabilirlik. README'deki bir komut kesindir. "Kaydırıcıyı yaklaşık buraya ayarla" değil.
Tarayıcı aracı, ara sıra yapılan bir görev için bir araç zinciri kurmak ve bakımını yapmak istemeyen herkes için, kaynağın yalnızca yerel işlemenin önemli olduğu kadar gizli olduğu ve dışa aktarma işlemine başlamadan önce çerçevelere bakmak istediğiniz durumlarda, tek seferlik işler için daha uygundur. Bunlar bir sıralama değil, gerçekten farklı durumlardır.
Hızlı başvuru
| İstediğiniz şey | FFmpeg | Tarayıcı aracı |
|---|---|---|
| Saniyede bir kare | -vf fps=1 |
Zaman Aralığı = 1 |
| Her 5 saniyede bir kare | -vf fps=1/5 |
Zaman Aralığı = 5 |
| Her biri. 10. kodlanmış kare | -vf "select=not(mod(n\,10))" -vsync vfr |
Kare Hızı modu, N = 10 |
| Yalnızca 1:30 - 2:15 | -ss 00:01:30 -to 00:02:15 |
Zaman aralığı kaydırıcısı |
| Kayıpsız çıktı | .png saniyede |
Biçim = PNG |
| Daha küçük dosyalar | -q:v 5 ile .jpg |
JPG + kalite kaydırıcısı |
| Çalıştırmadan önce sayıyı görün | Manuel hesaplama | Aralık alanı altında gösterilir |
| Kaydetmeden önce önizleyin | Çıktı klasörünü açın | Yerleşik önizleme ızgarası |
| Otomasyon / toplu | Kabuk döngüsü, cron, CI | Mümkün değil |
| ProRes, DNxHD, raw | Desteklenir | Yalnızca tarayıcının kodunu çözdüğü şey |
Hangi rotayı seçerseniz seçin, aralık kararı önce gelir ve araç ikinci sırada gelir. Gerçekte kaç kareye ihtiyacınız olduğunu hesaplayın, başlamadan önce sayımı onaylayın; gerisi mekaniktir.