ffmpeg unisce due file mp4 con ffmpeg sulla riga di comando


29

Posso unire con successo più file usando il seguente comando:

ffmpeg -f concat -i input.txt -codec copy output.mp4

L'unico problema con questo comando è che devi leggere i percorsi dei file dal file di testo chiamato input.txt con il seguente contenuto:

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

C'è un modo per raggiungere lo stesso obiettivo senza dover leggere i percorsi dei file da un file? Ho provato quanto segue senza fortuna:

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

Devo usare un comando diverso?


Risposte:


37

Aggiornamento 2019:

Come accennato nei commenti, Stack Overflow ha una grande descrizione delle opzioni disponibili per la concatenazione, nonché una discussione su quale metodo usare in base ai tipi di file che stai usando:

Come concatenare due file MP4 usando FFmpeg?

Risposta originale 2016:

Dovresti essere in grado di utilizzare il metodo del protocollo concat per combinare i file:

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

Inoltre, il manuale di FFmpeg discute un metodo specifico per i file MP4, al fine di concatenarli senza perdita di dati, ma richiede la creazione di file temporanei (o named pipe):

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

1
Il primo comando ha funzionato per me come un burro ... ci sono voluti dai 2 ai 3 secondi per concatenare i miei file da 6 mp4 nel file di output (239 MB circa).
Sachin,

22
Il primo comando non ha funzionato per me. Ha appena copiato il primo file.
Luis A. Florit,

3
Questo non funziona, ha appena copiato il primo file output.mp4.
crmpicco,

2
La concatenazione a livello di file non funziona per MP4, quindi il protocollo concat non è raccomandato per questo formato e generalmente non funzionerà.
Llogan,

1
@brasofilo Grazie per il link. È atteso da tempo, ma ho aggiornato la risposta per indirizzare le persone in quella direzione.
Carson Darling,

5

È possibile sostituire il file con l'elenco emettendo l'elenco stdoute leggendo l'elenco stdinda ffmpeg:

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"

Utilizzando ffmpeg versione 2.4.3-tessus su Mac OS 10.12.6, viene generato un errore: "Opzione non riconosciuta 'protocol_whitelist'". Senza l'opzione protocol_whitelist, sembra solo fare una copia del secondo file MP4.
James,

2

No, sembra che non ci sia modo di usare il demuxer concat ffmpeg su una singola riga di comando senza alcun hack. È necessario creare il file di testo di input con l'elenco dei file. Ho pensato che fosse strano, forse qualcuno lo aggiungerà a FFMpeg in un secondo momento.

La risposta accettata a questa domanda utilizza il protocollo concat, non il demuxer concat che è ciò che l'OP ha chiesto.


1
In realtà c'è. stdin.
Qwertiy,

il protocollo concat non deve essere utilizzato con MP4 o altri formati che richiedono un'intestazione globale.
Llogan,

1

Potresti ancora farlo in uno script senza cambiare il comando. Qualcosa di simile a:

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

$$ si espande nel pid della shell che esegue il comando, quindi il nome del file sarà diverso ogni volta che lo esegui. quindi puoi usare $$. txt se preferisci. O qualcos'altro...

Inoltre, puoi usare qui i file per aggiungere un mucchio di dati al file:

cat <<EOF >$$.tmp
file fname1
file fname2
file fname3
EOF

bash La sostituzione delle variabili funziona, quindi puoi determinare programmaticamente il contenuto del file, non è necessario correggerlo. Ho sempre inserito questo tipo di roba nei loop. Infine, il reindirizzamento funziona come sopra, quindi> $$. Tmp tronca e poi scrive, >> $$. Tmp si aggiunge.


2
La domanda si pone: "esiste un modo per raggiungere lo stesso obiettivo senza dover leggere i percorsi dei file da un file?" Tutto quello che hai fatto è fornire un modo per scrivere i percorsi dei file in un file (prima di leggere i percorsi dei file dal file). Questo non risponde alla domanda.
Scott,
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.