Amazon Kinesis Video Streams API/SDK による開発

Amazon Kinesis Video Streams を使ったアプリケーションを開発するための SDK について整理してみました。

※WebRTC については触れていません。

## 参考

- [Amazon Kinesis Video Streams 開発者ガイド](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams/latest/dg/what-is-kinesis-video.html)
- [AWS IoT 再入門ブログリレー Amazon Kinesis Video Streams編](https://dev.classmethod.jp/articles/re-introduction-iot-2021-amazon-kinesis-video-streams/)
- [Kinesis Video Streams API and Producer Libraries Support](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/how-it-works-kinesis-video-api-producer-sdk.html)

## API 構成

Amazon Kinesis Video Streams のストリームに対する配信、閲覧は以下の API を使用することで実現され、呼び出すための SDK が各種用意されています。

### Producer API

ストリームに映像を送信する API はひとつだけです。

![Producer API](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2022/02/08/748cca42-bfee-4d52-8ad5-7168efeba1dc.png)

- [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html) : ストリームにメディアデータをセグメント単位(1~10秒)で送信する
  - MKV 形式のみ
  - CLI: なし

PutMedia API は通常の API とは異なりセッションを張ったまま複数のやりとりをおこなう Long Running Session となっており、AWS CLI ではサポートされていません。基本的には SDK の使用が推奨されています。直接 API を叩く場合、以下のような処理を自前でおこなう必要があると思われます。

- 認証
- コネクションの管理 (コネクションの維持、再接続など)
- フロー制御 (レイテンシーを監視してフレームを破棄するなど)

### Consumer API

![Consumer API](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2022/11/24/4a346538-57d2-4684-a0a3-224b4d952be0.png)

- [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html) : メディアデータを取得する
  - 開始位置(日時/フラグメントなど)を指定し、それ以降を連続的に受信する。
  - 取得形式は MKV 形式のチャンクのため、解析には Parser Library を使用する。
  - CLI: [aws kinesis-video-media get-media](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-media/get-media.html)
- [ListFragments](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_ListFragments.html) : 指定範囲のフラグメントのリストを取得する
  - 開始日時、終了日時を指定
  - CLI: [aws kinesis-video-archived-media list-fragments](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/list-fragments.html)
- [GetMediaFromFragmentList](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetMediaForFragmentList.html) : 指定したフラグメントのメディアデータを取得する
  - フラグメント番号を指定 (フラグメントのリストから取得する)
  - CLI: [aws kinesis-video-archived-media get-media-for-fragment-list](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/get-media-for-fragment-list.html)
- [GetClip](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetClip.html) : 指定範囲の mp4 ファイルを取得する
  - 開始日時、終了日時を指定 (取得できるサイズに上限あり)
  - CLI: [aws kinesis-video-archived-media get-clip](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/get-clip.html)
- [GetImages](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetImages.html) : 画像(jpeg/png)を取得する
  - 開始日時、終了日時、取得間隔、フォーマットを指定
  - CLI: [aws kinesis-video-archived-media get-images](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/get-images.html)
- [GetDASHStreamingSessionURL](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetDASHStreamingSessionURL.html) : DASH 再生用 URL を取得する
  - CLI: [aws kinesis-video-archived-media get-dash-streaming-session-url](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/get-dash-streaming-session-url.html)
- [GetHLSStreamingSessionURL](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetHLSStreamingSessionURL.html) : HLS 再生用 URL を取得する
  - CLI: [aws kinesis-video-archived-media get-hls-streaming-session-url](https://docs.aws.amazon.com/cli/latest/reference/kinesis-video-archived-media/get-hls-streaming-session-url.html)

Consumer 側は AWS SDK で GetMedia/GetMediaFromFragmentList API を呼ぶことで、送信されたメディアデータにメタデータが付与されたチャンクという単位で読み出しをおこないますが、これを解析する Parser Library が別途用意されます。また mp4 ファイル形式や DASH/HLS で再生するための URL を取得する API も用意されています。

Consumer API を使った具体的な実装方法は別途、以下に整理しました。

- [Amazon Kinesis Video Streams から動画をリアルタイム受信して画像処理をおこなう (Java)](https://qiita.com/yh1224/items/114aa4017b009befff06)
- [Amazon Kinesis Video Streams から動画を受信して画像処理をおこなう (Python)](https://qiita.com/yh1224/items/563f90c62fe7b177d102)

## SDK のビルド

Amazon Kinesis Video Streams に対する SDK は以下のリポジトリに分かれています。

- [CPP Producer, GStreamer Plugin and JNI](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp) (C++/Streamerプラグイン/JNI)
- [Producer SDK Java](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java) (Java)
- [C Producer](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/) (C)
- [PIC](https://github.com/awslabs/amazon-kinesis-video-streams-pic) (プラットフォーム非依存部)

### CPP Producer / GStreamer Plugin / JNI

Producer Library (CPP Producer) と、GStreamer 用のプラグイン、Java 用の JNI (インターフェイス)がビルドできるプロジェクトです。

- リポジトリ) [Amazon Kinesis Video Streams CPP Producer, GStreamer Plugin and JNI](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp)

#### CPP Producer / GStreamer Plugin / JNI のビルド準備

Debian GNU/Linux の場合

```shell
apt-get install -y cmake g++ git m4 make pkg-config

# JNI もビルドする場合
apt-get install -y openjdk-11-jdk

# GStreamer Plugin もビルドする場合
apt-get install -y 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
```

macOS の場合

```shell
brew install cmake git log4cplus make pkg-config

# JNI もビルドする場合
brew install adoptopenjdk11

# GStreamer Plugin もビルドする場合
brew install gstreamer gst-plugins-base \
  gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav \
  log4cplus openssl
```


#### CPP Producer / GStreamer Plugin / JNI のビルド

```shell
git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git
cd amazon-kinesis-video-streams-producer-sdk-cpp
mkdir -p build
cd build
cmake .. \
  -DBUILD_JNI=ON \
  -DBUILD_GSTREAMER_PLUGIN=ON
make
```

ビルド結果は以下に出力されます。 (macOS の場合は .dylib)

- CPP Producer) libKinesisVideoProducer.so
- JNI) libKinesisVideoProducerJNI.so
- JStreamer プラグイン) libgstkvssink.so
- 依存ライブラリ
  - dependency/libkvscproducer/kvscproducer-src/libcproducer.so
  - open-source/local/lib 配下

#### CPP Producer の動作確認

```shell
export AWS_DEFAULT_REGION=ap-northeast-1
export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
tst/producerTest
```

テスト用のサンプルソースは tst/ProducerTestFixture.h に書かれています。

#### GStreamer Plugin の動作確認

GST_PLUGIN_PATH にビルドしたライブラリのあるパスを指定することで、GStreamer から認識されます。

```shell
export GST_PLUGIN_PATH=$(pwd)/build
export LD_LIBRARY_PATH=$(pwd)/open-source/local/lib
gst-inspect-1.0 kvssink
```

### Producer SDK Java

- リポジトリ) [Amazon Kinesis Video Streams Producer SDK Java](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java/)

