I'm mencoba untuk menggabungkan dua file mp4 menggunakan ffmpeg. Aku ingin ini menjadi sebuah proses otomatis maka mengapa saya memilih ffmpeg. I'm mengkonversi dua file ke .ts file dan kemudian menggabungkan mereka dan kemudian mencoba untuk mengkodekan yang concated .ts file. File h264 dan aac dikodekan dan I'm berharap untuk menjaga kualitas yang sama atau sebagai dekat dengan aslinya mungkin.
ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4
Sayangnya saya'm mendapatkan pesan error berikut datang kembali dari ffmpeg selama encoding:
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s
av_interleaved_write_frame(): Error while opening file
Hal ini terjadi sekitar setengah jalan melalui pengkodean yang membuat saya berpikir bahwa anda dapat't concat dua .ts file bersama-sama dan memiliki pekerjaan.
FFmpeg memiliki tiga rangkaian metode:
ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
-filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mkv
Perhatikan bahwa metode ini melakukan re-encode.
$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
Untuk Windows:
(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
ffmpeg -i "concat:input1|input2" -codec copy output.mkv
Metode ini tidak bekerja untuk banyak format seperti MP4, karena sifat dari format tersebut dan sederhana rangkaian dilakukan dengan metode ini.
concat filter: Digunakan jika input anda tidak memiliki parameter yang sama (lebar, tinggi, dll), atau tidak sama format/codec, atau jika anda ingin melakukan penyaringan. (Anda bisa re-encode hanya input yang don't pertandingan sehingga mereka berbagi codec yang sama dan parameter lainnya, kemudian gunakan concat demuxer untuk menghindari re-encoding input lainnya).
concat demuxer: Gunakan ketika anda ingin menghindari re-encode dan format tidak mendukung file tingkat rangkaian (kebanyakan file yang digunakan oleh pengguna umum tidak mendukung file tingkat rangkaian).
concat protokol: dengan Menggunakan format yang mendukung file tingkat rangkaian (MPEG-1, MPEG-2 PS, DV). Jangan gunakan dengan MP4.
Jika ragu-ragu mencoba concat demuxer.
UNTUK FILE MP4
Untuk .mp4 file (yang saya peroleh dari DailyMotion.com: 50 menit tv episode, download hanya dalam tiga bagian, seperti tiga .mp4 video file) berikut ini adalah solusi yang efektif untuk Windows 7, dan tidak TIDAK melibatkan re-encoding file.
Saya mengubah nama file (seperti file1.mp4, file2.mp4, file3.mp4) sedemikian rupa sehingga bagian dalam urutan yang benar untuk melihat lengkap episode tv.
Kemudian saya dibuat sederhana batch file (concat.bat), dengan isi sebagai berikut:
:: Create File List
echo file file1.mp4 > mylist.txt
echo file file2.mp4 >> mylist.txt
echo file file3.mp4 >> mylist.txt
:: Concatenate Files
ffmpeg -f concat -i mylist.txt -c copy output.mp4
The batch file, dan ffmpeg.exe, keduanya harus dimasukkan ke dalam folder yang sama sebagai .file mp4 untuk bergabung. Kemudian jalankan file batch. Hal ini biasanya akan memakan waktu kurang dari sepuluh detik untuk menjalankan. .
Tambahan (2018/10/21) -
Jika apa yang anda cari adalah metode untuk menentukan semua file mp4 di folder saat ini tanpa banyak mengetik ulang, mencoba ini dalam Windows anda batch file bukan (HARUS sertakan pilihan -aman 0):
:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt
:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
Ini bekerja pada Windows 7, dalam sebuah batch file. Don't coba gunakan pada command line, karena hanya bekerja pada file batch!
Berikut ini's yang cepat (kurang dari 1 menit) dan lossless cara untuk melakukan hal ini tanpa perlu perantara file:
ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
"ls" berisi file-file untuk bergabung "perl" menciptakan rangkaian file on-the-fly ke pipa " aku" bagian memberitahu ffmpeg untuk membaca dari pipa
(catatan - file saya tidak punya ruang atau hal-hal aneh pada mereka - anda'll perlu sesuai shell-melarikan diri jika anda ingin melakukan ide ini dengan "keras" file).
Jika mereka tidak persis sama (100% sama codec, resolusi yang sama, jenis yang sama) MP4 file, maka anda harus trans-kode mereka menjadi perantara aliran pada awalnya:
ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts
// now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
*CATATAN*!: Output akan menjadi seperti file pertama ( dan kedua)
Aku mencoba untuk menggabungkan tiga .mp3
file audio menjadi satu .m4a
file dan ffmpeg ini perintah bekerja.
Masukan perintah:
ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a
Makna :
" -filter_complex concat=n=3:v=0:a=1" :
concat cara menggunakan media concatenate (bergabung) fungsi.
n cara konfirmasi jumlah total dari file input.
v berarti _has kumpulan gambar? gunakan 0 = tidak ada video, 1 = berisi video.
a berarti has audio? gunakan 0 = tidak ada audio, 1 = berisi audio.
-f berarti kekuatan mengatur file format (untuk melihat semua format yang didukung, gunakanffmpeg -format
)
vn cara menonaktifkan video (dan juga-
yang akan menonaktifkan audio jika tidak ingin)
-y cara menimpa file output (output file yang sudah ada).
Untuk info lebih lanjut: gunakan ffmpeg -jam penuh
cetak semua pilihan (termasuk semua format dan codec tertentu pilihan, sangat panjang)
Akhirnya saya menggunakan mpg sebagai intermediate format dan bekerja (CATATAN ini adalah berbahaya contoh, -qscale 0 akan re-encode video...)
ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4
Dokumentasi rinci tentang berbagai cara dari rangkaian di ffmpeg dapat ditemukan di sini]1.
Anda dapat menggunakan 'Concat filter' cepat untuk rangkaian.
Ia melakukan re-encode. Pilihan ini adalah yang terbaik ketika input memiliki berbagai format video/audio.
Untuk Menggabungkan 2 file:
ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4
Untuk Menggabungkan 3 file:
ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4
Ini bekerja sama serta beberapa jenis file input.
ini bekerja untuk saya (pada windows)
ffmpeg -i "concat:input1|input2" -codec copy output
contoh...
ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.mp4
Menggunakan beberapa kode python untuk melakukannya dengan sebanyak mp4 ada di folder (install python dari python.org, copy dan paste dan simpan kode ini ke file bernama mp4.py dan jalankan dari cmd dibuka di folder dengan python mp4.py dan semua mp4 di folder akan bersambung)
import glob
import os
stringa = ""
for f in glob.glob("*.mp4"):
stringa += f + "|"
os.system("ffmpeg -i \"concat:" + stringa + "\" -codec copy output.mp4")
Diambil dari posting di blog saya, ini adalah bagaimana saya melakukannya di python:
import os
import glob
def concatenate():
stringa = "ffmpeg -i \"concat:"
elenco_video = glob.glob("*.mp4")
elenco_file_temp = []
for f in elenco_video:
file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
elenco_file_temp.append(file)
print(elenco_file_temp)
for f in elenco_file_temp:
stringa += f
if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
stringa += "|"
else:
stringa += "\" -c copy -bsf:a aac_adtstoasc output.mp4"
print(stringa)
os.system(stringa)
concatenate()
Saya menemukan pipa operator tidak bekerja untuk saya ketika menggunakan opsi 3 untuk concat beberapa MP4s pada Mac pada jawaban yang diterima.
Berikut satu-liner bekerja pada Mac (High Sierra) untuk menggabungkan mp4s, tanpa perantara pembuatan berkas yang diperlukan.
ffmpeg -f concat -aman 0 -i <(for f in ./*.mp4; echo "file '$PWD/$f',"; selesai) -c copy output.mp4
berdasarkan rogerdpack's dan Ed999's tanggapan, saya've buat saya .sh versi
#!/bin/bash
[ -e list.txt ] && rm list.txt
for f in *.mp4
do
echo "file $f" >> list.txt
done
ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt
ia bergabung semua *.mp4
file dalam folder saat ini menjadi bergabung-out ekspres.mp4
diuji pada mac.
sehingga filesize adalah tepat jumlah 60 saya diuji file. Tidak boleh ada penurunan. Hanya apa yang saya butuhkan
Dari dokumentasi berikut: https://trac.ffmpeg.org/wiki/Concatenate
Jika anda memiliki file MP4, ini bisa menjadi losslessly bersambung dengan terlebih dahulu transcoding mereka untuk MPEG-2 transport stream. Dengan video H. 264 dan AAC audio, berikut dapat digunakan:
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
Pendekatan ini bekerja pada semua platform.
Saya membutuhkan kemampuan untuk merangkum ini di lintas platform script, jadi saya menggunakan lancar-ffmpeg
dan datang dengan solusi berikut:
const unlink = path =>
new Promise((resolve, reject) =>
fs.unlink(path, err => (err ? reject(err) : resolve()))
)
const createIntermediate = file =>
new Promise((resolve, reject) => {
const out = `${Math.random()
.toString(13)
.slice(2)}.ts`
ffmpeg(file)
.outputOptions('-c', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'mpegts')
.output(out)
.on('end', () => resolve(out))
.on('error', reject)
.run()
})
const concat = async (files, output) => {
const names = await Promise.all(files.map(createIntermediate))
const namesString = names.join('|')
await new Promise((resolve, reject) =>
ffmpeg(`concat:${namesString}`)
.outputOptions('-c', 'copy', '-bsf:a', 'aac_adtstoasc')
.output(output)
.on('end', resolve)
.on('error', reject)
.run()
)
names.map(unlink)
}
concat(['file1.mp4', 'file2.mp4', 'file3.mp4'], 'output.mp4').then(() =>
console.log('done!')
)
Berikut ini adalah script yang saya buat untuk menggabungkan beberapa GoPro mp4's ke 720p mp4. Harapan itu's bantuan.
#!/bin/sh
cmd="( "
for i; do
cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}
Untuk .mp4
file, saya menemukan itu bekerja lebih baik dan lebih cepat untuk menggunakan opensource alat baris perintah: mp4box
. Kemudian Anda dapat menggunakan cara ini:
mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4
Download di sini untuk sebagian besar platform: https://gpac.wp.imt.fr/mp4box/
Saya personnaly seperti tidak menciptakan file eksternal yang harus saya hapus setelah itu, jadi saya larutan berikut ini yang termasuk file penomoran daftar (seperti file_1_name, file_2_name, file_10_name, file_20_name, file_100_name
, ...)
#!/bin/bash
filesList=""
for file in $(ls -1v *.mp4);do #lists even numbered file
filesList="${filesList}${file}|"
done
filesList=${filesList%?} # removes trailing pipe
ffmpeg -i "concat:$filesList" -c copy $(date +%Y%m%d_%H%M%S)_merged.mp4
Setelah mencoba berbagai script di bawah ini bekerja untuk saya pada windows 10 powershell.
$files=Get-ChildItem -path e:\ -Filter *.mp4
$files| ForEach-Object {"file '$($_.FullName)'"}| Out-File -FilePath e:\temp.txt -Encoding ASCII
if (-not (test-path "e:\ffmpeg\bin\ffmpeg.exe")) {throw "e:\ffmpeg\bin\ffmpeg.exe needed"}
E:\ffmpeg\bin\ffmpeg.exe -safe 0 -f concat -i "e:\temp.txt" -c copy -bsf:v hevc_mp4toannexb -an e:\joined.mp4
# Conversion Cleanup
Remove-Item e:\temp.txt
Berikut dua baris pertama membuat file teks temp.txt yang memiliki konten berikut
file 'e:\first.mp4'
file 'e:\second.mp4'
3, 4 baris memeriksa jika ffmpeg tersedia di jalan dan menciptakan "bergabung.mp4"
Perbedaan utama dari jawaban yang lain adalah seperti di bawah ini
usage of -bsf:v hevc_mp4toannexb -an
untuk file mp4 di atas yang berhasil, anda mungkin perlu untuk menggunakan alternatif lain seperti di bawah ini tergantung pada encoding video.
h264_mp4toannexb
Semua mungkin Bitstream filter dapat ditemukan di https://ffmpeg.org/ffmpeg-bitstream-filters.html
Berikut ini's metode saya untuk bergabung dengan sebuah direktori penuh MP4 file menggunakan perintah substitusi dan concat video filter (ini akan re-encode) - pikir orang lain akan mendapatkan beberapa penggunaan ini satu-kapal, terutama jika anda memiliki banyak file (saya baru saja bergabung 17 file dalam satu gerakan):
ffmpeg $(for f in *.mp4 ; do echo -n "-i $f "; selesai) -filter_complex \ "$(i=0 ; for f in *.mp4 ; do echo -n "[$i:v] [$i:a] " ; i=$((i+1)) ; dilakukan \ && echo "concat=n=$i:v=1:=1 [v] [a]")" peta "[v]" peta " []" output.mp4
N. B. perintah ini bergabung dengan file anda dalam urutan di mana mereka're bernama (yaitu urutan yang sama seperti mereka're disajikan jika anda menjalankan ls *.mp4
) - dalam kasus saya, mereka masing-masing memiliki nomor trek, sehingga bekerja dengan baik.
Concat protokol yang dijelaskan di sini; https://trac.ffmpeg.org/wiki/Concatenate#protocol
Ketika diimplementasikan dengan menggunakan pipa bernama untuk menghindari file intermediate
Sangat cepat (baca: instan), tidak memiliki frame turun, dan bekerja dengan baik.
Ingat untuk menghapus bernama pipa file dan ingat untuk memeriksa jika video H264 dan AAC yang dapat anda lakukan dengan hanya ffmpeg -i namafile.mp4
(periksa h264 dan aac menyebutkan)