FFmpeg divide il video e si ricollega


8

Sto cercando di utilizzare FFmpeg per dividere i video in base ad alcuni start_timee end_timeinput e sostituire quelli con altri file video. Ad esempio, per l'input 10 15dovrò sostituire i secondi EXACT 10 to 15con un altro video.

OK. Ciò che mi viene in mente è questo:

  1. Dividi prima il video (in questo caso, 0-10, 10-15 e 15-end)
  2. Sostituisci il 10-15 con l'altro video
  3. Unisci di nuovo tutti i video secondari

Prima domanda: è questa la soluzione migliore e più veloce? Abbiamo un comando più semplice o altri strumenti per sostituire un determinato periodo di tempo nel video con un altro video?

Seconda domanda: supponendo che FFmpeg sia la soluzione praticabile, quando uso semplicemente il comando ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4, il mio codice di elaborazione video non può leggere ed elaborare il file. Ho usato lo mediainfostrumento per confrontare i due file e ho notato differenze nelle dimensioni dell'intestazione mentre tutte le cose relative al codec video erano uguali. Ho notato che HEADER SIZE è diverso e che apparentemente sta causando il problema. Esistono modi per forzare anche la dimensione dell'intestazione (a parte i codec) essere la stessa?

AGGIORNAMENTO: ecco il .mp4file originale che funziona bene nell'emulatore.


Per prima cosa dovremmo affrontare il problema che menzioni nella tua seconda domanda. Si prega di mostrare il comando esatto che si sta utilizzando e l'output della riga di comando completo, non tagliato che si ottiene da ffmpeg. Mostra anche tutti gli errori che ricevi durante la lettura del file: sarebbe bene sapere esattamente quale sia il tuo "codice di elaborazione".
slhck,

@slhck il codice di elaborazione video è una base di codice enorme. Non posso condividerlo. È solo che per alcuni motivi viene letto il file originale ma non quello rigenerato. Posso comunque condividere il .mp4file originale , se necessario.
Ariana,

Ho usato lo strumento mediainfo per confrontare i due file e notare differenze nelle dimensioni e roba dell'intestazione
Ariana

Avere l'originale sarebbe di aiuto, ma non saremo in grado di risolvere il motivo per cui non può essere letto, temo, se si tratta di un codice interno.
slhck,

@slhck Ho caricato il file. La mia domanda è aggiornata
Ariana il

Risposte:


9

Utilizzo di trime concat- file di origine con codec diversi

Per questo, assicurati che i tuoi singoli file abbiano la stessa risoluzione e idealmente lo stesso framerate e il sottocampionamento cromatico ecc. Ciò eviterà errori o glitch durante la concatenazione.

Puoi fare tutto in una volta senza dividere il file, usando i filtri trime concat:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Qui, trimviene utilizzato per specificare le singole parti dei flussi video di input ( 0:v, 1:v) che in seguito si desidera concatenare. Queste parti sono nominate v0attraverso v2. (Il setptsfiltro reimposta i timestamp di queste singole parti su 0, necessario per la concatenazione). Successivamente, concateniamo le tre parti.

Se si desidera tagliare da un determinato timestamp fino alla fine, utilizzare trim=start=15invece di specificare l'intervallo.

Se i tuoi file hanno audio, devi tagliare quei flussi separatamente:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

In questo caso, il video e l'audio verranno ricodificati: assicurarsi di specificare gli obiettivi di qualità di output appropriati (ad esempio -crfper x264, x265 o libvpx-vp9). Puoi leggere di più su questo nel Wiki di FFmpeg, ad esempio per VP9 o H.264 .

Utilizzo di singoli segmenti

Se si desidera dividere i clip e successivamente rimontarli:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Se i file hanno audio, usa lo stesso approccio di cui sopra:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Ciò ricodificherà nuovamente il flusso video. È un po 'più semplice ma altrimenti dovrebbe essere equivalente al metodo sopra.

Utilizzando concatdemuxer

In linea di principio puoi anche provare a concatenare i flussi di bit senza ricodificarli, usando il demuxer concat. Crea un file chiamato concat.txte aggiungi le seguenti voci (corrispondenti ai video clip creati sopra):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Quindi concatenare questi singoli file:

ffmpeg -f concat -i concat.txt -c copy output.avi

Ciò richiede tuttavia che le tue clip abbiano lo stesso codec, risoluzione, framerate ecc., Quindi non funzionano con tutti i tipi di fonti eterogenee.

Utilizzando il concatprotocollo

Il suddetto tipo di concatenazione a livello di file può essere ottenuto anche utilizzando il concatprotocollo, con lo stesso tipo di vincoli di cui sopra (stesso codec, risoluzione, ecc.):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Per maggiori informazioni sulla concatenazione, leggi la rispettiva pagina Wiki di FFmpeg .


Questo sembra molto completo! Grazie. Li proverò!
Ariana,

Idk perché l'utilizzo del concatmetodo genera un errore:[concat @ 00000000025c2560] Line 1: unknown keyword 'part1.mp4 \\ text.txt: Invalid data found when processing input
Ariana,

Per "utilizzare singoli segmenti", vedo un arresto e un piccolo taglio dell'output. Esistono modi per risolvere questo problema?
Ariana,

Il metodo 1 funziona perfettamente. Una cosa: come possiamo specificare "fino alla fine" senza indicare un numero specifico (anziché 30 s)
Ariana,

1
Scusa, ho fatto un errore. Per il concatdemuxer, la sintassi era diversa. Riparato ora. Per arrivare fino alla fine, usare trim=start=15, consultare la documentazione del filtro trim: ffmpeg.org/ffmpeg-filters.html#trim - per quanto riguarda i problemi di temporizzazione, questo dipende dal materiale sorgente. Non ho avuto problemi a concatenare però con la clip che hai caricato.
Slhck,
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.