RTMP ストリームを Kinesis Video Streams へメディア形式で収集
Kinesis Video Streams(KVS) ではストリーミング方法として、メディア形式での収集と WebRTC の 2 種類があります。詳しくは AWS Black Belt Online Seminar を、さらに詳しくは ドキュメント をみてください。
本記事では KVS を使った動画配信についてメディア形式での収集を試してみます。
構成
非常に簡易な図ですが、このような構成を構築します。
この構成では、WiFi/4G/5G に接続している Mobile client(スマホ、今回は iPhone) のカメラから Amazon Elastic Compute Cloud(EC2) を経由し最終的に KVS へ動画データを配信します。
- スマホからクラウドへは RTMP Live Streaming を使用し動画データを送信
- クラウドの EC2 にインストールし起動済みの nginx で動画データを受信
- nginx で受信した動画データを、 GStreamer によりエンコーディングし、 KVS プラグインを利用して KVS へ配信
構築
EC2 インスタンスの構築
VPC, Subnet, Security Group などはすでにあるものとし、 EC2 インスタンスを Public Subnet に構築します。
- OS :
Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
- Instance Type : t3.large (ビルドしたりするので)
- Public IP : 18.xx.yy.94
- Security Group
- Inbound : 1935(rtmp), 22(ssh) を ソース IP 指定で開放
- Outbound : デフォルトで全てを開放
EC2 上での作業は、ターミナルで ssh した ubuntu ユーザーで実施します。
RTMP モジュールを使用した nginx のインストール
- apt 一覧及びパッケージの更新
$ sudo apt update && sudo apt upgrade
- nginx ビルドに必要なパッケージをインストール
$ sudo apt install cmake build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev
- 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
- RTMP プラグインのダウンロード
$ git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
- 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 プラグインのインストール
- 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
- ホームディレクトリに 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
- GStreamer Plugin(kvssink) のビルド
$ cd amazon-kinesis-video-streams-producer-sdk-cpp/build
$ cmake -DBUILD_GSTREAMER_PLUGIN=TRUE ..
$ make
インストール確認
- 環境変数を設定
$ 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
- 以下のコマンドで 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 パイプラインを実行するスクリプト作成
- 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"
}
}
- IAM ユーザーに KVS へフルアクセス権限ポリシーを割り当て (本番では最小権限を推奨)
$ aws iam attach-user-policy --user-name $IAM_USER --policy-arn arn:aws:iam::aws:policy/AmazonKinesisVideoStreamsFullAccess
- スクリプトに埋め込むためのアクセスキー、シークレットアクセスキーを生成
$ aws iam create-access-key --user-name $IAM_USER
{
"AccessKey": {
"UserName": "rtmp-test",
"AccessKeyId": "アクセスキー",
"Status": "Active",
"SecretAccessKey": "シークレットアクセスキー",
"CreateDate": "2021-06-29T10:27:39Z"
}
}
- nginx で受信した動画データを KVS へ配信する処理をするスクリプトを作成
- スクリプト内のシグナルのハンドリング処理は別途対応する必要
#!/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
- ファイルのユーザー/グループ変更と実行権限付与
$ sudo chown nobody:nogroup /opt/kvs-streamer.sh
$ sudo chmod u+x /opt/kvs-streamer.sh
- 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 起動ための準備
- nginx サービス登録
sudo vi /lib/systemd/system/nginx.service
ファイルの中身はこちらを参照してください。
- 作成したファイルのシンボリックリンクを作成
sudo ln -s /lib/systemd/system/nginx.service /etc/systemd/system/multi-user.target.wants/
- ログディレクトリの作成
sudo mkdir -p /var/log/nginx
- 以下コンテンツの nginx の設定ファイルを作成
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
}
}
}
- nginx 起動
$ sudo systemctl start nginx
nginx 確認
- 起動状態の確認
$ 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
- Server Url に
検証
カメラでの撮影とクラウドでの動画再生でどの程度の遅延が発生しているかを確認してみます。
まずは、お手元の PC で AWS コンソールにログインし、 Kinesis Video Streams へ移動します。初めて KVS をさわる場合はストリームは空で、RTMP Live Streaming を起動してクラウドへ接続したタイミングで、ストリームが作成されるかと思います。
作成されたストリームをクリックし、詳細画面内のメディア再生を開きストリームへ収集されている動画データをコンソールで確認します。遅延時間は環境に依存するので、全ての環境で同じ結果にはならないと認識しているが、今回の検証では 7 秒ほど遅延していることがわかります。
最後に
今回は、カメラから KVS へ GStreamer を使用したメディア形式の動画データの配信について試してみました。実際のプロジェクトでは、要件 (オンプレミスのサーバ有無や通信環境が安定して広帯域であるかなど) に沿って構成を検討していただき、今回の構成をそのまま利用してもいいかは検討する必要があるかと思いました。
Discussion