Wie zeichnet man ein Fadenkreuz über ein Live-Video mit ffmpeg?

724
AJMansfield

Ich versuche, einem Live-Video-Feed ein Fadenkreuz hinzuzufügen und brauche das Fadenkreuz, um sich auf der Grundlage einiger externer Daten bewegen zu können.

Ich kann mit ffmpeg eine Box auf das Video zeichnen:

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

(Beachten Sie, dass ich momentan nur mit Videodateien teste, da dies einige Teile einfacher macht.)

Es scheint jedoch nicht möglich zu sein, die Werte xund ynach dem Start des Befehls extern anzupassen . Dies wäre ideal, wenn es eine Möglichkeit gibt, sie problemlos einzulesen, z. B. von stdin oder /dev/shm/reticle-pos.txt, aber ich finde keine Möglichkeit, dies zu tun.

Eine andere Möglichkeit, die ich versucht habe, ist, das Absehen mit imagemagick extern zu zeichnen und dann mit ffmpeg zu überlagern:

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 

Dies funktioniert jedoch nicht, da ffmpeg die Bilddatei nur einmal und nicht für jedes Bild liest.

Wie kann ich ein Absehen über dem Video zeichnen, sodass ich die Position des Absehens kontrollieren kann?

0

2 Antworten auf die Frage

2
Rens

Schleifenoption verwenden:

ffmpeg -i input.mpg -loop 1 -f image2 -i /dev/shm/reticle.png -filter_complex overlay output.mpg 
  • ffmpeg liest reticle.png in jedem Frame, indem die Schleifenoption von image2 demuxer verwendet wird.
  • Aktualisieren Sie rectile.png atomar, indem Sie zunächst ein neues Absehen in eine temporäre Datei schreiben und dann in rectile.png umbenennen.
  • Weitere Informationen finden Sie unter https://ffmpeg.org/ffmpeg-formats.html#image2-1
0
AJMansfield

Ich habe einen Weg gefunden, dies zu tun. Es ist wahrscheinlich nicht der beste Weg, aber es funktioniert:

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 

Dies funktioniert, wenn mit imagemagick rohe Pixeldaten ( -size 1080x720 -depth 8 rgba:-) ausgegeben werden . Die Pixeldaten für jeden Frame werden zusammen mit dem Rest zu einem einzigen Rohvideostream verkettet. ffmpeg kann dann diesen Rohvideostream ( -f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0) lesen und dem Hauptvideo überlagern.