【ラズパイDIY講座】ラズパイゼロで作る監視カメラ① 〜 ラズパイ側から画像配信してみる


※ 当ページには【広告/PR】を含む場合があります。
2021/06/27
2021/07/03
【Websocket X IoT】Node.js上でWebsocketネットワークを構築し、ラズパイ&Arduinoをシリアル通信でデータを受信してみる
【ラズパイDIY講座】ラズパイゼロで作る監視カメラ② 〜 UV4LのビルドインシグナリングサーバでWebRTC
蛸壺の中の工作室|ラズパイゼロで作る監視カメラ① 〜 ラズパイ側から画像配信してみる



ラズパイゼロWHはWiFi接続が可能ですので、カメラ機能を有効化して家庭内のネットワークに接続すると、ネットワークに繋がっている他のPCやタブレットから静止画像をキャプチャしたり、リアルタイムで監視動画を配信したりと、高機能な監視カメラシステムを自力で構築することもできます。
前の回でラズパイを用いたWebsocketネットワークの構築方法の概要をブログとしてポストしていました。


合同会社タコスキングダム|蛸壺の技術ブログ
【Websocket X IoT】Node.js上でWebsocketネットワークを構築し、ラズパイ&Arduinoをシリアル通信でデータを受信してみる

Node.jsを使ったWebsocketサーバをLinux機(ラズパイ)に構築し、シリアル接続したArduinoからWebsocket経由でデータを取得する例を解説します。




今回から数回に渡ってWebRTC over Websocketを使ったラズパイゼロWで自作監視カメラを作ってみる試みを紹介していこうと思います。
第一弾として、とりあえず最初に本稿でラズパイゼロに接続したカメラのセットアップと、WebRTC配信のための環境構築の方法、簡単な画像の転送までをテストしてみます。


Web監視カメラの概要



今回構築する家庭内監視カメラシステムの模式図を以下に示しておきます。

合同会社タコスキングダム|蛸壺の技術ブログ


Websocket通信ベースでLANネットワークにあるPCやタブレットからならば何処からでもWebsocketサーバとして動作させたラズパイゼロWにアクセスして、動画を確認できるようにするのが今回の記事の目的です。


ラズパイカメラのセットアップ



ラズパイゼロとカメラモジュールの基本設定の手順を順次説明していきます。

ラズパイ-カメラモジュールの接続準備



まずはラズパイゼロWのカメラ周りの材料調達から考えていきましょう。
ウェブカメラとして利用するため、購入するラズパイゼロシリーズは、Wifiモジュール内蔵のゼロWをチョイスします。
また今回はラズパイ公式のカメラモジュールV2を利用します。
V2カメラモジュールを購入してラズパイゼロWで利用する場合の注意点として、付属のリボンケーブルはラズパイゼロ用の規格ではないので、そのままでは使えません。

合同会社タコスキングダム|蛸壺の技術ブログ


※図中の上がラズパイゼロ用のカメラケーブル/下が通常のラズパイ用カメラケーブル
そこで別途対応のリボンケーブルを購入する必要があります。





これらの具材を単純に接続させてみると以下のようになります。

合同会社タコスキングダム|蛸壺の技術ブログ


監視カメラとしての固定方法やケースなどは後々考えるとして、今回のブログではラズパイでカメラを使うことにフォーカスしていこうとおもいます。

カメラの動作テスト



ラズパイゼロの購入から本体の基本セットアップに関しては、以前のブログに特集していましたので、ここでは既にラズパイゼロは基本設定およびNode.jsはインストール済みとし、カメラモジュールのセットアップの手順を説明していきます。


合同会社タコスキングダム|蛸壺の技術ブログ
[ラズパイ x 環境構築] Wi-FiとSSHから行うRaspberryPi Zero Wのセットアップ方法

Raspberry Pi Zero Wのセットアップ方法をSSH接続を利用したディスプレイレスな環境構築手順をまとめてみます。




早速、カメラモジュールを接続したラズパイに電源を投入して作業を始めてみます。
なお今回も本ブログではCUI(SSHターミナル)メインのディスプレイレス環境でラズパイゼロを操作していく方式で以降解説していきます。
まずはカメラデバイスを有効にします。

            $ sudo raspi-config

        

として設定画面を呼び出し、以下の図のようにカメラモジュールを有効にします。

