Sto cercando di concatenare due file mp4 usando ffmpeg. Ho bisogno che questo sia un processo automatico, ecco perché ho scelto ffmpeg. Sto convertendo i due file in file .ts e poi concatenandoli e poi cercando di codificare quel file .ts concatenato. I file sono codificati in h264 e aac e spero di mantenere la qualità la stessa o il più vicino possibile all'originale.
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
Purtroppo sto ricevendo il seguente messaggio di errore da ffmpeg durante la codifica:
[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
Questo accade circa a metà strada durante la codifica, il che mi fa pensare che non è possibile concatenare due file .ts e farlo funzionare.
FFmpeg ha tre metodi di concatenazione:
sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh, sh;
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
Nota che questo metodo esegue un 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
per 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
Questo metodo non funziona per molti formati, incluso MP4, a causa della natura di questi formati e della concatenazione semplicistica eseguita da questo metodo.
Filtro concat: Usalo se i tuoi input non hanno gli stessi parametri (larghezza, altezza, ecc.), o non sono gli stessi formati/codec, o se vuoi eseguire qualche filtro. (Potresti ricodificare solo gli input che non corrispondono in modo che condividano lo stesso codec e altri parametri, quindi utilizzare il demuxer concat per evitare di ricodificare gli altri input).
concat demuxer: Da usare quando si vuole evitare una ricodifica e il proprio formato non supporta la concatenazione a livello di file (la maggior parte dei file usati dagli utenti generici non supporta la concatenazione a livello di file).
Protocollo concat: Utilizzare con formati che supportano la concatenazione a livello di file (MPEG-1, MPEG-2 PS, DV). Non usare con MP4.
Se sei in dubbio prova il demuxer concat.
Ho finito per usare mpg come formato intermedio e ha funzionato (NOTA questo è un esempio pericoloso, -qscale 0 ricodifica il 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
Ecco uno script che ho fatto per concatenare diversi mp4 GoPro in un mp4 a 720p. Spero che sia di aiuto.
#!/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}