ラズパイで居留守を極める


CYBIRDエンジニア Advent Calendar 2日目担当の @march_f です。
1日目は @ntrv さんによる「新規案件の設計について, 使用したサービスの紹介」でした。
私は普段恋愛ゲームのサーバー担当なので、インフラの構造や動きはとてもためになりました。
皆さんもぜひご覧ください!

はじめに

CYBIRDはコロナ禍に入ってすぐに在宅勤務となったのですが、いざ在宅勤務になると宗教の勧誘や営業訪問が多く来る事に気付きました。
来るたびに確認に行くのも面倒ですし、居留守を使いたいので足音も出したくありません。が、よく通販を利用するためその宅配も逃したくありません。
そこで、玄関扉の覗き穴(ドアアイもしくはドアスコープと呼ぶそう)にカメラを設置して、作業部屋から誰が来たかを確認できるようにします。

やること

  • ドアスコープに内視鏡カメラ固定
  • ラズパイにカメラを接続してRTSPサーバーをたてて配信する
  • PC、スマホから視聴する

準備

今回は事前にラズパイへOSのインストールや設定をしている前提です。

ハードウェア

  • Raspberry Pi 4(OS、SSHなど設定済み)
  • サンコー Android/PC両対応5.5mm径内視鏡ケーブル 2m 形状記憶タイプ MCADNEW2
    https://www.amazon.co.jp/dp/B0758YWNFV

  • 視聴用の環境(今回はWindows、iPhone)


  • カメラはラズパイへ繋げておきます。
  • 内視鏡カメラはドアスコープへ取り付けておきます。

ソフトウェア

カメラの設定

有効化&確認

$ sudo raspi-config
  1. 「3 Interface Options」→「P1 Camera」->「Yes」
    設定したらカメラをラズパイに繋いで再起動

  2. カメラのリストを表示

$ v4l2-ctl --list-devices

/dev/video0 が表示されていればOK

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

USB2.0 PC CAMERA: USB2.0 PC CAM (usb-0000:01:00.0-1.3.4):
        /dev/video0
        /dev/video1

RTSPサーバを立てる

インストール

はじめに内視鏡カメラの対応フォーマットを見ます。

$ v4l2-ctl -d /dev/video0 --list-formats
ioctl: VIDIOC_ENUM_FMT
    Type: Video Capture

    [1]: 'YUYV' (YUYV 4:2:2)

今回使っている内視鏡カメラは YUYV しか表示されていません。
Webカメラを用いてRTSPサーバを立てる際は、v4l2rtspserver や VLC を使えば一瞬なのですが、今回のフォーマットだと初期で対応していないため使えません。(エンコーダーを追加するといけるようですが、いろいろ試して挫折...)
調べたところ、 gstreamer を使えばできるみたいなので、それを用いてRTSPサーバを構築できる gst-rtsp-server を使ってサーバをたてます。

gstreamer は、映像と音声の圧縮・変換・復元したりできるフレームワークで、gst-rtsp-server はそれを用いてRTSPサーバを立てることができるライブラリです

Wikipediaより引用

GStreamer(ジーストリーマー)は、フリー(ライセンスはLGPL)のマルチメディアフレームワーク。

ビデオ編集ソフトやストリーミング、そしてメディアプレーヤーなどのようなマルチメディアアプリケーションのベースとなる機能を提供する。

まず、必要なものを一式インストールします。

$ sudo apt install gstreamer1.0-tools
$ sudo apt install gstreamer1.0-plugins-good
$ sudo apt install gstreamer1.0-plugins-bad
$ sudo apt install gstreamer1.0-plugins-ugly
$ sudo apt install libglib2.0-dev
$ sudo apt install libgstreamer1.0-dev 
$ sudo apt install libgstreamer-plugins-base1.0-dev

インストールされたバージョンを確認します。

dpkg -l | grep gstreamer

次にダウンロードする gst-rtsp-server をこのバージョンと合わせる必要があります。
記事を書いている時点では 1.14.4 でした。
※バージョンが違う場合は 1.14.4 の部分を変えてください

