THETA S + Raspberry Pi 2でライブストリーミングしてみた

# THETA S + Raspberry Pi 2でライブストリーミングしてみた

## 前書き
こんにちは、[syumai](http://qiita.com/syumai)です。
現在、[DUCKLINGS Inc.](http://ducklings.jp/)と言う会社で研究開発のアルバイトをしています。
DUCKLINGSでは、遠隔地にいる体の不自由な方とのコミュニケーションを、VR技術で解決しようという[HUG Project](http://hugproject.net/)に取り組んでいます。
今回、その一環としてTHETA Sを利用した動画配信について調査を行いました。

## 本題
THETA Sの映像をRaspberry Pi 2に**USB経由**で取り込み、
無線LAN経由で、同じネットワーク内のPCにRTPで配信します。

※…HDMIのキャプチャーは**大きな困難**が伴いそうなので、今回の範囲外となります。Advent Calendarの他の日に誰かがやってくれるかと…笑

## 必要なもの
* PC(受信用)
* THETA S
* Raspberry Pi 2 一式(Raspbian環境)

配信側を無線にしたい場合は、以下の物を準備する必要があります。

* USB接続のWiFi子機
* モバイルバッテリー

今回は、Buffaloの無線LANアダプタ、Panasonicのモバイルバッテリーを用意して、持ち運び出来るようにしました。
![theta_s.png](https://qiita-image-store.s3.amazonaws.com/0/45427/63c6860f-8ac2-4bcb-997a-b44e777bb33c.png)


## 概要
USBカメラとして認識したTHETA Sの映像を、
OpenMAXプラグインを利用してH.264にハードウェアエンコードし、
GStreamerを使ってRTPで配信します。

## 参考にしたページ
[raspberry pi で USB camera から h.264 動画 - Qiita (kwiさん)](http://qiita.com/kwi/items/36a5233d4ab31c015f8a)
[Raspberry Pi - Gstreamer streaming H.264 with OpenMax](http://emmanuelgranatello.blogspot.jp/2013/10/raspberry-pi-gstreamer-streaming-h264.html)

## 手順

### Raspberry Pi 2側
大体[kwiさんの記事](http://qiita.com/kwi/items/36a5233d4ab31c015f8a)に書いてある通りですが、
まずはRaspbianと、GStreamerをインストールします。

#### Raspbianのインストール
多くの方は既にインストール済みだと思いますが、
https://www.raspberrypi.org/downloads/raspbian/
からダウンロードしてSDに書き込みます。
今回はJessie(2015-09-24)を使いました。

#### GStreamerのインストール

```bash
sudo apt-get install gstreamer1.0 gstreamer1.0-tools
```

#### THETA Sの接続

THETA SをLiveモードにして接続します。
(モード切り替えボタンを押しながら電源をONにし、USB接続)

v4l2(Video for Linux 2)を使用し、カメラとして認識されたか確認します。

```bash
v4l2-ctl --list-devices
```

出力

```bash
RICOH THETA S (usb-bcm2708_usb-1.4):
	/dev/video0
```

今回は、`/dev/video0`がTHETA Sの(カメラデバイスとしての)パスになっていることがわかりました。
(他に接続しているカメラがあれば、video1やvideo2になっている場合があります。)

```bash
Failed to open /dev/video0: No such file or directory
```

この様に表示されたら、THETA Sを接続し直してください。

次に、THETA Sで利用できるビデオの取り込み形式を確認します。
`-d /dev/video0`でデバイスをTHETA Sとして指定し、そのフォーマットを表示します。(video0の場合、デバイスの指定は省略可能です)

```bash
v4l2-ctl -d /dev/video0 --list-formats
```

出力

```bash
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : MJPEG
```

--list-formats-extオプションで、画像の解像度とフレームレートも確認可能です。

```bash
v4l2-ctl -d /dev/video0 --list-formats-ext
```

出力

```bash
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : MJPEG
		Size: Discrete 1280x720
			Interval: Discrete 0.067s (14.985 fps)
```

1280x720の約15fpsで、MJPG形式の画像を取得出来ることが確認出来ました。

#### プレビュー

配信に使うツールが正しくインストールされているか、gst-inspect-1.0で確認します。

```
$ gst-inspect-1.0 | grep v4l2src
video4linux2:  v4l2src: Video (video4linux2) Source

$ gst-inspect-1.0 | grep omxh264
omx:  omxh264enc: OpenMAX H.264 Video Encoder
omx:  omxh264dec: OpenMAX H.264 Video Decoder
```
`v4l2src`, `omxh264enc`があればOKです。

※…OpenMAXのエンコーダを利用すると、Raspberry Pi 2のSoCに内蔵されたエンコーダが走るので、高速に動画の圧縮ができる（らしい）です。これを使わないと、尋常じゃない遅延と、低フレームレートに苦しむ事になります…。

ここで一度、THETA Sの動画が正しく表示出来るか確認します。
sshでRaspberry Pi 2に接続している場合は、この手順はスキップしてください。
(例によって`device='/dev/video0'`は省略可)

```bash
gst-launch-1.0 v4l2src device='/dev/video0' ! autovideosink
```

物凄いフレームレート低い(&遅延あり)ですが、画面にTHETA Sの映像が表示されると思います。

ここまででRaspberry Pi 2側での確認は終了です。


### PC側(Mac)

Homebrewで、GStreamerを各種プラグインとセットでインストールします。

```bash
brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav
```

## 配信
今回、ポート番号は1234としておきます。

### PC側(Mac)

こちらを入力して待ち受けます。

```bash
gst-launch-1.0 udpsrc port=1234 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! rtph264depay ! avdec_h264 ! autovideosink sync=false
```

### Raspberry Pi 2側

以下の内容を、`stream.sh`などの適当な名前のファイルとして保存してください。
(`chmod +x ./stream.sh`で実行権限を付けるのを忘れずに)

```bash
gst-launch-1.0 v4l2src ! videoconvert ! omxh264enc ! rtph264pay pt=96 config-interval=1 ! udpsink host=$1 port=$2
```

第一引数に送信先のIPアドレス、第二引数にポート番号を渡して実行します。

```bash
./stream.sh {送信先IPアドレス} 1234
```

![theta_s_preview.png](https://qiita-image-store.s3.amazonaws.com/0/45427/435df9b1-5dbb-3a49-4aaa-aa69fbf8c6a8.png)

PC側に映像が表示されました！

## 終わりに
ひとまず、これでRTPでの動画送信は出来ました。
無線環境下でも使えるので、結構取り回しが良いです。

GStreamerの使い方はまだあまり良くわかっていない（と言うより、ほとんどわかっていない…）ので、突っ込みどころなどありましたらどうぞよろしくお願いします…m(_ _)m

今度は、受信した動画をUnityで表示するものを作ってみようと思います。(Oculusで見れたらいいな…)

## 追記
1月末のTHETA S Advent Calendar LT大会にて発表した、
『THETA S + Raspberry pi 2でライブストリーミングしてみた（続） 』のスライドをアップしました。
http://www.slideshare.net/ShuichiroFukuoka/theta-s-raspberry-pi-2