¿Cómo fusionar múltiples (más de dos) videos en Ubuntu?

39

Quiero fusionar videos en lotes de veinte (20) cada uno. Estoy ejecutando una máquina Linux. Los videos están en formato mp4 y calidad moderada. Algunos incluso tienen la secuencia de audio que falta. Hasta ahora he intentado ffmpeg, mencoder, cvlc/vlcy MP4Box. Quiero escribir un script de línea de comando para lograr esto, ya que estoy haciendo un procesamiento por lotes.

El problema principal es que algunas de las soluciones que probé funcionan bien para dos videos, algunas funcionan bien para videos con transmisión de audio y otras funcionan bien para algún otro subconjunto de mi conjunto de videos. Sin embargo, no he podido encontrar una solución integral para esta tarea.

Dhruv Singal
fuente
2
Por favor no pida misma pregunta en sitios múltiples SE: superuser.com/questions/928548/...
Maythux
¿Podría publicar específicamente lo que ha probado hasta ahora?
ohaal
1
@ohaal Intenté usar varios métodos de concatenación ffmpeg, incluidos filtros y protocolos de archivo. También intenté usar la concatfunción de cvlc/vlc. También probé la concatfunción de mencoder. Todo esto funcionó parcialmente. Esto finalmente me ayudó a resolver el asunto.
Dhruv Singal
Sí, ya mencionaste las herramientas, lo que quise decir fueron los comandos reales que ejecutaste. También sería genial si pudiera incluir el comando que terminó resolviéndolo por usted (en su respuesta), para futuros visitantes.
ohaal
Aah, entiendo tu punto. Desafortunadamente, no puedo enumerar los comandos debido al gran número. El comando que resolvió mi problema fue estemelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal

Respuestas:

41

Estoy usando mkvmergepara unir múltiples archivos MP4 en uno solo:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4
Huso Szabolcs
fuente
3
Es mejor usar la extensión .mkvpara el archivo de salida, ya que es un contenedor Matroska independientemente de la extensión que le dé.
haridsv
Aquí se explica cómo instalar mkvmerge: tipsonubuntu.com
Morgoth
Solo este comando mkvmerge funciona. Todos los ffmpeg fallan con audio desplazado al menos.
42n4
25

Puedes hacerlo usando ffmpeg:

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

referencia y más información

Maythux
fuente
2
Intenté hacer eso. El problema con esto es que no da una salida adecuada. 1. Las pistas de audio están confusas. 2. Hay alguna perturbación en la pista de video.
Dhruv Singal
Lo utilicé para más que una muestra, el resultado es de alta calidad, ¿tal vez la calidad del video de origen sea el problema?
Maythux
Probablemente tengas razón. Esto resolvió el problema: askubuntu.com/a/637179/420614
Dhruv Singal
2
No use el protocolo concat para concatenar MP4. Solo funciona con ciertos formatos que la mayoría de los usuarios generales no encuentran. Utilice concat demuxer o concat filter en su lugar.
llogan
Intenté ffmpeg con 2 archivos mp4 de 30 minutos cada uno. Tengo un archivo de salida con una duración de 7 horas.
Guus
7

Esto resolvió el problema: https://stackoverflow.com/a/22324018/5014767

meltes una gran utilidad de línea de comando para esto. Aqui esta la pagina

Editar de comentarios: el comando que resolvió mi problema fue este melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264

Dhruv Singal
fuente
4

Escribí un pequeño script de shell para concatenar MP4s sin transcodificar usando ffmpeg.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

Esto crea archivos intermedios en un contenedor MPEG y luego los concatena en un MP4.

RawwrBag
fuente
Es importante tener en cuenta que este script fallará si alguno de los nombres de archivo contiene espacios o, en algunos casos, caracteres especiales. Para el ciclo, es significativamente mejor usar solo for f in *.MP4sin usar ls. (Siempre debe evitar el uso lsen scripts por un par de razones importantes; hay mejores opciones). Además, use comillas para las variables a menos que esté seguro de que no hay espacios u otros caracteres especiales, por lo que "${f}"(o simplemente "$f") en lugar de sin comillas $f.
Paddy Landau
CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")no funciona bien con nombres de archivo que son 1, 2, 3 ... 10 ... 20. Termina analizándolos como 1, 10 ... 2, 20 ... etc. Sugiero que CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")esto garantizará el orden .
tisaconundrum
2

Cree un archivo files.txt con todos los archivos que desea concatenar en la siguiente forma (se ignoran las líneas que comienzan con un #):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Tenga en cuenta que estos pueden ser caminos relativos o absolutos. Luego puede transmitir, copiar o volver a codificar sus archivos:

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
ShaDeRzz
fuente
0

Mi guión, puramente en bashy ffmpeg. Vuelve a codificar los archivos dados en una línea de comando en uno.

Requiere que los archivos tengan la misma resolución. Acepta diferentes rotaciones de metadatos, que ffmpeg concat:no lo hacen.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"
Victor Sergienko
fuente
0

Creé un script de Python que, usando moviepy , puede concatenar también subsegmentos (útil si desea, por ejemplo, eliminar algunas partes de un video).

Úselo con:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>
Antonello
fuente
-1

Además de la respuesta de Maythux, de :

Algunos contenedores multimedia (MPEG-1, MPEG-2 PS, DV) permiten concatenar video simplemente concatenando los archivos que los contienen.

Es decir, los videos que se van a concatenar usan uno de los contenedores de video mencionados anteriormente (al que agregaré MPEG-4 Parte 14 para una experiencia personal), simplemente podría:

cat video1.ext video2.ext video3.ext > video4.ext
kos
fuente
1
Intenté esto pero solo devuelve el primer video como salida. Leí en alguna parte que no funciona, aunque no recuerdo la razón detrás de esto.
Dhruv Singal
@DhruvSingal Sí, puedo confirmar esto, lo he intentado en dos videos MP4 con exactamente la misma codificación de video / audio y, como usted, solo pude navegar por el primer video. Lo cual parece razonable, sin embargo, estoy bastante seguro de que he hecho esto una vez con un par de videos MP4. Quizás la memoria no esté funcionando bien aquí, o hay otros requisitos para que esto funcione. Quiero investigar sobre esto ya que también estoy interesado, si encuentro algo actualizaré la respuesta y te dejaré un comentario
kos
De alguna manera, necesitamos cambiar los metadatos al comienzo del primer video para abarcar toda la duración de la película combinada, y probablemente otras cosas. Solo unos pocos archivos mpeg4 me permiten ver los metadatos ..
Ken Mollerup