$ wget https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-1.14.4.tar.xz
$ tar -xf gst-rtsp-server-1.14.4.tar.xz
$ cd gst-rtsp-server-1.14.4
$ ./configure
$ make
$ sudo make install

起動

インストールしたフォルダに、test-launch というファイルがあり、これを実行すると簡単に rtspサーバ が立てられるのですが、
YUYV の場合はいろいろオプションをつけないといけないみたいで、当時ここがわからずずっと止まってました。

調べていくと、「YUYV camera + Raspberry Pi」 というめちゃくちゃピンポイントなコマンドを見つけました。
ありがとうございます🙏

/home/pi/gst-rtsp-server-1.14.4/examples/test-launch "( v4l2src ! video/x-raw,format=YUY2,width=640,height=480 ! videoconvert ! video/x-raw,format=I420 ! videoconvert ! x264enc qp-min=18 speed-preset=superfast ! h264parse ! rtph264pay name=pay0 pt=96 config-interval=1 )"

実行すると stream ready at rtsp://127.0.0.1:8554/test という表示がでます。
この 127.0.0.1 をラズパイのIPアドレスにしたものが配信サーバーのアドレスになります。

コマンドの説明

なんでこのコマンドで動くのかあまり理解していないのですが、一応上記のコマンドに沿って ! ごとにそれぞれの意味を書いておきます。(! はパイプラインです)
各要素はエレメントと呼ばれています。

コマンドNo. エレメント 意味
No.1 v4l2src ! video/x-raw,format=YUY2,width=640,height=480 ラズパイに繋がっているビデオの映像フォーマットを指定して取得。この場合は 620x480 のYUY2形式
No.2 videoconvert ! video/x-raw,format=I420 No.1のビデオを I420 に変換する
No.3 videoconvert ! x264enc qp-min=18 speed-preset=superfast No.2 を h264 にエンコード
No.4 h264parse No.3 をパーズ(解析)
No.5 rtph264pay name=pay0 pt=96 config-interval=1 No.4 を RTPパケットにエンコード

変換を多くしているのは、そのままだとその次の受け取り可能なフォーマットに対応していないからだと思われます。

例として、No.3 で指定している x264enc の受け取り可能なフォーマットには YUY2 がないため、受け取り可能な I420 に変換する必要があります。

エレメントの受け取り可能なフォーマットは以下で確認できます。

$ gst-inspect1.0 コマンド名
$ gst-inspect1.0 x264enc

サービス化

毎回こんな長いの打てないのでサービス化します。

sudo vi /usr/lib/systemd/system/entrance-camera-rtsp.service
/usr/lib/systemd/system/entrance-camera-rtsp.service
[Unit]
Description = RTSP server for entrance camera.

[Service]
ExecStart = /home/pi/gst-rtsp-server-1.14.4/examples/test-launch "( v4l2src ! video/x-raw,format=YUY2,width=640,height=480 ! videoconvert ! video/x-raw,format=I420 ! videoconvert ! x264enc qp-min=18 speed-preset=superfast ! h264parse ! rtph264pay name=pay0 pt=96 config-interval=1 )"
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

できてるか確認

sudo systemctl list-unit-files --type=service | grep entrance

以降は sudo systemctl start entrance-camera-rtsp で起動できます。

自動起動設定

sudo systemctl enable entrance-camera-rtsp

視聴

  1. インストールした VLC Media Player を起動して
    左上の「メディア」→「ネットワークストリームを開く」を押します。

  2. ネットワークURLに入力して「再生」を押すと配信を見ることができます。

接続するとカメラの映像が出ます。(出ない場合は30秒ほど待つと出ます)
遅延は1秒~2秒ほどでした。

この画像にはうつっていませんが、人を識別できるほどはっきりは見えました。

さいごに

これでデスクから離れなくてよくなったが、ますます歩かなくなった。
明日のCYBIRDエンジニア Advent Calendar 2021 3日目は、 @kyorokyoro さんによる「アプリの通信回数を減らすためにやったこと」です。
通信回数は分野問わず重要なことなので、ぜひご覧ください!

ありがとうございました!

参考