Amazon Kinesis Video Streamsを使ってストリーム映像をAWS上に流してみる【Raspberry Pi】– ClassmethodサーバーレスAdvent Calendar 2017 #serverless #adventcalendar #reinvent

2017.12.22

西田@大阪です。今回は Raspberry pi から Kinesis Video Streams にストリームデータを送信したいと思います

このエントリはServerless Advent Calendar 2017 22日目の記事です

以前 西村祐二 が書いた下記ブログの Raspberry Pi 版です

Amazon Kinesis Video Streamsを使ってストリーム映像をAWS上に流してみる【MacBook Pro】– ClassmethodサーバーレスAdvent Calendar 2017 #serverless #adventcalendar #reinvent

基本的には以下の参考資料にそって進めていきます

前準備

この記事はカメラモジュールを接続した Raspberry Pi でSSHに接続できる状態であることを前提としています

試した環境

Raspberry Pi3 Model B

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.1 (stretch)
Release:    9.1
Codename:   stretch
$ uname -a
Linux raspberrypi 4.9.70-v7+ #1068 SMP Mon Dec 18 22:12:55 GMT 2017 armv7l GNU/Linux

Kinesis Video Streams を用意

任意のストリーム名を入力し、デフォルト設定の使用にチェックが入ってることを確認し作成します

Raspberry Pi が使う IAM User を作成し、インラインポリシーに以下の権限を設定します

Getting Started にはkinesisvideo:TagStreamが無いですが、実際にテストを通すためには必要でした

{
    "Statement": [
        {
            "Action": [
                "kinesisvideo:DescribeStream", 
                "kinesisvideo:CreateStream", 
                "kinesisvideo:GetDataEndpoint", 
                "kinesisvideo:PutMedia", 
                "kinesisvideo:TagStream"
            ], 
            "Effect": "Allow", 
            "Resource": [
                "*"
            ]
        }
    ], 
    "Version": "2012-10-17"
}

Kinesis Video Streams のデモアプリをRaspberry Pi にインストール

まずは、Raspberry PiにSSHでログインします

$ ssh pi@<Raspberry PiのIP> 

githubよりサンプルアプリケーションをgit cloneしてダウンロードします

$ git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cp

必要なライブラリをインストールします

$ sudo apt-get update
$ sudo apt-get install autoconf cmake bison automake libtool gcc flex

ビルドするためにディレクトリを移動します

cd amazon-kinesis-video-streams-producer-sdk-cpp/kinesis-video-native-build

Raspberry Piをアプデートします ※ 必ずしも必要ではありません

$ sudo rpi-update

JAVA_HOMEを設定しないとfatal error: jni.h: そのようなファイルやディレクトリはありませんとエラーになるためJAVA_HOMEを設定します。筆者の環境では以下のディレクトリにJavaが置かれていました

$ export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/

このままだと./startを実行してテストが走った時に1GiB以上メモリを確保しようとして、512MiBしかない Raspberry Pi 3 Model B だとSegmentation faultを起こしてしまいます

heapInitialize(): Initializing native heap with limit size 1073741824, spill ratio 0% and flags 0x00000001
Segmentation fault

確保するメモリを以下のファイルを編集し256MiBにします

$ vi ../kinesis-video-producer/tst/ProducerTestFixture.h
-#define TEST_STORAGE_SIZE_IN_BYTES                          1024 * 1024 * 1024ull
+#define TEST_STORAGE_SIZE_IN_BYTES                          256 * 1024 * 1024ull

ビルドを行います(3-4時間ほどかかります。。。)

$ ./install-script

AWSの接続情報を環境変数に設定します

$ export AWS_ACCESS_KEY_ID=<ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<SECRET_ACCESS_KEY>

テストを実行します

$ ./start

テストが成功すると以下のように出力されます

[----------] 1 test from ProducerApiTest (186483 ms total)

[----------] Global test environment tear-down
[==========] 308 tests from 30 test cases ran. (194841 ms total)
[  PASSED  ] 308 tests.
INFO - Curl shutdown.

最後に以下のコマンドでフ/dev/video以下にファイルが置かれていることを確認します

$ ls /dev/video*

もしファイルが存在しないまま配信を実行するとUnable to set the pipeline to the playing state. というエラーがでてしまうため以下のコマンドを実行しファイルを生成します

$ vcgencmd get_camera
$ sudo modprobe bcm2835-v4l2

動画を配信する

./kinesis_video_gstreamer_sample_app <ストリーム名>

動画配信している Raspberry Piを自撮り

かなりラグがあるものの一応配信できてます

試行錯誤し以下のパラメーターを調整すると少しだけマシになりました

$ vi ../kinesis-video-gst-demo/kinesis_video_gstreamer_sample_app.cpp
diff --git a/kinesis-video-gst-demo/kinesis_video_gstreamer_sample_app.cpp b/kinesis-video-gst-demo/kinesis_video_gstreamer_sample_app.cpp
index 694f90b..92212da 100644
--- a/kinesis-video-gst-demo/kinesis_video_gstreamer_sample_app.cpp
+++ b/kinesis-video-gst-demo/kinesis_video_gstreamer_sample_app.cpp
@@ -92,7 +92,7 @@ public:
     device_info_t getDeviceInfo() override {
         auto device_info = DefaultDeviceInfoProvider::getDeviceInfo();
         // Set the storage size to 256mb
-        device_info.storageInfo.storageSize = 512 * 1024 * 1024;
+        device_info.storageInfo.storageSize = 256 * 1024 * 1024;
         return device_info;
     }
 };
@@ -334,9 +334,9 @@ int gstreamer_init(int argc, char* argv[]) {

     /* source filter */
     GstCaps *source_caps = gst_caps_new_simple("video/x-raw",
-                                               "width", G_TYPE_INT, 1280,
-                                               "height", G_TYPE_INT, 720,
-                                               "framerate", GST_TYPE_FRACTION, 30, 1,
+                                               "width", G_TYPE_INT, 640,
+                                               "height", G_TYPE_INT, 360,
+                                               "framerate", GST_TYPE_FRACTION, 10, 1,
                                                NULL);
     g_object_set(G_OBJECT (data.source_filter), "caps", source_caps, NULL);
     gst_caps_unref(source_caps);
@@ -354,9 +354,9 @@ int gstreamer_init(int argc, char* argv[]) {
                                              "profile", G_TYPE_STRING, "baseline",
                                              "stream-format", G_TYPE_STRING, "avc",
                                              "alignment", G_TYPE_STRING, "au",
-                                             "width", G_TYPE_INT, 1280,
-                                             "height", G_TYPE_INT, 720,
-                                             "framerate", GST_TYPE_FRACTION, 30, 1,
+                                             "width", G_TYPE_INT, 640,
+                                             "height", G_TYPE_INT, 360,
+                                             "framerate", GST_TYPE_FRACTION, 10, 1,

さいごに

いかがでしたでしょうか?

Kinesis Video Streams を使うと Raspberry Pi での動画配信がとても簡単に実現できます。普段の誰も居ないときのペットの姿を見たり、Amazon Rekognition Video を使った解析など用途はいろいろあるのではないでしょうか?

次回はAmazon Rekognition Video を使った解析を使って Raspberry Pi の動画解析をやってみたいと思います