İki mp4 dosyasını ffmpeg kullanarak birleştirmeye çalışıyorum. Bunun otomatik bir işlem olmasına ihtiyacım var, bu yüzden ffmpeg'i seçtim. İki dosyayı .ts dosyalarına dönüştürüyorum ve sonra bunları birleştiriyorum ve sonra bu birleştirilmiş .ts dosyasını kodlamaya çalışıyorum. Dosyalar h264 ve aac kodlu ve kaliteyi aynı veya mümkün olduğunca orijinaline yakın tutmayı umuyorum.
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
Ne yazık ki kodlama sırasında ffmpeg'den aşağıdaki hata mesajını alıyorum:
[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
Bu, kodlamanın yaklaşık yarısında gerçekleşiyor ve bu da bana iki .ts dosyasını bir araya getirip çalışmasını sağlayamayacağınızı düşündürüyor.
FFmpeg'in üç birleştirme yöntemi vardır:
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
Bu yöntemin bir yeniden kodlama gerçekleştirdiğini unutmayın.
$ 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
Windows için:
(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
Bu yöntem, MP4 dahil olmak üzere birçok formatta, bu formatların doğası ve bu yöntemle gerçekleştirilen basit birleştirme nedeniyle çalışmaz.
concat filtresi: Girdileriniz aynı parametrelere (genişlik, yükseklik, vb.) sahip değilse veya aynı formatlar/kodekler değilse ya da herhangi bir filtreleme yapmak istiyorsanız kullanın. (Aynı codec'i ve diğer parametreleri paylaşmaları için yalnızca eşleşmeyen girdileri yeniden kodlayabilir, ardından diğer girdileri yeniden kodlamaktan kaçınmak için concat demuxer'ı kullanabilirsiniz).
concat demuxer: Yeniden kodlamadan ve formatınızdan kaçınmak istediğinizde kullanın dosya düzeyinde birleştirmeyi desteklemez (genel kullanıcılar tarafından kullanılan çoğu dosya dosya düzeyinde birleştirmeyi desteklemez).
concat protokolü: Dosya düzeyinde birleştirmeyi destekleyen formatlarla kullanın (MPEG-1, MPEG-2 PS, DV). MP4 ile kullanmayın.
Şüpheniz varsa concat demuxer'ı deneyin.
Sonunda ara format olarak mpg kullandım ve çalıştı (NOT bu tehlikeli bir örnektir, -qscale 0 videoyu yeniden kodlayacaktır...)
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
İşte birkaç GoPro mp4'ünü 720p mp4 olarak birleştirmek için yaptığım bir komut dosyası. Umarım yardımcı olur.
#!/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}