合同会社タコスキングダム|蛸壺の技術ブログ


これでラズパイが再起動後にカメラデバイスが有効化しているか確認してみます。
まずはカメラデバイスが認識されている場合、
/dev/ フォルダでvideo0が追加されているはずなので、以下のコマンドで確認します。

            $ ls /dev/ | grep video
video0 #👈カメラモジュール
video10
#...

        

次にこのカメラモジュールが有効かつラズパイに対応しているかの判断を以下のコマンドで行います。

            $ vcgencmd get_camera
supported=1 detected=1

        

このとき
supported=0detected=0 になってしまうと、機種未対応のカメラモジュール製品と接続されている可能性がありますのでご留意ください。
ではRaspberry Pi OSに標準でインストールされている
raspistill というユーティリティでカメラモジュールから静止画像をキャプチャし、現在の場所に保存します。

            $ sudo raspistill -o 1.jpg

        

というコマンドを叩くと、数秒後に
1.jpg という名前の画像が保存されると思います。
今回はSSH接続してCUIでラズパイを動かしていますので、サッと保存した画像をプレビューできないのが難点ではあります。 そんなときはsshコマンドと同じ要領で、M2Mのファイル転送を行う
scpコマンド でラズパイからホストPCに画像を転送しましょう。
SSH接続中のコンソールとは別画面で以下のコマンドを叩きます。
ここではラズパイのユーザー・
raspi 、ラズパイの固定IP・ 192.168.0.123 、SSHのポート番号(デフォルトから変えている場合)・ 12345 、キャプチャ画像の保存先(絶対パス)・ /home/raspi/1.jpg で転送元から、現在のPCのtmpフォルダへコピーさせてみましょう。

            $ mkdir tmp
$ scp -P 12345 raspi@192.168.0.123:/home/raspi/1.jpg tmp/
$ ls tmp/
1.jpg

        

で画像が送れます。
手元のビュアーで天井か地面などが移っていればカメラモジュールは正常に動作しているはずです。


UV4Lサーバのセットアップ



次にラズパイから動画を簡単に配信するためのUV4L(over HTTP)サーバをセットアップしていきます。
なお
こちらのインストール手順として参考に書かれているやり方 はちょっとだけ古いRaspbian OS Basterで確認されているようですが、一応手元のRaspberry Pi OSであっても問題なく動作しています。
まずはパッケージキーのインストールですが、

            $ curl http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add -
gpg: no valid OpenPGP data found.

        

となってCurlでは取得失敗するかもしれませんので、このようなエラーが発生した場合wgetでの操作に切り替えます。

            $ wget http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc
$ sudo apt-key add lpkey.asc
OK

        

次に以下のコマンドで
/etc/apt/sources.list にUV4Lダウンロード用のレポジトリを追加します。

            $ echo 'deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main' | sudo tee -a /etc/apt/sources.list

        

もしくは直接
/etc/apt/sources.list を編集し、

            $ sudo nano /etc/apt/sources.list
#...追加👇
deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main

        

とすることもできます。
なおレポジトリは未だに名前が
raspbian/stretch のままでプログラムがおいてありますが、とりあえず名前はそのまま気にせずに使います。
編集したら、
apt-get でパッケージのアップデートとUV4Lのインストールを行います。

            $ sudo apt-get update
$ sudo apt-get install uv4l uv4l-server uv4l-raspicam

        

これでラズパイ側からUV4Lサーバから動画が配信されるのですが、後々WebRTC接続して利用しますので、WebRTC接続配信用のエクステンションもインストールしておきます。

            #Raspberry Pi 2, 3 or later
#$ sudo apt-get install uv4l-webrtc
#Raspberry Pi 1, Compute Module 1, Zero or Zero W (Wireless)
$ sudo apt-get install uv4l-webrtc-armv6

        

ラズパイの製品モデルによってCPUのアーキテクチャに併せてインストールする必要があります。 今回はラズパイゼロWで利用するので、
uv4l-webrtc-armv6 を利用します。
インストール後は再起動するとUV4Lサーバがバックグラウンドで起動するようになります。
UV4Lで例えば以下のようなオプションで起動してみます。

            $ uv4l --driver raspicam --auto-video_nr --encoding h264 --width 320 --height 240 --server-option '--port=8080' --enable-server on
