Como desenhar uma retícula sobre o vídeo ao vivo com o ffmpeg?

0

Estou tentando adicionar um reticle a um feed de vídeo ao vivo e preciso que o reticle seja capaz de se mover com base em alguns dados externos.

Eu posso desenhar uma caixa no vídeo com o ffmpeg:

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

(Observe que, por enquanto, estou apenas testando com arquivos de vídeo, pois isso torna algumas partes mais simples.)

No entanto, parece não haver uma maneira de ajustar os valores x e y externamente depois que o comando é iniciado. Isto seria ideal se houvesse uma maneira de lê-los facilmente em, e. de stdin ou /dev/shm/reticle-pos.txt , mas não consigo encontrar uma maneira de fazer isso.

Outra opção que tentei é desenhar a retícula externamente com o imagemagick e depois sobrepô-lo com o 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

No entanto, isso não funciona, pois parece que o ffmpeg apenas lê o arquivo de imagem uma vez, em vez de em cada quadro.

Como posso desenhar uma retícula por cima do vídeo, de uma forma que me permita controlar a posição da retícula?

    
por AJMansfield 04.10.2017 / 23:42

2 respostas

2

usando a opção de loop:

ffmpeg -i input.mpg -loop 1 -f image2 -i /dev/shm/reticle.png -filter_complex overlay output.mpg
  • ffmpeg lê reticle.png em cada frame usando a opção loop de demoder image2.
  • Atualize rectile.png atomicamente escrevendo um novo reticle para temp primeiro arquivo e depois renomeie para rectile.png.
  • Para mais detalhes: link
por 08.10.2017 / 20:29
0

Eu descobri uma maneira de fazer isso. Provavelmente não é o melhor caminho, mas 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

Isso funciona com a geração de dados de pixel brutos de saída do imagemagick ( -size 1080x720 -depth 8 rgba:- ). Os dados de pixel de cada quadro são concatenados junto com o restante em um único fluxo de vídeo bruto. O ffmpeg é então capaz de ler o fluxo de vídeo bruto ( -f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0 ) e sobrepô-lo no vídeo principal.

    
por 05.10.2017 / 02:22