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

Я могу нарисовать прямоугольник на видео с помощью 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 ответа2

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#image2-1
0

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

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) и наложить его на основное видео.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .