Raspberry Pi Zero Wを使ってライブストリーミングカメラを作る、1時間くらいの作業で。

![IMG_20200518_092413.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88590/aec43d69-02ea-72cd-7914-4c5cc52bcde5.jpeg)

認証の待ち時間が24時間くらいありますが、慣れていれば作業は1時間くらいで済むと思います。

## はじめに

Raspberry Pi Zero Wを使ってライブストリーミングカメラを作ってFull HD 30fpsの動画（現時点では音声なし）をYoutubeで配信します。
YouTube Liveを利用することで定点撮影や監視カメラを手軽に作ることができます。 また、手軽に持ち運び可能な動画配信機材として使うこともできるでしょう。
Youtube Liveの設定で非公開設定とすることで、閲覧できるユーザーを限定することもできます。

用意するものは以下です。

- Raspberry Pi Zero W
- Pi Camera：アマゾンで互換品が1000円くらいで購入できます。ZeroなのでHWエンコーダ利用したい。
- microSDカード 8GB
- ケース：お好きなものを用意してください。なくても構いません。
- Googleアカウント

手順の概要です。

- Googleアカウントの作成（持っていなければ）
- YouTubeの準備:ライブ配信のための認証（電話番号が必要）
- ラズパイのセットアップ
- YouTube Live配信の開始＆ラズパイでコマンドの実行


## Googleアカウントの作成
Youtube用にGoogleアカウントを準備します。
https://support.google.com/accounts/answer/27441?hl=ja


## Youtubeの準備