#### Producer SDK Java のビルド準備

Debian GNU/Linux 11 の場合

```shell
apt-get install -y maven
```

macOS の場合

```shell
brew install maven
```

#### Producer SDK Java のビルド

```shell
git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java.git
cd amazon-kinesis-video-streams-producer-sdk-java
mvn compile assembly:single
```

#### Producer SDK Java の動作確認

src/main/demo/com/amazonaws/kinesisvideo/demoapp/DemoAppMain.java を書き換えて、適切なリージョンおよび認証情報を使用するよう修正します。

例)

```java
final KinesisVideoClient kinesisVideoClient = KinesisVideoJavaClientFactory
        .createKinesisVideoClient(Regions.AP_NORTHEAST_1, new ProfileCredentialsProvider());
```

実行

```shell
JAVA_LIBRARY_PATH=$(cd "../amazon-kinesis-video-streams-producer-sdk-cpp/build"; pwd)
STREAM_NAME=stream-test
java \
  -classpath target/amazon-kinesis-video-streams-producer-sdk-java-1.11.0-jar-with-dependencies.jar \
  -Djava.library.path=${JAVA_LIBRARY_PATH} \
  -Dkvs-stream=${STREAM_NAME} \
  com.amazonaws.kinesisvideo.demoapp.DemoAppMain
```

src/main/resources/data/h264/ 配下の動画ファイルが、指定されたストリームに送信されます。

### C Producer

上記の C++/Java 用ライブラリとは別のリポジトリに、ベースとなる C 言語版が存在します。

- リポジトリ) [Amazon Kinesis Video Streams C Producer](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/)

```shell
git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git
cd amazon-kinesis-video-streams-producer-c
mkdir build 
cd build
cmake ..
make
```

試してはいません。