Ответ 1
Объединение фильтра сцены (для обнаружения изменений сцены) и фильтра showinfo должно достичь того, что вы хотите:
ffmpeg -i input.flv \
-filter:v "select='gt(scene,0.4)',showinfo" \
-f null \
- 2> ffout
Эта команда извлекает все кадры, которые отличаются от предыдущего кадра более чем на (gt
) 0.4
(в масштабе от 0
до 1
). Для этих кадров информация распечатывается (showinfo
) следующим образом
[Parsed_showinfo_1 @ 0x2d85e60] n: 0 pts:2537204 pts_time:2.5372 pos: 2998114 fmt:rgb24 sar:1/1 s:1920x1200 i:P iskey:1 type:I checksum:5616582E plane_checksum:[5616582E]
Теперь вам нужно только извлечь метку времени. Я думаю, что вы заинтересованы в pts_time
. Вы можете сделать это так:
grep showinfo ffout | grep pts_time:[0-9.]* -o | grep [0-9.]* -o > timestamps
Это даст вам список всех временных меток:
2.5372
4.37799
6.65301
8.09344
Чтобы этот подход работал, у вас должна быть версия FFmpeg, которая реализует обнаружение сцены. Кроме того, вы должны выбрать подходящее значение для порога (0.4
в первой команде). Вы можете попытаться найти оптимальный порог, извлекая кадры для различных пороговых значений (а затем проверяя кадры вручную), как это
ffmpeg -i input.flv \
-filter:v "select='gt(scene,0.1)',showinfo" \
-vsync 0 frames/%05d.jpg
Просто для пояснения: grep [0-9.]*
Не исключает целых чисел, как указано в другом ответе. Он соответствует любой последовательности символов, состоящей из цифр и точек, но он также соответствует не числам, таким как "4.4.4". Однако ffmpeg не должен выводить такие плохо сформированные временные метки.