Come unire più (più di due) video su Ubuntu?


39

Voglio unire i video in lotti di venti (20) ciascuno. Sto usando una macchina Linux. I video sono in formato mp4 e di qualità moderata. Alcuni addirittura mancano del flusso audio. Finora ho provato ffmpeg, mencoder, cvlc/vlce MP4Box. Voglio scrivere uno script da riga di comando per raggiungere questo obiettivo, poiché sto eseguendo l'elaborazione in batch.

Il problema principale è che alcune delle soluzioni che ho provato funzionano bene per due video, alcune funzionano bene per i video con streaming audio e altre ancora funzionano bene per alcuni altri sottogruppi del mio set di video. Tuttavia, non sono stato in grado di trovare una soluzione completa per questo compito.


2
Per favore, non fare la stessa domanda nei siti multi SE: superuser.com/questions/928548/…
Maythux

Potresti pubblicare in particolare ciò che hai provato finora?
ohaal,

1
@ohaal Ho provato a utilizzare vari metodi di concatenazione forniti ffmpeg, inclusi filtri e protocolli di file. Ho anche provato a usare la concatfunzione di cvlc/vlc. Ho anche provato la concatfunzione di mencoder. Tutti questi hanno funzionato parzialmente. Questo alla fine mi ha aiutato a risolvere la questione.
Dhruv Singal,

Sì, hai già menzionato gli strumenti, ciò che intendevo era i comandi reali che hai eseguito. Inoltre sarebbe bello se tu potessi includere il comando che ha finito per risolverlo per te (nella tua risposta), per i futuri visitatori.
ohaal,

Aah, vedo il tuo punto. Sfortunatamente, non posso elencare i comandi a causa del numero puro. Il comando che ha risolto il mio problema era questomelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal,

Risposte:


41

Sto usando mkvmergeper unire più file MP4 in uno singolo:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4

3
È meglio usare l'estensione .mkvper il file di output, in quanto è un contenitore Matroska indipendentemente dall'estensione fornita.
Haridsv,

Ecco come installare mkvmerge: tipsonubuntu.com
Morgoth

Solo questo comando mkvmerge funziona. Tutti quelli con ffmpeg falliscono almeno con l'audio spostato.
42n4

25

Puoi farlo usando ffmpeg:

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

riferimento e maggiori informazioni


2
Ho provato a farlo. Il problema è che non dà una risposta corretta. 1. Le tracce audio sono confuse. 2. C'è qualche disturbo nella traccia video.
Dhruv Singal,

L'ho usato per più di un campione, il risultato è di alta qualità, forse la tua qualità video sorgente è il problema?
Maythux,

Probabilmente hai ragione. Ciò ha risolto il problema: askubuntu.com/a/637179/420614
Dhruv Singal

2
Non utilizzare il protocollo concat per concatenare MP4. Funziona solo con determinati formati che la maggior parte degli utenti generici non incontra. Utilizzare invece il demuxer concat o il filtro concat .
Llogan,

Ho provato ffmpeg con 2 file mp4 di 30 minuti ciascuno. Ho ottenuto un file di output della durata di 7 ore.
Guus,

7

Ciò ha risolto il problema: https://stackoverflow.com/a/22324018/5014767

meltè un'ottima utility da riga di comando per questo. Ecco la pagina

Modifica dai commenti: il comando che ha risolto il mio problema era questo melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264


4

Ho scritto un piccolo script di shell per concatenare MP4 senza transcodifica 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

Ciò crea file intermedi in un contenitore MPEG e quindi li concatena in un MP4.


È importante notare che questo script fallirà se uno dei nomi di file contiene spazi o, in alcuni casi, caratteri speciali. Per il loop, è significativamente meglio usare solo for f in *.MP4senza usare ls. (Dovresti sempre evitare di utilizzare gli lsscript per un paio di motivi importanti; ci sono opzioni migliori.) Inoltre, usa le virgolette per le variabili a meno che tu non sia sicuro che non ci siano spazi o altri caratteri speciali, quindi "${f}"(o solo "$f") invece di non quotati $f.
Paddy Landau,

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")non funziona bene con nomi di file che sono 1, 2, 3 ... 10 ... 20. Finisce per analizzarli come 1, 10 ... 2, 20 ... ecc. Suggerisco che CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")questo assicurerà l'ordine .
tisaconundrum,

2

Crea un file files.txt con tutti i file che desideri concatenare nel seguente formato (le righe che iniziano con un # vengono ignorate):

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

Si noti che questi possono essere percorsi relativi o assoluti. Quindi puoi copiare o ricodificare i tuoi file in streaming:

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

0

La mia sceneggiatura, puramente in bashe ffmpeg. Ricodifica i file forniti su una riga di comando in uno.

Richiede che i file abbiano la stessa risoluzione. Accetta diverse rotazioni di metadati, ffmpeg concat:ma non è così.

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}"

0

Ho creato uno script Python che, usando moviepy , può concatenare anche sottosegmenti (utile se si desidera ad esempio rimuovere alcune parti da un video).

Usalo con:

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

-1

Oltre alla risposta di Maythux, da :

Alcuni contenitori multimediali (MPEG-1, MPEG-2 PS, DV) consentono di concatenare i video semplicemente concatenando i file che li contengono.

Vale a dire che i video da concatenare utilizzano uno dei suddetti contenitori di video (a cui aggiungerò MPEG-4 Parte 14 per esperienza personale), potresti semplicemente:

cat video1.ext video2.ext video3.ext > video4.ext

1
Ho provato questo, ma restituisce solo il primo video come output. Ho letto da qualche parte che non funziona, anche se non ricordo la logica alla base di questo.
Dhruv Singal,

@DhruvSingal Sì, posso confermarlo, l'ho provato su due video MP4 con la stessa identica codifica video / audio e come te ho potuto sfogliare solo il primo video. Il che sembra ragionevole, tuttavia sono abbastanza sicuro di averlo già fatto una volta con un paio di video MP4. Forse la memoria non sta funzionando bene qui, o ci sono altri requisiti per farlo funzionare. Voglio fare delle ricerche su questo poiché sono anche interessato, se trovo qualcosa aggiornerò la risposta e ti
lascerò

In qualche modo abbiamo bisogno di cambiare i metadati all'inizio del primo video per includere l'intera lunghezza del film combinato, e probabilmente altre cose. Solo pochi file mpeg4 mi permettono di vedere i metadati ..
Ken Mollerup,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.