💨

RTMP ストリームを Kinesis Video Streams へメディア形式で収集

2021/06/30に公開

Kinesis Video Streams(KVS) ではストリーミング方法として、メディア形式での収集と WebRTC の 2 種類があります。詳しくは AWS Black Belt Online Seminar を、さらに詳しくは ドキュメント をみてください。
本記事では KVS を使った動画配信についてメディア形式での収集を試してみます。

構成

非常に簡易な図ですが、このような構成を構築します。

構成

この構成では、WiFi/4G/5G に接続している Mobile client(スマホ、今回は iPhone) のカメラから Amazon Elastic Compute Cloud(EC2) を経由し最終的に KVS へ動画データを配信します。

  1. スマホからクラウドへは RTMP Live Streaming を使用し動画データを送信
  2. クラウドの EC2 にインストールし起動済みの nginx で動画データを受信
  3. nginx で受信した動画データを、 GStreamer によりエンコーディングし、 KVS プラグインを利用して KVS へ配信

構築

EC2 インスタンスの構築

VPC, Subnet, Security Group などはすでにあるものとし、 EC2 インスタンスを Public Subnet に構築します。

  • OS : Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
    • OS
  • Instance Type : t3.large (ビルドしたりするので)
  • Public IP : 18.xx.yy.94
  • Security Group
    • Inbound : 1935(rtmp), 22(ssh) を ソース IP 指定で開放
    • Outbound : デフォルトで全てを開放

EC2 上での作業は、ターミナルで ssh した ubuntu ユーザーで実施します。

RTMP モジュールを使用した nginx のインストール

  1. apt 一覧及びパッケージの更新
$ sudo apt update && sudo apt upgrade
  1. nginx ビルドに必要なパッケージをインストール
$ sudo apt install cmake build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev
  1. nginx のダウンロードと展開
$ wget http://nginx.org/download/nginx-1.20.1.tar.gz (http://nginx.org/download/nginx-1.19.10.tar.gz)
$ tar zxvf nginx-1.20.1.tar.gz
  1. RTMP プラグインのダウンロード
$ git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
  1. RTMP モジュールを含んだ nginx のビルド及びインストール
$ cd nginx-1.20.1
$ ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --add-module=../nginx-rtmp-module/
$ make
$ sudo make install

インストール確認

  • nginxが正常にインストールされているか確認
$ nginx -V
nginx version: nginx/1.20.1
built by gcc 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --add-module=../nginx-rtmp-module/

GStreamer と KVS プラグインのインストール

  1. GStreamer ビルドに必要なパッケージをインストール (GStreamer のコアライブラリはここでインストール)
$ sudo apt install libssl-dev libcurl4-openssl-dev liblog4cplus-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base-apps gstreamer1.0-plugins-bad gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-tools
  1. ホームディレクトリに Amazon Kinesis Video Streams CPP Producer, GStreamer Plugin and JNI をダウンロード
$ cd
$ git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git
  1. GStreamer Plugin(kvssink) のビルド
$ cd amazon-kinesis-video-streams-producer-sdk-cpp/build
$ cmake -DBUILD_GSTREAMER_PLUGIN=TRUE ..
$ make

インストール確認

  1. 環境変数を設定
$ export GST_PLUGIN_PATH=/home/ubuntu/amazon-kinesis-video-streams-producer-sdk-cpp/build
$ export LD_LIBRARY_PATH=/home/ubuntu/amazon-kinesis-video-streams-producer-sdk-cpp/open-source/local/bin:$LD_LIBRARY_PATH
  1. 以下のコマンドで KVS プラグインがインストールされているか確認
$ gst-inspect-1.0 kvssink
Factory Details:
  Rank                     primary + 10 (266)
  Long-name                KVS Sink
  Klass                    Sink/Video/Network
  Description              GStreamer AWS KVS plugin
  Author                   AWS KVS <kinesis-video-support@amazon.com>

Plugin Details:
  Name                     kvssink
  Description              GStreamer AWS KVS plugin
  Filename                 /home/ubuntu/amazon-kinesis-video-streams-producer-sdk-cpp/build/libgstkvssink.so
  Version                  1.0
  License                  Proprietary
  Source module            kvssinkpackage
  Binary package           GStreamer
  Origin URL               http://gstreamer.net/
・・・

GStreamer パイプラインを実行するスクリプト作成

  1. IAM ユーザーを作成
$ export IAM_USER=rtmp-test # ユーザー名は適当
$ aws iam create-user --user-name $IAM_USER
{
    "User": {
        "Path": "/",
        "UserName": "rtmp-test",
        "UserId": "AIDAUJDL34IZ4JOUTGABI",
        "Arn": "arn:aws:iam::<AWS アカウント ID>:user/rtmp-test",
        "CreateDate": "2021-06-29T10:27:11Z"
    }
}
  1. IAM ユーザーに KVS へフルアクセス権限ポリシーを割り当て (本番では最小権限を推奨)
$ aws iam attach-user-policy --user-name $IAM_USER --policy-arn arn:aws:iam::aws:policy/AmazonKinesisVideoStreamsFullAccess
  1. スクリプトに埋め込むためのアクセスキー、シークレットアクセスキーを生成
$ aws iam create-access-key --user-name $IAM_USER
{
    "AccessKey": {
        "UserName": "rtmp-test",
        "AccessKeyId": "アクセスキー",
        "Status": "Active",
        "SecretAccessKey": "シークレットアクセスキー", 
        "CreateDate": "2021-06-29T10:27:39Z"
    }
}
  1. nginx で受信した動画データを KVS へ配信する処理をするスクリプトを作成
  • スクリプト内のシグナルのハンドリング処理は別途対応する必要
/opt/kvs-streamer.sh
#!/bin/bash

export GST_PLUGIN_PATH=/home/ubuntu/amazon-kinesis-video-streams-producer-sdk-cpp/build
export LD_LIBRARY_PATH=/opt/amazon-kinesis-video-streams-producer-sdk-cpp/open-source/local/lib:$LD_LIBRARY_PATH
export PATH=/opt/amazon-kinesis-video-streams-producer-sdk-cpp/open-source/local/bin:$PATH

export AWS_REGION=ap-northeast-1
export AWS_ACCESS_KEY="これは create-access-key コマンド実行結果のアクセスキー"
export AWS_SECRET_KEY="これは create-access-key コマンド実行結果のシークレットアクセスキー"

/usr/bin/gst-launch-1.0 -v rtmpsrc name=rtmpsrc blocksize=1024 do-timestamp=true location="rtmp://localhost:1935/$1/$2" ! flvdemux name=demux demux.video ! h264parse ! video/x-h264, format=avc,alignment=au ! kvssink log-config=/opt/kvs-log-config stream-name=$2 storage-size=512 aws-region="${AWS_REGION}" access-key="${AWS_ACCESS_KEY}" secret-key="${AWS_SECRET_KEY}" >> /tmp/$1-$2.log &

wait
  1. ファイルのユーザー/グループ変更と実行権限付与
$ sudo chown nobody:nogroup /opt/kvs-streamer.sh
$ sudo chmod u+x /opt/kvs-streamer.sh
  1. config を作成 (このファイル をコピーし、適宜編集してください)
/opt/kvs-log-config
log4cplus.rootLogger=DEBUG, KvsConsoleAppender, KvsFileAppender

#log4cplus.logger.MemoryCheck=TRACE, KvsConsoleAppender

#KvsConsoleAppender:
log4cplus.appender.KvsConsoleAppender=log4cplus::ConsoleAppender
log4cplus.appender.KvsConsoleAppender.layout=log4cplus::PatternLayout
log4cplus.appender.KvsConsoleAppender.layout.ConversionPattern=[%-5p] [%d{%d-%m-%Y %H:%M:%S:%Q %Z}] %m%n

#KvsFileAppender
log4cplus.appender.KvsFileAppender=log4cplus::DailyRollingFileAppender
log4cplus.appender.KvsFileAppender.File=/tmp/kvs.log
log4cplus.appender.KvsFileAppender.Schedule=HOURLY
log4cplus.appender.KvsFileAppender.CreateDirs=true
log4cplus.appender.KvsFileAppender.layout=log4cplus::PatternLayout
log4cplus.appender.KvsFileAppender.layout.ConversionPattern=[%-5p] [%d{%d-%m-%Y %H:%M:%S:%Q %Z}] %m%n

nginx 起動ための準備

  1. nginx サービス登録
sudo vi /lib/systemd/system/nginx.service

ファイルの中身はこちらを参照してください。

  1. 作成したファイルのシンボリックリンクを作成
sudo ln -s /lib/systemd/system/nginx.service /etc/systemd/system/multi-user.target.wants/
  1. ログディレクトリの作成
sudo mkdir -p /var/log/nginx
  1. 以下コンテンツの nginx の設定ファイルを作成
/etc/nginx/conf/nginx.conf
worker_processes  1;
error_log /var/log/nginx/error.log;

pid /run/nginx.pid;

events {
    worker_connections  1024;
}

# RTMP configuration
rtmp {
    server {
	listen 1935;
	chunk_size 8192;

	# Application configuration
	application live {
	    live on;
	    record off;
	    meta copy;

	    exec /opt/kvs-streamer.sh $app $name
	}
    }
}
  1. nginx 起動
$ sudo systemctl start nginx

nginx 確認

  1. 起動状態の確認
$ sudo systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-06-29 10:16:39 UTC; 4s ago
    Process: 70836 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 70848 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 70849 (nginx)
      Tasks: 2 (limit: 9418)
     Memory: 1.8M
     CGroup: /system.slice/nginx.service
             ├─70849 nginx: master process /usr/sbin/nginx
             └─70851 nginx: worker process

スマホへの RTMP Live Streaming 設定

アプリケーションは事前にインストールされているものとします。

  • 設定画面 (例)
    • Server Url に rtmp://<EC2 の Public IP>:1935/live
    • Stream name/key に stream

RTMP 送信先設定

検証

カメラでの撮影とクラウドでの動画再生でどの程度の遅延が発生しているかを確認してみます。

まずは、お手元の PC で AWS コンソールにログインし、 Kinesis Video Streams へ移動します。初めて KVS をさわる場合はストリームは空で、RTMP Live Streaming を起動してクラウドへ接続したタイミングで、ストリームが作成されるかと思います。

Kinesis Video Streams ストリーム一覧

作成されたストリームをクリックし、詳細画面内のメディア再生を開きストリームへ収集されている動画データをコンソールで確認します。遅延時間は環境に依存するので、全ての環境で同じ結果にはならないと認識しているが、今回の検証では 7 秒ほど遅延していることがわかります。

Kinesis Video Streams ストリーム詳細 - メディア再生

最後に

今回は、カメラから KVS へ GStreamer を使用したメディア形式の動画データの配信について試してみました。実際のプロジェクトでは、要件 (オンプレミスのサーバ有無や通信環境が安定して広帯域であるかなど) に沿って構成を検討していただき、今回の構成をそのまま利用してもいいかは検討する必要があるかと思いました。

Discussion