
Estoy intentando agregar una retícula a una transmisión de video en vivo y necesito que la retícula pueda moverse en función de algunos datos externos.
Puedo dibujar un cuadro en el video con ffmpeg:
ffmpeg -i input.mpg -vf drawbox=x=100:y=100:w=20:h=20:c=red output.mpg
(Tenga en cuenta que por ahora solo estoy probando con archivos de video, ya que eso simplifica algunas partes).
Sin embargo, no parece haber una manera de ajustar los valores x
y y
externamente una vez que se ha iniciado el comando. Esto sería ideal si hubiera una manera de leerlos fácilmente, por ejemplo, desde stdin o /dev/shm/reticle-pos.txt
, pero no puedo encontrar una manera de hacerlo.
Otra opción que probé es dibujar la retícula externamente con imagemagick y luego superponerla con 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
Sin embargo, esto no funciona, ya que parece que ffmpeg solo lee el archivo de imagen una vez, en lugar de cada cuadro.
¿Cómo puedo dibujar una retícula sobre la parte superior del video, de manera que me permita controlar la posición de la retícula?
Respuesta1
usando la opción de bucle:
ffmpeg -i input.mpg -loop 1 -f image2 -i /dev/shm/reticle.png -filter_complex overlay output.mpg
- ffmpeg lee reticle.png en cada fotograma utilizando la opción de bucle de image2 demuxer.
- Actualice rectile.png atómicamente escribiendo primero una nueva retícula en un archivo temporal y luego cambie el nombre a rectile.png.
- Para detalles:https://ffmpeg.org/ffmpeg-formats.html#image2-1
Respuesta2
He descubierto una manera de hacer esto. Probablemente no sea la mejor manera, pero funciona:
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
Esto funciona haciendo que imagemagick genere datos de píxeles sin procesar ( -size 1080x720 -depth 8 rgba:-
). Los datos de píxeles de cada cuadro se concatenan con el resto en una única secuencia de video sin procesar. Luego, ffmpeg puede leer esa transmisión de video sin procesar ( -f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0
) y superponerla al video principal.