前置き
世の中なにかとカメラを使って録画しておきたいということがありますよね。
実験データと時間を合わせて撮りたいときとか、カメラアプリもデータをとるスクリプトもなんて操作が多すぎて失敗することもしばしば。
そこで、データをとるスクリプト内にカメラも録画できるようにCLIで操作できるgstreamerを使って録画をしてみようというのがこの記事です。
環境
- Windows10
- GStreamer 1.16.2
ここでダウンロードしたインストーラを使用しました。
ウェブカメラとカメラを使う場合は"complete"ですべてインストールするか、必要そうなパッケージをインストールしてください。"typical"ではプラグインがなくて動きませんでした。あと、powershellから使えるようにbinフォルダのパスを通しておきましょう。 - Webカメラ
今回使用したカメラはIO-DATAのTS-NA220Wというものでhttpでjpegを吐き出してくれるものでした。 - プログラミング言語
文字列でpowershellのコマンドを実行できるのが前提条件です。python
だったらsubprocess.Popen("ls". shell=True)
みたいな
まずは動画を取得してみる
私の使用していたウェブカメラはAPIが用意されており、rtspでmp4,mjpegが、httpでjpegがストリーミングで見ることができました。
以下にそれぞれrtspとhttpで動画を取得するコマンドを載せておきます。<>の部分は適宜自分の環境に書き換えてください。
powershellを起動して実行してみましょう。
gst-launch-1.0.exe rtspsrc location=rtsp://<username>:<password>@<IPaddress>:<port>/<path> ! rtph264depay ! queue ! h264parse ! decodebin ! videoconvert ! autovideosink
私の使用していたウェブカメラはrtspでmp4をストリーミングできたのですが、映像が遅く、3秒前の自分が映っていたので使い物になりませんでした。
gst-launch-1.0.exe souphttpsrc location=http://<username>:<password>@<IPaddress>:<port>/<path> ! queue ! jpegdec ! videoconvert ! autovideosink
いよいよ録画
映像を取得できることが確認出来たら、次は録画になりますね。
それに使うコマンドはこちら
gst-launch-1.0 --eos-on-shutdown souphttpsrc location=http://<username>:<password>@<IPaddress>:<port>/<path> ! queue ! capsfilter caps=image/jpeg,width=1280,height=720,framerate=25/1 ! jpegdec ! jpegenc ! avimux ! filesink location=<filepath>.avi
録画の終了はCtrl+C
でできます。--eos-on-shutdown
をつけることでCtrl+C
を使って終了しても動画ファイルが壊れないようになっています。(ちなみにプロセスをキルしたらデータは保存されませんでした)
souphttpsrc
もrtspsrc
もフレームをカウントする機能がないので何フレーム後に終了という設定ができず、これを使っています。
あと、jpegdec ! jpegenc
は非常に頭悪いですがなしだとうまく動かなかったのでこれにしてあります。
さて、これだけだと自分でCtrl+C
を打ってあげないとダメなので、Ctrl+C
を打ってくれるスクリプトも用意する必要があります。
参考:PowerShellでSendKeysを使ってみた
使いやすいようにコピペします。
Param( $InputStroke, $InputProcessName, $InputWaitTime )
## ここに「PowerShellでSendKeysを使ってみた」をまるまるコピーしました。
Send-Keys $InputStroke -ProcessName $InputProcessName -Wait $InputWaitTime
これで準備は整いました。sendkey.ps1
とgstreamer
をpythonとかそういうスクリプト内でpowershellのコマンドを実行するだけです!
最終的なスクリプト
以下のスクリプトでは指定したURLからjpegをストリーミングして10秒間録画するスクリプトになります。
import subprocess
gstCommand = 'start C:/gstreamer/1.0/x86_64/bin/gst-launch-1.0 --eos-on-shutdown souphttpsrc location=http://<username>:<password>@<IPaddress>:<port>/<path> ! queue ! capsfilter caps=image/jpeg,width=1280,height=720,framerate=25/1 ! jpegdec ! jpegenc ! avimux ! filesink location=<filepath>.avi'
sendKeyPath = '<path>/<to>/sendkey.ps1'
gstEndCommand = 'start powershell ' + sendKeyPath + ' "^C" "gst-launch-1.0" 10000'
subprocess.Popen(gstCommand, shell=True)
subprocess.Popen(gstEndCommand, shell=True)
このスクリプトではgstreamerを実行しているウィンドウにフォーカスを移してからCtrl+C
を送るので、終了時に画面操作をしているとうまく終了しないことがあります。
まとめ
いやー、撮れてよかった。