Как нарисовать сетку поверх живого видео с помощью ffmpeg?

622
AJMansfield

Я пытаюсь добавить сетку в прямую трансляцию видео, и мне нужно, чтобы сетка могла двигаться на основе внешних данных.

Я могу нарисовать прямоугольник на видео с помощью ffmpeg:

ffmpeg -i input.mpg -vf drawbox=x=100:y=100:w=20:h=20:c=red output.mpg 

(Обратите внимание, что сейчас я просто тестирую видеофайлы, так как это упрощает некоторые его части.)

Тем не менее, как представляется, не быть способ регулировки xи yзначения извне после запуска команды. Это было бы идеально, если бы был способ легко прочитать их, например, из stdin или /dev/shm/reticle-pos.txt, но я не могу найти способ сделать это.

Другой вариант, который я пробовал, - нарисовать сетку снаружи с помощью imagemagick, а затем наложить ее на ffmpeg:

while true; do for x in ; do convert -size 1080x720 xc:none -fill none -stroke red -strokewidth 2 \ -draw "ellipse $x,100 10,10 0,360" -scale 1080x720 /dev/shm/newreticle.png cp /dev/shm/newreticle.png /dev/shm/reticle.png sleep 0.001 done done &  ffmpeg -i input.mpg -i /dev/shm/reticle.png -filter_complex overlay output.mpg 

Однако это не работает, так как кажется, что ffmpeg читает файл изображения только один раз, а не в каждом кадре.

Как нарисовать сетку поверх видео таким образом, чтобы я мог контролировать положение сетки?

0

2 ответа на вопрос

2
Rens

используя параметр цикла:

ffmpeg -i input.mpg -loop 1 -f image2 -i /dev/shm/reticle.png -filter_complex overlay output.mpg 
  • ffmpeg читает reticle.png в каждом кадре с помощью параметра цикла демультиплексора image2.
  • Обновите rectile.png атомарно, сначала записав новую сетку во временный файл, а затем переименуйте в rectile.png.
  • Для получения подробной информации: https://ffmpeg.org/ffmpeg-formats.html#image2-1
0
AJMansfield

Я нашел способ сделать это. Это, вероятно, не лучший способ, но он работает:

reticle(){ convert -size 1080x720 xc:none \ -fill none -stroke red -strokewidth 2 -draw "ellipse $1,$2 10,10 0,360" \ -size 1080x720 -depth 8 rgba:- } export -f reticle  parallel -k reticle {} 100 ::: \ | ffmpeg \ -i input.mpg \ -f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0 \ -filter_complex overlay \ -y -c libx264 output.mpg 

Это работает, когда imagemagick выводит необработанные данные пикселей ( -size 1080x720 -depth 8 rgba:-). Пиксельные данные для каждого кадра объединяются вместе с остальными в один необработанный видеопоток. Затем ffmpeg может читать этот необработанный видеопоток ( -f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0) и накладывать его на основное видео.

Похожие вопросы