Para responder literalmente à pergunta do seu título: Você pode obter uma lista de quadros I com
ffprobe -select_streams v -show_frames <INPUT>
Você pode limitar ainda mais a saída necessária adicionando -show_entries frame=pkt_pts_time,pict_type
.
Para ver qual quadro está mais próximo (vem depois) de um determinado timestamp, primeiro você precisa descobrir todos os timestamps dos quadros-chave, por exemplo, com awk
.
Primeiro, defina a hora que você deseja procurar, por exemplo, 2: 30m, que é igual 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
Por exemplo, isso retornaria 150.400000
.
Observe que, ao usar -ss
antes de -i
, o FFmpeg localizará o quadro-chave anterior ao ponto de busca e atribuirá valores negativos de PTS a todos os quadros a seguir até atingir o ponto de busca. Um jogador deve decodificar, mas não exibir quadros com PTS negativo, e o vídeo deve começar com precisão.
Alguns jogadores não respeitam isso corretamente e exibem vídeo preto ou lixo. Nesse caso, o script acima pode ser usado para localizar o PTS do quadro-chave após seu ponto de busca e usá-lo para começar a procurar no quadro-chave. Isso, no entanto, não será preciso.
Observe que, se você quiser ser super preciso durante a pesquisa e manter a compatibilidade com muitos players, provavelmente deverá converter o vídeo em qualquer formato intra-only sem perdas, onde poderá cortar a qualquer momento e recodificar isto. Mas isso não será rápido.