Amazon Kinesis Video Streams にUbuntu上のUSBカメラから動画配信するコンテナを作りました
この記事の最後に、作成したdockerfileとcompose.yamlを貼ります。経緯とかに興味ない人は飛んでください
作った経緯
Amazon Kinesis Video Streamsに動画を配信したいという要件があり、使い方を調べてみました。
Amazon Kinesis Video Streams は、接続されたデバイス上で構築、設定できる C++ および Java の SDK を提供します。
C++とかJavaとか普段使わないのでつらい
SDK は GStreamer プラグインとしても利用可能で、カスタムメディアデータフローの構築ができます。
GStreamerというやつを使えば、C++とかJavaを使わなくても配信できるらしい
SDK はソースから構築するか、または Ubuntu、MacOS、Raspberry Pi デバイスで使える Docker イメージを用いて簡単な Docker プルでデプロイでき、わずか数分でストリーミングビデオを開始できます。
ソースから構築はツラいので、Dockerイメージを使おう
AWS提供のDockerイメージで、ネットワークカメラの動画を配信してみた
C++やJAVAは知見がないしプラグインをソースから構築するのが面倒くさそうなので、AWS提供のDockerイメージを使ってネットワークカメラの動画を配信してみました。
Dockerイメージの使い方がこちら
Dockerイメージ内から配信するコマンドのこちら
いやー、、、ドキュメント分かりにくいし、Dockerイメージ使うにしては面倒くさくないか?
面倒くさいので、compose.yamlを作った
# dockerイメージをダウンロードする際は、事前に下記コマンドでecrにloginしてください。
# $ aws ecr get-login-password --region us-west-2 | docker login -u AWS --password-stdin https://546150905175.dkr.ecr.us-west-2.amazonaws.com
services:
gstreamer:
image: 546150905175.dkr.ecr.us-west-2.amazonaws.com/kinesis-video-producer-sdk-cpp-amazon-linux
network_mode: host
env_file: .env
command: /bin/bash -c "./kvs_gstreamer_sample ${VIDEO_STREAM_NAME} ${RTSP_URL}"
AWS_DEFAULT_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=(AWSのアクセスキー)
AWS_SECRET_ACCESS_KEY=(AWSのシークレットアクセスキー)
VIDEO_STREAM_NAME=(Kinesis Video Streamのリソース名)
RTSP_URL=(ネットワークカメラのURL)
配信出来でました。(画質が低いわけではなく、プライバシー保護のためモザイクをかけております)
いやいやいや、10秒以上の遅延って遅くない?
ググって調べた感じ普通にそのくらい遅延するみたいではあるのですが、やっぱり遅いなぁと。WebRTCを使えば早くなるだろうけど、AWS上に一定期間動画を保存しておきたかったので却下。
それで思ったことが、
- ネットワークカメラだと
カメラ->PC->AWS
の経路でネットワークを2回通るから遅くなるのでは? - USBカメラなら遅延が減るのでは?
USBカメラ試してみた
ということで、ネットワークカメラからの動画配信は遅延が大きかったので、USBカメラの動画をAWS提供のDockerイメージを使って配信しようとしました。
ですが、母艦がMacやWindowsの場合はコンテナ内からカメラを認識できないという問題があります。母艦からコンテナ内に動画を送りつける方法は無くはないですが、それは結局遅延するので却下。
・・・・・・
仕方がないのでUbuntuのPCを用意しました。母艦がLinuxならコンテナ内からでもカメラが使えますので、AWS提供のUbuntu向けDockerイメージを使って配信しようとしました。
その結果、、、
glib.GError: no element "x264enc"
動画のエンコードでエラーになりました。
gst-inspect x264enc
No such element or plugin 'x264enc'
AWS提供のコンテナ、エンコーダーが認識されてないじゃん。。。PATHが通ってないんじゃないかとか、手動でインストールしたら動くんじゃないかとかイロイロ試したのですが、結局動かずでした。前述のネットワークカメラの場合はカメラ側で動画エンコードをしていたのでこの問題は発生しませんでした。
(Ubuntu向けのDockerイメージがAmazon Linuxベースで作られているのがよくないのでは?)
USBカメラは動画エンコードができる高級品ではないのでアプリ側でエンコードしてから配信する必要があります。でも、AWSが用意したDockerイメージを使うとエンコーダーが動かない。。。もういいや。。。公式に頼らず自力でビルドしてContainerイメージを作ろう。。。
と判断して作ったものが以下です。
作ったもの
FROM ubuntu:22.04 AS base
# ビルドと実行の両方に共通するライブラリをインストール
RUN apt-get update && \
apt-get install -y \
libgstreamer-plugins-base1.0-dev
FROM base AS build
WORKDIR /kinesis_video
# ビルドに必要なものをインストール
RUN apt-get update && \
apt-get install -y \
cmake m4 git build-essential \
default-jdk
# ソースコードをclone
RUN git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git
# ビルド
RUN mkdir ./amazon-kinesis-video-streams-producer-sdk-cpp/build
RUN cd ./amazon-kinesis-video-streams-producer-sdk-cpp/build && \
cmake .. -DBUILD_GSTREAMER_PLUGIN=ON -DBUILD_JNI=TRUE && \
make
FROM base AS runtime
WORKDIR /kinesis_video
# ビルドしたものをコピー(buildとlibだけだとエラーになったので、全部持ってくる)
COPY /kinesis_video/amazon-kinesis-video-streams-producer-sdk-cpp /kinesis_video/amazon-kinesis-video-streams-producer-sdk-cpp
# ライブラリのパスを通す
ENV LD_LIBRARY_PATH=/kinesis_video/amazon-kinesis-video-streams-producer-sdk-cpp/open-source/local/lib
ENV GST_PLUGIN_PATH=/kinesis_video/amazon-kinesis-video-streams-producer-sdk-cpp/build
# 必要なgstreamerのプラグインをインストール
RUN apt-get update && \
apt-get install -y \
gstreamer1.0-plugins-base-apps \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-ugly \
gstreamer1.0-plugins-bad
# 何故かsslエラーになるので再インストールする
RUN apt-get reinstall -y ca-certificates && \
update-ca-certificates
services:
kinesis-video-stream:
build: .
env_file: .env
devices:
- "/dev/video0:/dev/video0"
command: /bin/bash -c 'gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! video/x-raw,format=I420,width=640,height=480,framerate=30/1 ! x264enc bframes=0 key-int-max=45 bitrate=500 tune=zerolatency ! video/x-h264,stream-format=avc,alignment=au ! kvssink stream-name=${VIDEO_STREAM_NAME} storage-size=128 access-key=${AWS_ACCESS_KEY_ID} secret-key=${AWS_SECRET_ACCESS_KEY}'
AWS_DEFAULT_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=(AWSのアクセスキー)
AWS_SECRET_ACCESS_KEY=(AWSのシークレットアクセスキー)
VIDEO_STREAM_NAME=(Kinesis Video Streamのリソース名)
使い方
- .envを自分の環境にあわせて編集する
docker compose up
動作確認
AWSコンソール上から配信された動画を確認できます(画質が低いわけではなく、プライバシー保護のためモザイクをかけております)
AWS公式提供のDockerイメージでは配信出来ませんでしたが、自力で構築したイメージからは無事に配信できました。
遅延もネットワークカメラと比べてかなり少ないです!
以上です!!
NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion