Raspberry piとWebカメラを使って、犬猫監視用にネットワークカメラを作ってみよう

2021-09-07

はじめに

GStreamerってみなさんご存知ですか? GStreamer: open source multimedia framework ビデオ編集ソフトやストリーミング、そしてメディアプレーヤーなどのようなマルチメディアアプリケーションのベースとなる機能を提供してくれています。 コマンドをパイプラインで繋いでやりたいことを実現するというのが基本設計のツール郡です。

今回は、Raspberry pi上でWEBカメラの映像を取得して、Windows PCに配信するシステムを構築したいと思います。 コマンドラインで完結するため非常にお手軽なのが魅力です。

隣の部屋で眠っている赤子を見たり、外出先から犬や猫の様子を眺めたり、金魚を全世界に常時配信するサイトを作ってみたりとアイディア次第で用途は広がります。

さっそく進めていきましょう。

配信側(raspberry pi)の準備

初期設定

Raspberry piで、WEBカメラを接続して使えるようにします。 まずは、raspi-configを立ち上げます。

sudo raspi-config

3.Interface Optionsを開いて、P1 Camera そしてEnableにします。

変更したらRaspberry piを再起動します。

sudo reboot

gstreamerのインストール

続いて今回の要である、gstreamerをインストールしていきます。 コマンドラインからポチポチやってインストールできるので特に問題ないはずです。

アップデート前に、インストールパッケージの更新を行います。

sudo apt-get update
sudo apt-get upgrade

apt-getでgstreamer関連ツール群をインストールします。

sudo apt-get install gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly

成功するとこんな感じに表示されるはずです。

Reading package lists... Done
Building dependency tree
Reading state information... Done
gstreamer1.0-plugins-bad is already the newest version (1.14.4-1+rvt+deb10u2).
gstreamer1.0-plugins-good is already the newest version (1.14.4-1+rpt1+deb10u1).
The following NEW packages will be installed:
  gstreamer1.0-tools
0 upgraded, 1 newly installed, 0 to remove and 97 not upgraded.
Need to get 1,109 kB of archives.
After this operation, 1,196 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf gstreamer1.0-tools armhf 1.14.4-1 [1,109 kB]
Fetched 1,109 kB in 1s (921 kB/s)
Selecting previously unselected package gstreamer1.0-tools.
(Reading database ... 98616 files and directories currently installed.)
Preparing to unpack .../gstreamer1.0-tools_1.14.4-1_armhf.deb ...
Unpacking gstreamer1.0-tools (1.14.4-1) ...
Setting up gstreamer1.0-tools (1.14.4-1) ...
Processing triggers for man-db (2.8.5-2) ...

準備はこれでOKです。

WEBカメラの接続確認

続いて、WEBカメラをRaspberry piのUSBポートに繋いで、以下のコマンドを実行します。 繋がっているデバイスを確認することができ、WEBCAMERAっぽいデバイスがあることを確認します。

v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16

GENERAL WEBCAM: GENERAL WEBCAM (usb-3f980000.usb-1.5):
        /dev/video0
        /dev/video1

この状態では、gstreamerから上手く認識しないことがあるので、 usermodを使って、セカンダリグループにvideoを作ってそこに$USERを追加します。

sudo usermod -a -G video $USER

有効になっているカメラデバイスを確認します。 arecordはAudioデバイスの録音とかに使うものらしいです。 デバイス確認以外でそういや使ったこと無いな…

arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: WEBCAM [GENERAL WEBCAM], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

上手く動いていそうですね。

Gstreamerの動作確認(ERROR対応)

gstreamerの起動はこのように行います。

gst-launch-1.0 v4l2src ! videoconvert ! ximagesink
Setting pipeline to PAUSED ...
ERROR: Pipeline doesn't want to pause.
ERROR: from element /GstPipeline:pipeline0/GstXImageSink:ximagesink0: Could not initialise X output
Additional debug info:
ximagesink.c(860): gst_x_image_sink_xcontext_get (): /GstPipeline:pipeline0/GstXImageSink:ximagesink0:
Could not open display
Setting pipeline to NULL ...
Freeing pipeline ...

このERRORは、コマンドラインからSSH接続なのでGUIが無いことで怒られているようです。

Raspberry piにGUIで接続できるようにする。

WEBカメラが接続されてGstreamerの動作確認を行うために手順を続けます。 WEBカメラ映像配信にはGUIが不必要なので省略してもらっても良いです。

xrdpをインストールします。 インストールしたらサービスを再起動して動かします。

sudo apt-get install xrdp
sudo service xrdp restart
raspi-config

VNCを有効にします。

Windowsからの接続

標準では言っている、リモートデスクトップアプリからつなげることができます。 コンピュータ名のところにRaspberry piのIPアドレスを入力しましょう。

接続したらRaspberry piのユーザ名とPASSを求められるので入力すると、デスクトップ画面に繋がります。

Raspberry piのTerminalを立ち上げて先程動かせなかったコマンドを実行しましょう。

gst-launch-1.0 v4l2src ! videoconvert ! ximagesink

WEBカメラの映像が移りましたね。良いですね。

使用中のカメラの性能を確認する

さて自分が繋いでいるカメラの解像度がどこまで対応してるのか確認します。 配信に使えるサイズを超えてないことが条件です。

v4l2-ctl --list-formats-ext --device=/dev/video0

出力結果はこんな感じになります。 画像は、1920x1080 動画は、640x480 と読み取れます。1000円カメラなのでこんなものかという感じです。

ioctl: VIDIOC_ENUM_FMT
    Type: Video Capture

    [0]: 'MJPG' (Motion-JPEG, compressed)
        Size: Discrete 1920x1080
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 1280x720
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 800x480
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 176x144
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 800x600
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 1920x1080
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.033s (30.000 fps)
    [1]: 'YUYV' (YUYV 4:2:2)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 176x144
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.033s (30.000 fps)

Raspberry piのWeb Cameraから配信を行う

Raspberry pi側

Raspberry piにSSHで接続して、以下のコマンドを実行します。 tcpserversinkを使ってTCP/IPで動画データを配信しています。

gst-launch-1.0 -v v4l2src ! video/x-raw,width=320,height=240,framerate=30/1 ! gdppay ! tcpserversink host=192.168.0.32

待受状態になっているかを確認するときはこのように打てばよいです。 画像はGUIでTerminal2つ立ち上げて確認シテますが、SSHで繋ぐ場合は2つのTerminalで繋ぐか、コマンドに&でもつけて裏で動かせば良いんじゃないかと思います。

netstat -an |grep 4953

これで準備は完了です。

Windows側

PowerShellから実行しました。 Gstreamerは、Windows向けにもインストーラが配布されているのでインストールしておいてください。 インストール後はBinフォルダを環境変数のPATHに追加しておきます。

gst-launch-1.0 -v tcpclientsrc host=192.168.0.32 ! gdpdepay ! videoconvert ! autovideosink

接続確認

WEBカメラの映像をつなげることが出来ました。

こんな感じです。動作イメージをつかみやすいようにYoutubeにあげておきました。

まとめ

同じネットワークに繋いでいますが遅延が結構あります。 体感で20秒ぐらいの遅延があるためリアルタイム監視とかそういった用途で使うのは厳しそうです。 もしかすると、配信するサーバをRaspberry piの最新にするとか、デスクトップPCにするなどの工夫が必要かもしれないです。 あとは、配信する映像のサイズを小さくするとか、動画ではなく画像を配信するとか何か別の工夫が必要だと思います。

Gstreamerはもう少し擦れそうなのでアルバイトも兼ねて遊んでみようと思います。