ffmpeg を使用してライブ ビデオ上にレチクルを描画する方法を教えてください。

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 は画像ファイルをフレームごとにではなく 1 回だけ読み取るため、これは機能しません。

レチクルの位置を制御できるように、ビデオの上にレチクルを描画するにはどうすればよいですか?

答え1

ループオプションの使用:

ffmpeg -i input.mpg -loop 1 -f image2 -i /dev/shm/reticle.png -filter_complex overlay output.mpg
  • ffmpeg は、image2 デマルチプレクサーのループ オプションを使用して、フレームごとに reticle.png を読み取ります。
  • まず新しいレチクルを一時ファイルに書き込んでから rectile.png に名前を変更することで、rectile.png をアトミックに更新します。
  • 詳細については:https://ffmpeg.org/ffmpeg-formats.html#image2-1

答え2

私はこれを実行する方法を見つけました。おそらく最善の方法ではありませんが、機能します。

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:-。各フレームのピクセル データは、残りのデータと連結されて 1 つの生のビデオ ストリームになります。その後、ffmpeg はその生のビデオ ストリーム ( ) を読み取り-f rawvideo -pixel_format bgr32 -video_size 1080x720 -framerate 30 -i pipe:0、メイン ビデオにオーバーレイできます。

関連情報