¿Cómo concatenar dos archivos MP4 usando FFmpeg? [cerrado]
Estoy intentando concatenar dos archivos mp4 usando ffmpeg. Necesito que esto sea un proceso automático, por eso elegí ffmpeg. Estoy convirtiendo los dos archivos en .ts
archivos y luego los concateno y luego intento codificar ese .ts
archivo concatenado. Los archivos están h264
codificados aac
y espero mantener la calidad igual o lo más cerca posible del original.
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
Desafortunadamente, recibo el siguiente mensaje de error de ffmpeg durante la codificación:
[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
Esto sucede aproximadamente a la mitad de la codificación, lo que me hace pensar que no se pueden combinar dos archivos .ts y hacerlo funcionar.
FFmpeg tiene tres métodos de concatenación:
1. filtro de vídeo concat
Utilice este método si sus entradas no tienen los mismos parámetros (ancho, alto, etc.), o no tienen los mismos formatos/códecs, o si desea realizar algún filtrado.
Tenga en cuenta que este método realiza una recodificación de todas las entradas. Si desea evitar la recodificación, puede volver a codificar solo las entradas que no coinciden para que compartan el mismo códec y otros parámetros, luego use el demuxer concat para evitar volver a codificar todo.
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
2. demultiplexor concat
Utilice este método cuando desee evitar una nueva codificación y su formato no admita la concatenación a nivel de archivo (la mayoría de los archivos utilizados por los usuarios generales no admiten la concatenación a nivel de archivo).
$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
Para ventanas :
(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
o
(for %i in (*.mp4) do @echo file '%i') > list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
3. protocolo concat
Utilice este método con formatos que admitan la concatenación a nivel de archivos (MPEG-1, MPEG-2 PS, DV). No lo use con MP4.
ffmpeg -i "concat:input1|input2" -codec copy output.mkv
Este método no funciona para muchos formatos, incluido MP4, debido a la naturaleza de estos formatos y a la concatenación física simplista que realiza este método. Es el equivalente a simplemente unir los archivos sin formato.
Si tiene dudas sobre qué método utilizar, pruebe el demuxer concat.
Ver también
- Preguntas frecuentes de FFmpeg: ¿Cómo puedo unir archivos de vídeo?
- FFmpeg Wiki: Cómo concatenar (unir, fusionar) archivos multimedia
PARA ARCHIVOS MP4
Para los archivos .mp4 (que obtuve de DailyMotion.com: un episodio de televisión de 50 minutos, descargable sólo en tres partes, como tres archivos de vídeo .mp4), la siguiente fue una solución eficaz para Windows 7 y NO implica volver a codificar el archivo. archivos.
Cambié el nombre de los archivos (como file1.mp4 , file2.mp4 , file3.mp4 ) de modo que las partes estuvieran en el orden correcto para ver el episodio de televisión completo.
Luego creé un archivo por lotes simple (concat.bat), con el siguiente contenido:
:: 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
El archivo por lotes y ffmpeg.exe deben colocarse en la misma carpeta que los archivos .mp4 que se van a unir. Luego ejecute el archivo por lotes. Normalmente tardará menos de diez segundos en ejecutarse.
.
Anexo (21/10/2018) -
Si lo que estaba buscando es un método para especificar todos los archivos mp4 en la carpeta actual sin tener que volver a escribir mucho, pruebe esto en su archivo por lotes de Windows ( DEBE incluir la opción -safe 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
Esto funciona en Windows 7, en un archivo por lotes. ¡No intentes usarlo en la línea de comando, porque solo funciona en un archivo por lotes!
A continuación se concatenan tres .mp3
archivos en uno .m4a
.
ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex "concat=n=3:v=0:a=1" -vn -y input.m4a
Significados de las opciones
-filter_complex "concat=n=3:v=0:a=1
concat
: concatenar filtros uniendo flujosn
: recuento de segmentos de entrada (= transmisiones de audio y video sincronizadas o transmisiones de solo audio o solo video)v
: recuento de secuencias de vídeo de salidaa
: recuento de flujo de audio de salida-vn
: deshabilitar video (-an
deshabilitaría audio)-y
: sobrescribe los archivos de salida sin avisos
Consulte man ffmpeg
o ffmpeg -h full
para imprimir todas las opciones (incluidas todas las opciones específicas de formato y códec).
para archivos MP4:
Si no son exactamente iguales (100% el mismo códec, la misma resolución, el mismo tipo) archivos MP4, primero debes transcodificarlos en secuencias intermedias:
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
¡NOTA! : La salida será como el primer archivo (y no un segundo)
Aquí hay una forma rápida (tarda menos de 1 minuto) y sin pérdidas de hacer esto sin necesidad de archivos intermedios:
ls Movie_Part_1.mp4 Movie_Part_2.mp4 | \
perl -ne 'print "file $_"' | \
ffmpeg -f concat -i - -c copy Movie_Joined.mp4
"ls" contiene los archivos para unir. "Perl" crea el archivo de concatenación sobre la marcha en una tubería. La parte "-i -" le dice a ffmpeg que lea desde la tubería.
(nota: mis archivos no tenían espacios ni cosas raras; necesitarás un escape de shell adecuado si quieres hacer esta idea con archivos "duros").