ffmpeg extrai imagens de vários pontos de tempo selecionados

1

Eu tenho um videofile e gosto de extrair uma única imagem de (cerca de 1500) timepoints específicos (expl. -ss 00:50, ss 00:67, ss: 01:70 ...)

Existe uma maneira de fazer isso? Eu tentei usar este comando:

ffmpeg.exe -ss 00:50 -i all.avi -t 00:00:01 -vframes 1 images-filename_%03d.png

Isso funciona muito bem para uma única foto, mas existe uma maneira de fazer isso com tantos pontos de tempo específicos?

Alguém tem um conselho?

    
por Jakob Winter 05.03.2018 / 15:49

2 respostas

1

Adicione vários timestamps como opções para o filtro select .

ffmpeg -i input.mp4 -filter:v \
"select='eq(t\,1.5)+eq(t\,10)+eq(t\,20)'" \
-vsync drop images-filename_%03d.png

Se o filtro for avaliado como verdadeiro, ele exibirá um quadro, portanto, a adição de verificações comparando o timestamp t do quadro com um timestamp em segundos (por exemplo, 1.5 ) fornecerá todos os quadros naqueles timestamps.

    
por 05.03.2018 / 19:24
1

Esta resposta melhora em @slhck 's answer , que pode não funcionar em algumas situações.

Uma sutileza na seleção de quadros por registro de data e hora (aproximado) é que o registro de data e hora real do quadro pode não ser exatamente igual ao registro de data e hora desejado. Por exemplo, em um vídeo com taxa de quadros de 23,98 (24000/1001) não há quadro com registro de data e hora 1.0 - o quadro mais próximo tem um valor de registro de data e hora de 1.001.

A expressão eq(t, specific_timepoint) é avaliada como verdadeira somente se t for exatamente igual a specific_timepoint . Portanto, ele não conseguirá selecionar um quadro na situação descrita acima. Como solução alternativa, podemos selecionar o primeiro quadro imediatamente após o registro de data e hora desejado, ou seja, o quadro cujo valor de registro de data e hora é maior ou igual ao ponto no tempo especificado, enquanto o registro de data e hora de seu quadro anterior era menor que o especificado. A expressão de seleção para um único momento será

lt(prev_pts * TB,timepoint) * gte(pts * TB,timepoint)

Note que eu deliberadamente não usei uma variante mais curta

between(timepoint, prev_pts*TB, pts*TB)

que é equivalente a

lte(prev_pts * TB,timepoint) * gte(pts * TB,timepoint)

como ele selecionaria dois quadros consecutivos quando o valor do registro de data e hora de (o primeiro) um deles corresponder exatamente ao valor do ponto no tempo especificado.

Exemplo de seleção dos quadros correspondentes ou imediatamente após os pontos no tempo 1.5, 10 e 20:

ffmpeg -i input.mp4 -filter:v \
    "select='lt(prev_pts*TB\,1.5)*gte(pts*TB\,1.5) \
            +lt(prev_pts*TB\,10)*gte(pts*TB\,10)   \
            +lt(prev_pts*TB\,20)*gte(pts*TB\,20)'" \
    -vsync drop images-filename_%03d.png
    
por 10.06.2018 / 09:25