Tagliare con precisione i file video dalla riga di comando


22

Ho problemi a trovare un'applicazione cli che può prendere un file video (preferibilmente avi, mkv e mp4) e ritagliare clip molto brevi (2-6 secondi) con precisione nel tempo. Ho provato ffmpeg , mencoder , avidemux e mp4box ma tutti hanno tagliato i fotogrammi chiave che creano clip da 6+ secondi. Esiste uno strumento che ricodificherà il file di input e taglierà l'ora esatta o taglierà in modo impreciso, ricodificherà e poi taglierà con precisione?


Probabilmente dovrai ricodificare prima di tagliare per farlo bene. Probabilmente potresti accelerare le cose tagliando prima i fotogrammi chiave circostanti e ricodificando solo gli snippet.
Nifle,

4
Quale comando FFmpeg hai provato esattamente? Credo che se decodifichi il video prima (ovvero posiziona il -ssparametro dopo -i ), dovrebbe essere più preciso.
slhck,

1
Il trucco di FFmpeg ha funzionato! Non mi ero reso conto che l'ordine fosse così importante. È lo stesso per qualsiasi altro strumento?
curmil,

Risposte:


23

Taglio video con ffmpeg

È possibile accuratamente tagliare i video con FFmpeg. Dalla versione 2.5 è molto semplice. Ad esempio, ciò taglierebbe 10 secondi, a partire da 0 minuti, 3 secondi e 123 millisecondi.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

La posizione e il tempo possono essere in secondi o in hh:mm:ss[.xxx]forma.

Si noti che in questi esempi, il video verrà ricodificato mediante l' encoder x264 ; l'audio viene copiato.

È inoltre possibile utilizzare -toinvece di -tspecificare il punto finale anziché la durata. In questo caso, tuttavia, -toequivale a -t, poiché mettendo il -ssdavanti a -i, ffmpeg cercherà prima a quel punto e poi inizierà a produrre.

Vedi anche la voce Cercando wiki.


Taglio accurato per ffmpegversioni precedenti

Se hai una versione precedente di ffmpeg, quindi per una ricerca accurata, devi posizionare il -ssdopo -i, il che rende il processo di codifica un po 'più lento, perché l'intero video deve essere prima decodificato:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Qui -toe -tcomportati diversamente. -t 10creerebbe una clip di dieci secondi, mentre -to 10creerebbe una clip di sette secondi.


Invece di -c:v libx264 -c:a libfaacpensare che possiamo usare ciò -acodec copy -vcodec copyche dice a ffmpeg solo per rilevare e usare gli stessi codec del file originale. Qualcuno può confermare?
Baodad,

2
@Baodad Puoi, ma questo non taglierà con precisione . Quando si copiano flussi di bit video / audio, ffmpeg deve iniziare da un fotogramma chiave, che può essere semplicemente posizionato ad ogni secondo o anche più lontano.
Slhck,

Come superare l'errore "Unknown encoder 'libfaac'"?
Doug,

@Doug Scegli un codificatore diverso, per esempio -c:a aac -strict experimental. Questa è la soluzione più semplice.
slhck,

1

L'unico strumento da riga di comando di Linux che ho trovato finora, che può tagliare al frame esatto (o, con precisione del frame), è melt( sudo apt-get install melt).

Di 'che hai un inputvid.mp4- prima controlla le sue impostazioni di codifica con dire ffmpeg(qui, dico solo che voglio codificarlo di nuovo in -f mp4, ma come il file in /dev/nullmodo che l'output venga scartato; reindirizzo stderr in modo da poterlo passare attraverso - nota nel mezzo , il comando richiede e dovresti rispondere ycon INVIO, quindi il processo procede e scarica le informazioni utili; questo è con ffmpeg 3.3.3 su Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, quindi possiamo vedere le ffmpegscelte libx264e gli aacencoder per questo video; allora possiamo inserirlo per melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... e melttaglierà con il pezzo tra i fotogrammi 7235 e il 7349 in un nuovo file, cut.mp4. Quindi per verificare se i cut.mp4loop sono corretti, utilizzare di meltnuovo per riprodurlo due volte e riprodurlo su una finestra SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... ed ecco cosa ffmpegvede per questo file:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Le impostazioni di codifica video per cut.mp4sembrano identiche inputvid.mp4all'eccezione del bitrate video modificato da 389 kb / sa 526 kb / s, e anche le impostazioni di codifica audio sono quasi le stesse, tranne che la frequenza di campionamento è cambiata da 44100 a 48000 Hz; sebbene ciò possa essere regolato con:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... tuttavia, anche con questo, il bitrate finale del video per me finisce 337 kb / s. Tuttavia, i tagli vanno bene (e questo include l'audio) quando vengono riprodotti in un ciclo, quindi immagino che questo sia davvero accurato per i frame ...


1
meltsta ricodificando il video e utilizza le librerie FFmpeg sottostanti. Se si consente la ricodifica, ffmpeg può produrre lo stesso output.
Gyan,

Grazie @Gyan - non ne ero a conoscenza (soprattutto che meltutilizza le librerie FFmpeg), buono a sapersi!
sdaau,

melt sembra più facile da usare di ffmpeg, tutto ciò di cui abbiamo bisogno è un modo per specificare i tempi, in particolare i tempi in hr, min, sec form o hr, min, sec, ms, che li converte nel frame giusto.
barlop

0

Come Baodad ha detto nei commenti (inserisco perché non è facile da trovare se leggi rapidamente), l'approccio migliore è rilevare automaticamente gli encoder audio / video tramite ffmpeg, quindi:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • inizio @ 00: 05: 17.18
  • input = in.mp4
  • fermata @ 00: 06: 29.10
  • output = out.mp4

2
Questo non ricodifica e non fornisce la precisione del frame.
Andrea Lazzarotto,
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.