Bagaimana memudar masuk / keluar klip video / audio dengan durasi yang tidak diketahui?

19

Saya sedang mengerjakan sebuah proyek di mana saya menggunakan ffmpeg untuk mengonversi beberapa file video, dan menambahkan efek fade in / out di bagian kepala dan ekor setiap klip.

Saya telah menggunakan sedikit kode ini untuk menambahkan efek fade / out pada klip dengan durasi yang diketahui:

ffmpeg -i clip.mp4 -filter:v 'fade=in:0:30,fade=out:9650:30' -c:v libx264 -crf 22 -preset veryfast -c:a copy fadeInOut.mp4

Dua pertanyaan saya adalah:

  1. Bagaimana saya bisa secara bersamaan memudar audio masuk / keluar?
  2. Bisakah ffmpeg secara otomatis mengetahui durasi klip dan diberi tahu hanya memudar 30 frame terakhir?

Terima kasih!

d13
sumber

Jawaban:

15

# 1 Untuk secara bersamaan memudar audio masuk / keluar:

ffmpeg -i clip.mp4 -vf 'fade=in:0:30,fade=out:960:30'
                   -af 'afade=in:st=0:d=1,afade=out:st=32:d=1'
       -c:v libx264 -crf 22 -preset veryfast fadeInOut.mp4

Kali afade berada di detik .

# 2 Secara Otomatis? Tapi lihat solusi di bawah ini

Pertama-tama Anda dapat menjalankan ffprobe untuk mendapatkan durasi.

ffprobe -i clip.mp4 -show_entries stream=codec_type,duration -of compact=p=0:nk=1

Anda akan mendapatkan sesuatu seperti ini:

video|13.556000
audio|13.816000

Anda kemudian dapat menggunakan hal di atas untuk memudar. Waktu ini dalam detik.

Penanganan masalah

ffmpeg -i clip.mp4 -sseof -1 -copyts -i clip.mp4 -filter_complex
       "[1]fade=out:0:30[t];[0][t]overlay,fade=in:0:30[v];
        anullsrc,atrim=0:2[at];[0][at]acrossfade=d=1,afade=d=1[a]"
       -map "[v]" -map "[a]" -c:v libx264 -crf 22 -preset veryfast -shortest fadeInOut.mp4

FFmpeg memiliki sseofopsi yang memungkinkan seseorang untuk mencari input dari akhir. Kita dapat menggunakannya untuk mencapai tujuan kita. Jadi kami memberi makan input dua kali, dengan waktu ke-2 menelan hanya detik terakhir. Kami memberi tahu FFmpeg untuk menjaga stempel waktu, sehingga ffmpeg mempertahankan posisi temporal dari bagian ekor ini.

Kami menerapkan fade out untuk ekor ini dan kemudian menampilkan hasilnya ke input penuh. Karena mereka adalah file media yang sama, latar depan sepenuhnya menutupi latar belakang, dan sejak copytsditerapkan, overlay terjadi pada bingkai identik yang sesuai pada input latar belakang.

Untuk audio, kami membuat audio dummy kosong berdurasi 2 detik, dan kemudian menerapkan crossfade audio dari audio utama ke audio dummy ini. Karena audio ke-2 kosong, efeknya adalah fade-out untuk input utama. Itu -shortestditambahkan untuk meninggalkan bagian dari audio boneka setelah crossfade telah terjadi.

Gyan
sumber
Ini memberikan kesalahan "tidak ada filter seperti itu!" untuk filter audio.
felwithe
1
Ada 4 filter audio yang digunakan. Yang mana? Jalankan perintah Anda dengan -reportmenambahkan dan berbagi laporan.
Gyan
7

Ini adalah retasan yang mengerikan, tetapi ini mungkin berhasil jika yang Anda ingin lakukan hanyalah audio fade in / out tetapi tidak tahu persis berapa lama klipnya:

ffmpeg -i input.mp4 -filter_complex "afade=d=0.5, areverse, afade=d=0.5, areverse" output.mp4

[edit 2019-07-24: Perhatikan bahwa solusi ini tidak baik untuk solusi streaming karena membutuhkan trek lengkap untuk diproses sebelum byte pertama dapat di-stream]

Pilihan lain yang akan saya gunakan acrossfadedengan trek diam:

