Использование FFMPEG: как сделать обнаружение изменения сцены? с таймкода?

на основе этой статьи кажется, что можно использовать FFMPEG для обнаружения изменения сцены в видео: http://www.luckydinosaur.com/u/ffmpeg-scene-change-detector

теперь у меня есть видео, которое отображает текст книги и когда текст (слово или предложение) говорят она подсвечивается. Что-то вроде этой аудиокниги:https://youtu.be/lA7L6ZNVKjc

Мне нужно знать метку времени, когда текст подсвечивается (следовательно, изменение сцены), это позволит мне добавить метки времени на моем видео youtube, чтобы слушателям было легче перемещаться по аудиокниге.

Что такое магия командная строка, которая сделает это?

большое спасибо!

3 ответов


объединение сцены фильтр (для обнаружения изменения сцены) и showinfo фильтр должен достичь того, чего вы хотите:

ffmpeg -i input.flv  -filter:v "select='gt(scene,0.4)',showinfo"  -f null  - 2> ffout

эта команда извлекает все кадры, которые отличаются от предыдущего кадра более чем (gt) 0.4 (по шкале от 0 to 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 не должен выводить такие плохо сформированные временные метки.


У меня нет представителя, чтобы опубликовать комментарий к вышеуказанному ответу, но я хотел указать, что grep, размещенный как @ckoehn, так и @keypulsations, будет захватывать только временные метки, которые являются плавающей точкой. Чтобы захватить как с плавающей запятой, так и целочисленные метки времени, используйте следующее регулярное выражение

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep -E '[0-9]+(?:\.[0-9]*)?' -o > timestamps

Я пробовал ответ @ckoehn, и он работал, пока не перестал работать, Звездочка в последнем grep вызывала проблемы. Чтобы избежать этого, я рекомендую использовать двойные кавычки в предложениях grep, таких как:

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep "[0-9.]*" -o > timestamps