ffmpeg bergabung dengan dua file mp4 dengan ffmpeg di baris perintah

29

Saya berhasil menggabungkan beberapa file menggunakan perintah berikut:

ffmpeg -f concat -i input.txt -codec copy output.mp4

Satu-satunya masalah dengan perintah ini adalah Anda perlu membaca filepath dari file teks yang disebut input.txt dengan konten berikut:

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

Apakah ada cara untuk mencapai tujuan yang sama tanpa harus membaca filepath dari file? Saya sudah mencoba yang berikut ini tanpa hasil:

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

Apakah saya harus menggunakan perintah yang berbeda?

Fabio Delarias
sumber
1
terkait: stackoverflow.com/questions/7333232/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

37

Pembaruan 2019:

Seperti disebutkan dalam komentar, Stack Overflow memiliki deskripsi yang bagus tentang opsi yang tersedia untuk penggabungan, serta diskusi tentang metode yang digunakan tergantung pada jenis file yang Anda gunakan:

Bagaimana cara menggabungkan dua file MP4 menggunakan FFmpeg?

Asli 2016 jawaban:

Anda harus dapat menggunakan metode protokol concat untuk menggabungkan file:

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

Selain itu, manual FFmpeg membahas metode khusus untuk file MP4, agar dapat digabungkan tanpa kehilangan, tetapi mengharuskan Anda membuat file sementara (atau bernama pipa):

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
Carson Darling
sumber
1
Perintah pertama bekerja untuk saya seperti mentega .. butuh 2 hingga 3 detik untuk menggabungkan file 6 mp4 saya menjadi file output (kira-kira 239 MB).
Sachin
22
Perintah pertama tidak berhasil untukku. Itu hanya menyalin file pertama.
Luis A. Florit
3
Ini tidak berfungsi, hanya menyalin file pertama ke output.mp4.
crmpicco
2
Rangkaian level file tidak berfungsi untuk MP4, jadi protokol concat tidak disarankan untuk format ini dan umumnya tidak akan berfungsi.
Logan
1
@brasofilo Terima kasih atas tautannya. Ini sudah lama ditunggu, tetapi saya memperbarui jawaban untuk mengarahkan orang ke arah itu.
Carson Darling
5

Anda dapat mengganti file dengan daftar dengan mengeluarkan daftar ke stdoutdan membaca daftar dari stdindengan ffmpeg:

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"
Qwertiy
sumber
Menggunakan ffmpeg versi 2.4.3-tessus di Mac OS 10.12.6, ini hanya menimbulkan kesalahan: "Opsi tidak dikenal 'protocol_whitelist'". Tanpa opsi protocol_whitelist, sepertinya hanya membuat salinan file MP4 kedua.
James
2

Tidak, tampaknya tidak ada cara untuk menggunakan demuxer concat ffmpeg pada satu baris perintah tanpa beberapa hack. Anda perlu membuat file teks input dengan daftar file. Saya pikir ini aneh sendiri, mungkin seseorang akan menambahkan ini ke FFMpeg di kemudian hari.

Jawaban yang diterima untuk pertanyaan ini menggunakan protokol concat, bukan demuxer concat yang diminta OP.

georgiecasey
sumber
1
Sebenarnya ada. stdin.
Qwertiy
protokol concat tidak boleh digunakan dengan MP4 atau format lain yang memerlukan header global.
Logan
1

Anda masih bisa melakukannya dalam skrip tanpa mengubah perintah. Sesuatu seperti:

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

$$ diperluas ke pid dari shell yang menjalankan perintah, sehingga nama file akan berbeda setiap kali Anda menjalankannya. jadi Anda bisa menggunakan $$. txt jika Anda mau. Atau sesuatu yang lain...

Anda juga dapat menggunakan file di sini untuk menambahkan banyak data ke file:

cat <<EOF >$$.tmp
file fname1
file fname2
file fname3
EOF

bash Substitusi berfungsi, jadi Anda dapat menentukan konten file secara terprogram, itu tidak harus diperbaiki. Saya menanamkan hal-hal semacam ini untuk loop sepanjang waktu. Akhirnya, pengalihan berfungsi sama seperti di atas, jadi> $ .tmp memotong kemudian menulis, >> $$. Tmp ditambahkan.

Richard Betel
sumber
2
Pertanyaannya adalah, "adakah cara untuk mencapai tujuan yang sama tanpa harus membaca filepath dari suatu file?" Yang telah Anda lakukan adalah menyediakan cara untuk menulis filepath ke file (sebelum membaca filepath dari file). Ini tidak menjawab pertanyaan.
Scott