Come get timbro di tempo del keyframe più vicino prima di un dato timestamp con FFmpeg?

Voglio un command di ricerca FFmpeg che sia veloce e preciso. Ho trovato questo .

La soluzione è che si applica -ss sia per input (ricerca veloce) e output (ricerca accurata). Ma: se la ricerca degli input non è precisa, come possiamo essere certi che la posizione di ricerca sia accurata?


Ad esempio: se vogliamo cercare 00:03:00, il command è qualcosa di simile:

 ffmpeg -ss 00:02:30 -i <INPUT> ... -ss 00:00:30 <OUTPUT> 

Le prime -ss cercheranno altrove, non 00:02:30 , dicono 00:02:31 . E dopo aver applicato la seconda ricerca, il risultato finale sarebbe 00:03:01non quello che vogliamo. È corretto?

Dove cerca il primo? Cerca il fotogramma chiave più vicino a 00:02:30 ?

Se è così, ecco il mio pensiero – mi correggo se sbaglio: dopo la prima ricerca, otteniamo il timestamp del risultato (in questo esempio: 00:02:31 ), allora 00:02:31 seconda ricerca con il tempo appropriato, in questo caso 00:00:29 .

La domanda è: come otteniamo il timbro temporale del primo risultato di ricerca?

Per rispondere letteralmente alla domanda del tuo titolo: Puoi get un elenco di I-frame con

 ffprobe -select_streams v -show_frames <INPUT> 

Puoi ulteriormente limitare questo valore all'output necessaria aggiungendo -show_entries frame=pkt_pts_time,pict_type .

Per vedere quale fotogramma è più vicino (viene dopo) un certo timestamp, devi prima trovare tutti i timestamp dei fotogrammi chiave, ad esempio con awk .

In primo luogo, definire l'ora che si desidera cercare, ad esempio, 2: 30m che equivale a 150s.

 ffprobe -select_streams v -show_frames -show_entries frame=pkt_pts_time,pict_type -v quiet in.mp4 | awk -F= ' /pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } } /pkt_pts_time/ { if (i && ($2 >= 150)) print $2; } ' | head -n 1 

Ad esempio, questo restituirà 150.400000 .


Ora, quando si utilizza -ss prima di -i , FFmpeg cerca fino a quel punto e poi utilizza il seguente fotogramma chiave che trova. Programmaticamente sarebbe un incubo implementare qualsiasi altro comportmento, vale a dire restituendo un keyframe prima di quello.

Quindi, utilizzare lo script sopra per scoprire il PTS del fotogramma chiave dopo il timestamp e utilizzarlo per get più accurate ricerche in un secondo momento.

La vera questione è perché tutto questo avrebbe davvero importnza. Se volete essere super precisi mentre cercate, probabilmente dovresti convertire il video in qualsiasi forma senza perdita, solo intra-in cui potresti tagliare in qualsiasi punto.