<notice> [core] Trying to loading driver 'raspicam' from built-in drivers...
<notice> [core] Loading driver 'raspicam' from external plug-in's...
<notice> [driver] Dual Raspicam & TC358743 Video4Linux2 Driver v1.9.76 built Apr 10 2021
<notice> [driver] Detected camera imx219, 3280x2464
<notice> [driver] Selected format: 320x240, encoding: h264, H264 Video Compression
<notice> [driver] Framerate max. 30 fps
<notice> [driver] H264 costant bitrate: 8000000
<notice> [core] Device detected!
<notice> [core] Registering device node /dev/video0

        

これでネットワークのパソコンのブラウザ側から、
http://[ラズパイのIP]:8080/stream を叩くと、カメラからの画像が確認できます。
サーバを止める場合には以下のコマンドから停止できます。

            $ sudo pkill uv4l

        

ラズパイカメラからの単純な映像送信であれば、これだけで十分に監視カメラとして機能しています。


UV4LからWebRTCを試す



ここからはさらなる機能拡張に向けたWebRTC通信のための下準備の話になります。

https://[ラズパイのIP]:8080/stream/webrtc からWebRTC経由でWebアプリのデモをみることができますが、昨今のブラウザではセキュリティの関係でhttps化しなければ映像が取得できないようになっています。
ここではもう少し使いやすいアプリに作り変えるための独自の実装をおこなっていきます。

mkcertでローカルssl証明を発行する



ローカルssl証明にはopensslを使って発行する例が多く紹介してありますが、今回は
mkcert を使って行っています。
以前、
別のブログでmkcertの概要の方を解説した記事 をおこしたことがありましたので詳しいことはそちらで確認ください。
mkcertはGo言語で作成されていますので、まずはGoのインストールから初めていきます。
ラズパイにGoをインストールする場合はリポジトリからは取得できないので、wgetからパッケージをダウンロードします。

            #パッケージの取得 ※ラズパイゼロ > armv6
$ wget https://golang.org/dl/go1.16.5.linux-armv6l.tar.gz
#今回は例ではパッケージの展開先はデフォルト
$ sudo tar -C /usr/local -xzf go1.16.5.linux-armv6l.tar.gz
#インストール確認
$ ls -l /usr/local/go
$ cat /usr/local/go/VERSION
go1.16.5

        

インストールしただけではパスが通ってないため、Goのパスを通します。

            $ nano ~/.bashrc
#...GoのPATHを通すためファイル末尾に以下を追記
export PATH=$PATH:/usr/local/go/bin

#パスの有効化
$ source .bashrc
#パスの確認
$ which go
/usr/local/go/bin/go

        

ではmkcertをソースコードビルドをします。

            $ sudo apt-get install git
$ git clone https://github.com/FiloSottile/mkcert && cd mkcert
$ go build -ldflags "-X main.Version=$(git describe --tags)"
$ ./mkcert --version
v1.4.3-1-g0a3190b

        

使いやすいようにビルドしたアプリケーションは移動してコマンドから呼び出せるように配置しておきます。

            $ sudo mkdir /usr/local/mkcert && sudo mkdir /usr/local/mkcert/bin
$ sudo cp mkcert /usr/local/mkcert/bin/

$ nano ~/.bashrc
#...mkcertのPATHを通すためファイル末尾に以下を追記
export PATH=$PATH:/usr/local/mkcert/bin

#パスの有効化
$ source .bashrc
#パスの確認
$ which mkcert
/usr/local/mkcert/bin/mkcert

        

ではmkcertを利用してssl証明を発行します。

            $ sudo apt install libnss3-tools
$ mkcert -install
Created a new local CA 💥
The local CA is now installed in the system trust store! ⚡️

$ mkcert localhost 127.0.0.1
Created a new certificate valid for the following names 📜
 - "localhost"
 - "127.0.0.1"

The certificate is at "./localhost+1.pem" and the key at "./localhost+1-key.pem" ✅

It will expire on 27 September 2023 🗓

$ ls
localhost+1-key.pem  localhost+1.pem

        

これで
localhost+1-key.pemlocalhost+1.pem の二つの自分認証ファイルが発行されました。 この2つのファイルをserver.keyとserver.crtに、それぞれリネームして利用してみます。

            $ mv localhost+1-key.pem server.key
