Apa cara yang efisien untuk melakukan crossfade video dengan FFmpeg?

11

Melakukan crossfade antara dua bagian konten video sebenarnya cukup rumit di FFmpeg. Tidak ada filter "crossfade" seperti untuk audio.

Apa cara yang efisien untuk melakukannya?

Mark Gerolimatos
sumber
Pertanyaan terjawab sendiri yang bagus!
JakeGould
Jawaban ini perlu mendapatkan BANYAK lebih banyak upvotes ... Mark, saya akan sangat mencintaimu selamanya jika Anda menambahkan cross-fading untuk audio juga ...
Merc
Segera setelah saya mengetahui caranya, saya akan menambahkannya. Saya pikir audio crossfade adalah snap, tho ', percaya bahwa ada filter sederhana untuk itu.
Mark Gerolimatos
Saya hanya menambahkan [0:a][1:a] acrossfade=d=1 [audio]ke filter dan kemudian -map "[audio]" ke perintah dan itu berhasil. Jika Anda suka, berikan tes dan perbarui jawabannya!
Merc
Kemungkinan duplikat crossfade antara 2 video menggunakan ffmpeg
r_alex_hall

Jawaban:

17

TL; versi DR:

Contoh ini hanya menjalankan video, dengan asumsi kedua klip video memiliki resolusi yang sama, kecepatan bingkai, dll. Ini akan membuat pudar 1 detik di antara fadeoutclip dan fadeinclip. Asumsikan bahwa fadeoutclip berdurasi 10 detik. Perhatikan bahwa ini diformat untuk kejelasan: ini benar-benar satu baris kode.

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an \
-filter_complex "\
    [0:v]trim=start=0:end=9,setpts=PTS-STARTPTS[firstclip]; \
    [1:v]trim=start=1,setpts=PTS-STARTPTS[secondclip]; \
    [0:v]trim=start=9:end=10,setpts=PTS-STARTPTS[fadeoutsrc]; \
    [1:v]trim=start=0:end=1,setpts=PTS-STARTPTS[fadeinsrc]; \
    [fadeinsrc]format=pix_fmts=yuva420p, \
                fade=t=in:st=0:d=1:alpha=1[fadein]; \
    [fadeoutsrc]format=pix_fmts=yuva420p, \
                fade=t=out:st=0:d=1:alpha=1[fadeout]; \
    [fadein]fifo[fadeinfifo]; \
    [fadeout]fifo[fadeoutfifo]; \
    [fadeoutfifo][fadeinfifo]overlay[crossfade]; \
    [firstclip][crossfade][secondclip]concat=n=3[output] \
    " \
-map "[output]" <add in encoding part here>

Versi lengkap:

Berikut ini penjelasan tentang semua ini:

Spesifikasi Input ... jelas

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an

Membuat filter_complex: dengan asumsi Anda sudah memahami kompleks filter:

-filter_complex

Pertama kita memecah dua aliran menjadi dua bagian masing-masing menggunakan filter trim : konten dan bagian memudar lintas. Fade out dipecah menjadi konten dan bagian fade, sedangkan fade in dipotong menjadi bagian fade dan konten. Total empat bagian.

Perhatikan bahwa sebenarnya, kita tidak harus memecah bagian fade out: kita BISA hanya menentukan fade out dan fade dalam waktu untuk dua klip video. Namun, dengan melakukan ini, kami:

  • Ikuti metodologi yang biasanya digunakan oleh editor video GUI
  • Hindari kompleksitas penggunaan overlayfilter yang membuat frustrasi
  • Pastikan bahwa solusinya adalah senyata mungkin (yaitu kode yang dapat digunakan kembali)
  • Izinkan kami untuk melakukan pra-proses dan pasca-proses bagian crossfade sebagaimana diperlukan (tidak dilakukan di sini)

Masing-masing dari empat bagian ini menentukan: waktu mulai (detik), waktu akhir (detik), dan setpts=PTS-STARTPTSfilter misterius , yang pada dasarnya membuat setiap subclip video dimulai pada 0 detik. Ini akan sangat penting ketika mengomposisi ulang mereka.

