Как нарисовать сетку поверх живого видео с помощью ffmpeg?
Я пытаюсь добавить сетку в прямую трансляцию видео, и мне нужно, чтобы сетка могла двигаться на основе внешних данных.
Я могу нарисовать прямоугольник на видео с помощью 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 {100..500..1}; 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 читает файл изображения только один раз, а не в каждом кадре.
Как нарисовать сетку поверх видео таким образом, чтобы я мог контролировать положение сетки?
2 ответа
Используя параметр цикла:
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
Я нашел способ сделать это. Это, вероятно, не самый лучший способ, но он работает:
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 ::: {100..500} \
| 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
) и наложить его на основное видео.