$ mv localhost+1.pem server.crt
$ ls
server.crt  server.key

        

さて、この2つのファイルの絶対パスが
/home/user/server.key/home/user/server.crt に配置してあるとして、

            $ uv4l --driver raspicam --auto-video_nr --encoding h264 \
    --width 320 --height 240 \
    --server-option '--port=4300' \
    --server-option '--use-ssl=yes' \
    --server-option '--ssl-private-key-file=/home/user/server.key' \
    --server-option '--ssl-certificate-file=/home/user/server.crt' \
    --enable-server on

        

とUV4Lサーバを起動してみましょう。
この状態でネットワーク内の別PCのブラウザから
https://[ラズパイのIP]:4300/stream/webrtc へアクセスすると、怪しいSSL接続とはされつつも今回は例外として見逃してもらえるようになりました。

合同会社タコスキングダム|蛸壺の技術ブログ


ローカルでもssl接続が可能となりWebRTCモードから映像の取得できていることがデモアプリからも確認できました。

合同会社タコスキングダム|蛸壺の技術ブログ

UV4Lカメラ画面に出る"linux-projects.org"のウォータマークを外す



UV4Lを使ってラズパイカメラから画像を取り込むと、画面上部にデカデカと
software by http://linux-projects.org のウォータマークがデフォルト表示されてしまいます。

合同会社タコスキングダム|蛸壺の技術ブログ


これはUV4Lで指定したカメラのドライバ
raspicam を利用している限り必ず表示されるような仕様になっているため、V4L2(Video for Linux 2)ドライバを使う必要があります。
V4L2はLinux上でビデオを扱うための汎用APIとして開発されているものです。 純正のラズパイカメラモジュールV2はこのV4L2に対応しているため、
raspicam の代わりのドライバとして利用できます。
ラズパイゼロではデフォルトでV4L2ドライバは利用できないため、
/etc/modules にドライバを追加します。

            $ sudo nano /etc/modules

#...中略
#👇V4L2ドライバを追加
bcm2835-v4l2

        

追加したらラズパイを再起動するだけでV4L2ドライバが有効になっていると思います。

v4l2-ctl コマンドでデバイス一覧をみると、 video0 がv4l2ドライバが有効となっています。

            $ 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

mmal service 16.1 (platform:bcm2835-v4l2-0):
    /dev/video0

        

もしも誤ってvideo0デバイスを消したり、再起動後もカメラモジュールが認識しない場合には手動でvideo0デバイスを作成する必要があるかも知れません。

            mknod /dev/video0 c 81 0
chmod 666 /dev/video0
chown root.video /dev/video0

        

としてvideo0デバイスを作成後、再起動してみて認識するかどうかを確認してください。 それでもダメそうならカメラケーブル配線に問題がないかなどハードの方を疑ってみたりと色々と悩む必要があります...。
V4L2ドライバが正常にセットアップできたら、UV4Lを外部ドライバからvideo0を指定して起動してみます。

            $ uv4l --external-driver --device-name=video0 \
    --auto-video_nr --encoding h264 \
    --width 320 --height 240 \
    --server-option '--port=4300' \
    --server-option '--use-ssl=yes' \
    --server-option '--ssl-private-key-file=/home/user/server.key' \
    --server-option '--ssl-certificate-file=/home/user/server.crt' \
    --enable-server on

        

上手く動作すると、無事ウォータマークが消えているはずです。

合同会社タコスキングダム|蛸壺の技術ブログ

まとめ



以上、ここまででUV4Lサーバを使ったラズパイカメラからの映像の転送方法を解説していきました。 LANネットワーク越しにラズパイからの映像を飛ばすだけであれば、十分監視カメラシステムとしては機能しそうです。
次回はもう少し応用的な利用法を模索するために、Node.jsを使ったWebRTCのシグナリングまで考えていこうかと思います。

参考サイト

UV4L | User space Video4Linuxuv4l-server command optionsRaspberry Pi Zero W カメラ映像をリアルタイムでストリーミングする方法WebRTC extension for the UV4L Streaming ServerUV4L Webrtc on Raspberry PiWebRTC on Raspberry Pi: Live HD Video and Audio StreamingVideo streaming from Raspberry Pi with UV4L