Memotong video pada frame yang tepat dengan filter pilih ffmpeg

16

Alih-alih menggunakan -ssdan -tomencari parameter, yang tampaknya tidak terlalu akurat, dapatkah saya memotong video untuk nomor bingkai tertentu? Sebagai contoh;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[Bingkai ke-80 dan bingkai ke-560 disertakan. Jadi, totalnya membuat (560 - 80 +1) bingkai]

Setelah jawaban dan sedikit pencarian, saya sudah mencoba beberapa perintah. Tetapi sejauh ini saya tidak dapat menemukan cara yang dapat diterima.

Jika seseorang ingin memotong streaming video antara frame 250 dan 750, ini adalah cara untuk pergi. Ini akan memberikan 501 frame sebagai output:

Catatan: movie.mp4 memiliki 25 fps, dan audio sample rate 48k

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Seperti yang diharapkan, outputnya panjang 20 detik, tepatnya.

Menggunakan metode yang sama untuk audio:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Tanpa diduga, akurasi yang satu ini sangat buruk. Seharusnya memberi saya 960001 (960k +1) sampel yang sama dengan audio 20 detik. Tetapi sebaliknya, hasilnya adalah 20,505 detik dan memiliki 984240 sampel. Juga, jika saya meningkatkan durasinya, kesalahan juga meningkat.

Kemudian saya mencoba menggunakan parameter -ss -to untuk memotong aliran audio:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

Cara klasik lama bekerja lebih baik. Output adalah 20,003 detik dan memiliki 960144 sampel. Plus, meningkatkan durasi tidak meningkatkan kesalahan, kesalahannya konstan, selalu ada 144 sampel surplus dengan file input itu.

Ringkasnya: selectfilter bekerja dengan baik sebagian besar waktu tetapi pilih tidak. -ssParameter klasik berfungsi lebih baik untuk audio tetapi tidak akurat sampel. Selain itu, tidak mungkin untuk menggunakan -vf selectdan -ssparameter secara bersama-sama, karena -ssakan memengaruhi streaming audio dan video sementara kami menginginkannya hanya memengaruhi audio.

Jadi, untuk memotong file media dengan tepat saya harus melakukan 3 langkah ini:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

Ini memberikan hasil yang paling akurat. Video berdurasi 20.000 detik dan Audio dengan frame-akurat 20,003 detik dan memiliki 960144 sampel. Tidak persis cocok dengan aliran video, tetapi tidak masalah. Hanya ada 144 sampel surplus. Kelemahan terbesar adalah, setiap kali saya ingin memotong file, saya harus mengirim 3 perintah untuk pekerjaan sederhana dan itu membuat dua file yang tidak perlu: a_stream.webm dan v_stream.webm. Dan selectfilter tidak berfungsi pada beberapa file input yang saya coba. Berhasil melakukan pekerjaan (?) Tetapi tidak pernah menghentikan proses penyandian, jadi saya harus menutup command prompt setiap waktu.

destor
sumber
Saya telah membaca halaman itu sebelum saya memposting pertanyaan ini. Halaman itu tidak membantu saya. Jika suatu input memiliki variabel fps dapatkah kita menghitung dengan menggunakan persamaan itu? Saya rasa tidak. Juga masih saya tidak berpikir '-ss' akan memberi saya posisi yang akurat. Bingkai demi bingkai mencari akan lebih baik kurasa.
destor
Perhatikan bahwa -ssframe-akurat (lihat di sini ). Apakah Anda benar-benar memiliki input variabel-fps? Jawaban saya menghubungkan ke utas milis yang menyebutkan menggunakan selectfilter tempat Anda dapat menentukan nomor bingkai. Sudahkah Anda mencobanya?
slhck
Saya telah mencoba menggunakan selectdan aselectmemfilter untuk streaming video dan audio. Selectframe-akurat untuk video, tetapi aselecttidak akurat sampel. Sebenarnya itu jauh dari akurat. Ini memberikan hasil yang jauh lebih buruk daripada menggunakan -ss -toparamaters sederhana . Karena itu, untuk saat ini, saya menggunakan kombinasi selectfilter dan -ss -toparameter untuk mendapatkan pemotongan paling akurat. Tapi itu adalah cara kumuh untuk melakukannya. Silakan lihat posting pertama saya, saya telah menambahkan beberapa commandlines dan hasilnya
destor
versi ffmpeg?
fie
Mengapa Anda mencoba memotong dengan nomor bingkai. Jika seseorang membutuhkan akurasi seperti itu maka mengapa tidak menggunakan avidemux? Mungkin juga masalah awal Anda karena memilih bingkai kunci terdekat?
fie

Jawaban:

3

Audio berasal dari detik, bukan bingkai, jadi jika Anda ingin memotong video, Anda harus menghitung video fps × 20 detik seperti ini: 20 detik dari 23,97 fps = 479,4

Pemotongan bingkai tidak akurat karena Anda tidak bisa mendapatkan fps penuh untuk detik terakhir, sehingga audio akan mendapatkan lebih banyak detik atau hanya setengah detik atau sedikit lebih atau kurang! Mungkin Anda harus menggunakan detik, bukan bingkai untuk mendapatkan potongan yang tepat, Anda memberi tahu ffmpeg untuk melakukannya untuk Anda. Dan jika Anda mendapatkan 1 frame tambahan, bagaimana dengan mengubah frame ke-250 dan ke-750 ke frame ke-250 dan ke-749 ?! Gunakan minus 1 di sana untuk selalu mendapatkan berapa banyak frame yang Anda minta!

Mojtaba Golestani
sumber
Sebenarnya audio berasal dari sampel, bukan detik ...
Anubioz