Perhatikan bahwa s=0penspesifikasi berlebihan, dan setptsfilter s=0untuknya juga berlebihan. Namun, keduanya ditentukan secara berlebihan untuk memungkinkan waktu mulai berubah dari 0, tanpa merusak kompleks filter. Juga, klip konten kedua berjalan ke akhir, sehingga e=bagian (akhir =) tidak ditentukan.

    [0:v]trim=s=0:e=9,setpts=PTS-STARTPTS[firstclip];
    [1:v]trim=s=1,setpts=PTS-STARTPTS[secondclip];
    [0:v]trim=s=9:e=10,setpts=PTS-STARTPTS[fadeoutsrc];
    [1:v]trim=s=0:e=1,setpts=PTS-STARTPTS[fadeinsrc];

Selanjutnya, kami menentukan fade in dan fade out: Kami pertama-tama menambahkan saluran alfa (transparansi) ke kedua bagian fade dengan menentukan format pikselyuva420p . Anda benar-benar dapat menggunakan format apa pun yang menyediakan saluran alfa.

Berikutnya dalam filter ini subcomplex kita menentukan satu memudar, dan satu memudar di. The alpha=1berarti bahwa video itu sendiri tidak akan gelap, hanya jumlah transparansi akan "memudar". stberarti mulai, dberarti durasi.

    [fadeinsrc]format=pix_fmts=yuva420p,      
                fade=t=in:st=0:d=1:alpha=1[fadein];
    [fadeoutsrc]format=pix_fmts=yuva420p,
                fade=t=out:st=0:d=1:alpha=1[fadeout];

Apa ini ?: The fifoFilter memastikan bahwa ada penyangga ruang yang tersedia dalam filter yang kompleks. Hebatnya, ini BUKAN default. Jika Anda tidak melakukan ini, crossfade bisa gagal jika output dari tahap di atas mengganti filter overlay di bawah ini. Ya, saya tahu apa yang Anda pikirkan saat ini. Ini memang bug FFMPEG .

    [fadein]fifo[fadeinfifo];
    [fadeout]fifo[fadeoutfifo];

Sekarang, overlay dua bagian fade: Dengan memastikan dua bagian crossfade memiliki ukuran yang sama, kita tidak perlu khawatir tentang opsi yang agak buruk yang diambil filter overlay (dan karenanya kita abaikan di sini):

    [fadeoutfifo][fadeinfifo]overlay[crossfade];

Akhirnya, kami mengatur tiga segmen kami menggunakan filter concat .

    [firstclip][crossfade][secondclip]concat=n=3[output]

Dan sekarang, petakan pad output sebagai sumber video Anda.

JANGAN LUPA untuk mengatur format piksel KE APA YANG BIASANYA ANDA GUNAKAN (biasanya yuv420p), karena bagian crossfade akan mengaturnya yuv420pada saluran output! (karena kami tidak menentukannya, Anda dapat menggunakan argumen overlay) Tentu saja, jika Anda INGIN yuv420, maka Anda baik-baik saja :-)

-map "[output]" <add your normal encoding part here>

Anda kemudian dapat menggabungkan kembali audio nanti (di luar ruang lingkup T&J ini)

Mark Gerolimatos
sumber
1
Dalam ffmpeg terbaru, itu harus trim=start=0:end=9, (bukan trim=st=0:e=9,..
Merc
Tapi serius, ini harus menjadi jawaban terbaik untuk FFMPEG yang pernah saya lihat, dan penjelasan ffmpeg paling jelas yang pernah ada.
Merc
Man, itu akan pergi ke kepalaku :-) Terima kasih atas alat peraga !!!!
Mark Gerolimatos
Jangan khawatir. Harap perbarui jawabannya terutama dengan = trim = start = 0 karena sekarang ini tidak berfungsi dengan ffmpeg terbaru
Merc
Versi ffmpeg terbaru memberi saya kesalahan ini: Filter setpts has an unconnected outputuntuk skrip. Saya sudah mengubah parameter trim untuk memulai dan mengakhiri.