YouTubeでライブ配信を行うためにはアカウントとチャンネルを作成し、本人確認を行う必要があります。
[YouTubeでアカウントを作成する](https://support.google.com/youtube/answer/161805?hl=ja&ref_topic=9267674)を参考にアカウントの作成、チャンネルを作成、アカウントの確認まで行ってください。
すでにGoogleアカウントを持っている場合はそれを利用しても構いません。
アカウントの確認に24時間かかるため待ちます。
1つの電話番号で確認できるアカウント（チャンネル）は1年間に2つまでです。


## ラズパイのセットアップ

ラズパイのセットアップをします。
OSはRaspbian Buster Lite, Version:February 2020を使いました。

キーボードやディスプレイを用意するのは手間なので、USB接続してヘッドレスで手っ取り早く設定します。起動前にPi Cameraを接続してください。
手順は[こちらなど](https://gan0803.hateblo.jp/entry/2018/04/28/140040)を参考にしてください。

ラズパイが起動したら`raspi-config`を実行して設定を行っていきます。

```shell
sudo raspi-config
```

以下の設定を行います。

- SSHの有効化
- 無線LANの接続設定
- カメラの有効化

再起動を促されるので再起動します。
ラズパイが再起動したら無線LAN経由でSSHログインします。

そしてアップデートをします。

```shell

sudo apt update && sudo apt -y upgrade
```

ffmpegをインストールします。

```shell
sudo apt install ffmpeg
```

これでラズパイの準備は完了です。


## Youtube live配信を開始する

[ライブ配信を開始する](https://support.google.com/youtube/answer/2474026?co=GENIE.Platform%3DDesktop&hl=ja&oco=0)を確認します。
Raspberry Piはバッテリに繋げば持ち運ぶこともできますが、パソコン扱いでの配信になるのでチャンネル登録数1000人以上の制限はありません。

エンコーダの項目を選択してライブ配信を行います。
[エンコーダでライブ配信を作成する](https://support.google.com/youtube/answer/2907883)に詳細が記載されていますので、これにそって進めます。
今回はラズパイがエンコーダということになります。

1. ライブ配信を有効にする -> 認証は先の手順で済ませました。24時間経っていればライブ配信画面に遷移できるはずです。
2. エンコーダをインストールする -> ffmpegをインストールしました。
3. ハードウェアを接続する -> 特にパソコンにつなぐものはありません。Raspberry Pi Zero Wを起動してSSHログインしてください。
4. エンコーダを接続してライブ配信を開始する -> ラズパイでコマンドを入力して配信を開始します。

**エンコーダ配信のダイアログでは公開設定を適切に設定してください。**
不特定多数の人が見ても構わないような配信であれば公開でも構いません。

エンコーダ配信の画面に遷移するとストリームキーが生成されます。これをコピーします。
このキーが漏洩すると誰でもあなたのチャンネルで動画を配信することができるようになってしまうので注意します。

ラズパイで以下のコマンドを実行して映像をYouTubeに流し込みます。



#### 4:3でカメラの撮影範囲すべてを表示したい場合

```shell
raspivid -w 1600 -h 1200 -fps 30 -o - -t 0 -b 2500000 | \
ffmpeg -re -ar 8k -ac 2 -c:a pcm_s16le -f s16le -ac 2 -i /dev/zero \
-f h264 -r 30 -i - \
-c:v copy -c:a copy -b:a 64k -g 60 -s 1600x1200 -f flv rtmp://a.rtmp.youtube.com/live2/[YOUR_STREAM_KEY]
```

コマンドを実行してしばらく待つとYoutube Liveの配信画面にラズパイからの映像が表示されます。
画面右上の「ライブ配信を開始」をクリックするとライブ配信が始まります。  
Youtubeの動画一覧画面を見るとライブ配信動画が表示されており、開くとURLが表示されます。
このURLにブラウザでアクセスすればカメラの映像を見ることができます。


## 音声のストリーミング（追記）
このままでは音声がありません。マイクを接続して音声入力できるようにします。

[USBオーディオアダプター(390円)](https://www.amazon.co.jp/gp/product/B01N4PBD66)を買ってマイクを繋げてみました。ただこのUSBオーディオアダプタ、入出力に"ビー"というようなノイズ音が乗ります……。
[USB microB-A変換ケーブル](https://www.amazon.co.jp/dp/B0197AP91S)も必要です（これは手持ちのものを使いました）。

USBオーディオアダプターを接続して`cat /proc/asound/cards`を実行すると以下のように`USB-Audio`が見えます。

```
$ cat /proc/asound/cards
 0 [ALSA           ]: bcm2835_alsa - bcm2835 ALSA
                      bcm2835 ALSA
 1 [Device         ]: USB-Audio - USB PnP Sound Device
                      C-Media Electronics Inc. USB PnP Sound Device at usb-20980000.usb-1, full speed
```

入力音量の調節のために上記`Device`に対してalsamixerコマンドを実行します。とりあえず音量を最大にしておきました。

```
$ alsamixer -c Device -V capture
```

次は試しに`arecord`で録音してみます。まずcard, deviceの番号を確認します。

```
$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

$ arecord -L
plughw:CARD=Device,DEV=0
    USB PnP Sound Device, USB Audio
    Hardware device with all software conversions
```

card 1, device 0であることが確認できたので以下の通り録音コマンドを実行します。終了するときはCtrl + cです。
test.wavを再生して音声が録音されていたら成功です。

```
arecord -D plughw:1,0 test.wav
```

最後にYoutube Liveへのストリーミングするコマンドです。
音声のサンプリングレートを8kHz(電話並み)、出力ビットレートを64kbpsにしています。thread_queue_sizeは試行錯誤でつけました。

```shell
raspivid -w 1920 -h 1080 -fps 30 -o - -t 0 -b 2500000 | \
ffmpeg \
-f alsa -ac 1 -ar 8000 -thread_queue_size 128 -i hw:1 \
-f h264 -r 30 -thread_queue_size 256 -i - \
-c:v copy -c:a aac -ar 8k -b:a 64k -g 60 -s 1920x1080 -threads 2 -f flv rtmp://a.rtmp.youtube.com/live2/[YOUR_STREAM_KEY]
```

ライブの管理画面で見ると途切れているようにも見えるのですが、動画はちゃんと音付きで流れています。（とりあえず良しとしました）


## おまけ

余談ですがRaspbian Busterではaptで入れられるffmpegがHWエンコードに対応しているようです。
[2018-10-09のリリースノート](http://downloads.raspberrypi.org/raspbian/release_notes.txt)に`Add hw acceleration to ffmpeg`とあります。
確認してみると以下のようにエンコーダーが表示されました。

```shell
$ ffmpeg -encoders 2>/dev/null | grep omx
V..... h264_omx             OpenMAX IL H.264 video encoder (codec h264)
```

1920x1080 30fpsの動画を少しだけエンコードしてみました。入力もmp4ですが。

ソフトウェアエンコード：

```shell
$ ffmpeg -i src.mp4 -c:v h264 dest.mp4

frame=   60 fps=0.3 q=29.0 size=     256kB time=00:00:01.87 bitrate=1118.1kbits/s speed=0.00792x
```

ハードウェアエンコード：

```shell
$ ffmpeg -i src.mp4 -c:v h264_omx dest.mp4

frame=   60 fps=3.1 q=-0.0 size=       0kB time=00:00:01.93 bitrate=   0.2kbits/s speed=0.101x
```

ハードウェアエンコードのほうが10倍くらい早いです。でも3.1fpsしか出ませんでした。


## 所感

実際に動かしてみて、映像横流ししてるだけではあるのですがカメラの入力をcopyするだけだとffmpegのCPU使用率が19%程度と少ないことに驚きました。
Raspberry Pi Zero Wでも余裕でライブ配信できますね。すごい。

> モバイルでライブ配信を行うには、チャンネル登録者数が 1,000 人以上である必要があります。

となっているのですが、ラズパイにバッテリーを繋いでテザリングすればモバイルじゃないけどモバイル配信できたりするんですかね。気になります。
配信中の電流を計測したら約0.3Aでした。3000mAhのバッテリーなら2時間くらい持ちそうです。

Youtubeでは撮影した動画をアーカイブしたり、[最大12時間巻き戻したりすることができる](https://support.google.com/youtube/answer/9296823?hl=ja)のも便利ですね。
それとffmpegのオプションを調べていましたが、多すぎて大変でした……。`ffmpeg -h full`をgrepしたりもしました。

参考：

- https://trac.ffmpeg.org/wiki/StreamingGuide
- https://trac.ffmpeg.org/wiki/Encode/H.264
- https://trac.ffmpeg.org/wiki/EncodingForStreamingSites