ffmpeg -i input.mp4 -filter_complex "aevalsrc=0:d=0.6 [a_silence]; [0:a:0] [a_silence] acrossfade=d=0.6" output.mp4
marekventur
sumber
3
Ini sebenarnya cukup elegan :-)
bk138
ini bekerja dengan baik. dapatkah Anda menjelaskan cara kerjanya? mencoba memahami dokumentasi ..
oberhamsi
1
@oberhamsi: Opsi 1: Filter pertama menambahkan fade di awal trek. Kemudian membalikkan audio dan menambahkan fade lain di awal (yang sebenarnya adalah akhir). Akhirnya lintasan dibalik lagi. Opsi 2 membuat trek diam 0,6 detik dan memintasinya untuk jumlah waktu yang sama dengan trek asli. Semua filter dan penggunaannya didokumentasikan di sini: ffmpeg.org/ffmpeg-filters.html (walaupun saya harus setuju bahwa ini agak samar)
marekventur
3

Jawaban atas pertanyaan 2 adalah YA tegas! Saya sedang mencari fungsi yang sama dan saya akhirnya menulis skrip bash yang meminta durasi fade dalam hitungan detik dan menghitung frame awal untuk fade-out:

#!/bin/bash

f="$*" # all args
p="${f##*/}" # file
fn="${p%.*}" # name only
e="${p##*.}" # extension

echo
echo $f
echo $p
echo $fn
echo $e
echo

read -e -p "Number of seconds of fade-out: " -i 1 sec # prompt for fade duration in seconds

r=$(ffprobe -show_streams "$f" 2> /dev/null | grep r_frame_rate | head -1 | cut -d \= -f 2) # frame rate
let "frames = $r * $sec" # duration of fade as number of frames
echo $r
echo $sec
echo $frames
lf=$(ffprobe -show_streams "$f" 2> /dev/null | grep nb_frames | head -1 | cut -d \= -f 2) # total number of frames
let "lf = $lf - $frames" # initial frame to start fade at

ffmpeg -loglevel quiet -i "$f" -vf fade=out:$lf:$frames -r $r -vcodec libx264 -preset slow -crf 12 -bf 2 -flags +cgop -pix_fmt yuv420p -acodec copy "$fn $sec sec fade-out.$e"
open "$fn $sec sec fade-out.$e"

Fade memerlukan pengodean ulang sehingga menggunakan crfnilai rendah untuk libx264memberikan pengodean ulang berkualitas tinggi. Komentar harus menjelaskan yang lainnya.

hmj6jmh
sumber
Jawaban atas pertanyaan 2 adalah YA tegas! -> masih tidak. Q adalah Dapat ffmpeg secara otomatis mengetahui durasinya ... tetapi Anda telah menulis skrip yang menjalankan beberapa perintah ff * untuk melakukannya. Berguna untuk sistem * nix.
Gyan
Begitu, jadi Anda bersikeras bahwa jawaban ANDA MASIH benar? Jika Anda mengikuti skrip saya, Anda akan melihat bahwa itu memang automatically figure out the durationmenggunakan ffprobe, yang diinstal dengan ffmpeg. Siapa yang mengatakan sesuatu tentang pembatasan jumlah perintah atau *nix? Tampaknya OP menggunakan versi UNIX. Tidak .exedalam ffmpegperintah. Saya sendiri menggunakan OS Xyang dibangun UNIXtetapi tidak UNIX.
hmj6jmh
1
* Jika Anda mengikuti skrip saya, Anda akan melihat bahwa skrip itu memang secara otomatis mencari tahu * -> skrip Anda tidak, ffmpeg tidak.
Gyan
Tetapi ffprobemerupakan bagian integral dari ffmpegdistribusi. Anda memilih di nits untuk menyelamatkan IMO wajah.
hmj6jmh
Saya harus setuju bahwa sesuatu yang dilakukan oleh skrip bash bukanlah sesuatu yang secara otomatis dilakukan oleh ffmpeg. Tetapi jika ini berhasil, ini adalah cara untuk mengatasi masalah itu. Karenanya istilah "solusi". Saya tidak dapat mengatakan apakah itu berhasil karena saya, seperti kebanyakan orang di luar sana, tidak memiliki sistem bash atau unix. +1 untuk upaya ini.
ashleedawg