Microsoft Azureでラズベリーパイから cloud live streamingする方法
Microsoft AzureのMedia Servicesを使ってラズベリーパイからストリーミングを行う方法です
背景的なもの
現在パブリッククラウドサービスはAWS, Azure, GCP等があり、それぞれストリーミングに関しては以下のようなサービスを提供しています
(IBMはプライベートクラウドに力をいれているらしく今回は調査対象外)
Cloud Growth Rate Increases; Amazon, Microsoft & Google all Gain Market Share | Synergy Research Group
AWS(wowza)
メディアストリーミングチュートリアル - Amazon CloudFront | AWS
Install Wowza Streaming Engine on Raspberry Pi
Azure Media Services
今回はAzureを利用してみます
Media Services : azure.microsoft.com
構成
- チャネル、プログラム、StreamingEndpointsからなる
- 各Media Servicesアカウントには、複数のチャネル、複数のプログラム、複数のStereamingEndpointsを含めることができる
- 帯域幅とセキュリティのニーズに応じて、StreamingEndpointサービスを一つまたは複数のチャネル専用にすることができる
- StreamingEndpointはどのチャネルからでもプルできる
channel
- Media Servicesにおいてライブストリーミングコンテンツの処理を担う
- ライブストリーミングコンテンツを処理するためのパイプラインを表す
- 入力エンドポイントであり、その取り込みURLをライブトランスコーダーに対して指定する
- チャネルはライブトランスコーダからライブ入力ストリームを受け取り、1つまたは複数のStreaming Endpointを介してストリーミングできる状態にする
- ストリームはあらかじめプレビューし、確認した上で処理、配信するが、チャネルはその際にしようするプレビューエンドポイントも提供する
- チャネル作成時に取り込みようURLとプレビューURLを取得できる
- チャネルが開始済み状態である必要はない
- ライブトランスコーダーからチャネルへのデータのプッシュを開始する準備ができたら、チャネルを開始する必要がある
- ライブトランスコーダーがデータの取り込みを開始した後、ストリームをプレビューできる
- チャネルの状態
- 停止済み:初期状態。ストリーミングの許可はされていない
- 開始中:チャネルを開始している。更新やストリーミングはできない。
- 実行中:ライブストリームを処理できる
- 停止中:チャネルを停止している
- 削除中:チャネルを削除している
Azureの設定
流れとしては以下のようになります
1. Azure Media Servicesのアカウント作成
2. StreamingEndpointsの開始
3. チャネルの作成
4. live eventの作成
5. channel とlive eventのstart
1. Create Azure Media Services Account
Media Servicesを選択
Addを選択
データを入力していきます
- Account Name
- Subscription
- Resource Group
- Location
- Storage Account
作成が完了すると、Media Servicesの一覧に新しい項目が追加されます
2. Start Streaming Endpoint
1で作成したMedia Serviceのアカウントを選択しOverview BladeからStreaming Endpointを選択します
そのまま以下の通りEndpointを開始します
3. Start Channel
Live Streaming BladeからCustom Createを選択します
- Setting
- Endoding type: Pass Through
- Pass Throughはsingle bit encoding
- クライアント側の通信速度に応じて画質を変更するmulti bit encodingも可能だが、その分遅延が発生するので今回はやらない
- Encoding UnitもPass Throughの際は関係ない(Reserved Unit0でよい)
- Name:なんでも
- Description: なんでも
- Automatically start the channel after creation: チェック外す
- Endoding type: Pass Through
- Ingest
- Streaming protocol: RTMP
- Preview
- 変更の必要なし
- Create
channelが作成されるとLive Streaming Bladeに作成されたChannelが表示されます
作成されたChannelを選択し、INGEST URL(Primary)をメモしておきます
4. Create Live Event
ChannelのメニューからLive Eventを選択します
Live Eventのデータを入力します
- Name
- asset name
- archive window
- 最小設定可能時間は5分
- archive自体は項目にDayもあるしStorageに余裕がある限り保存できそう
- ただし一回のストリーミングに関しては連続して8時間以下が推奨とのこと
Live Eventが作成されたら、Streaming URLをメモしておきます
5. Start Channel & Live Event
最後にChannelとLive Eventを開始します
Raspberry Piの設定
設定
# カメラの確認 $ modprobe bcm2835-v4l2 # ラズパイカメラを利用する場合 $ v4l2-ctl --list-device mmal service 16.1 (platform:bcm2835-v4l2): /dev/video0 # 音声入力デバイスの確認 $ arecord -l **** List of CAPTURE Hardware Devices **** ### 今回はマイク機能なしのカメラを利用 # 映像フォーマット、解像度、フレームレートの組み合わせの確認 $ v4l2-ctl -d /dev/video0 --list-formats-ext ioctl: VIDIOC_ENUM_FMT Index : 0 Type : Video Capture Pixel Format: 'YU12' Name : Planar YUV 4:2:0 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 1 Type : Video Capture Pixel Format: 'YUYV' Name : YUYV 4:2:2 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 2 Type : Video Capture Pixel Format: 'RGB3' Name : 24-bit RGB 8-8-8 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 3 Type : Video Capture Pixel Format: 'JPEG' (compressed) Name : JFIF JPEG Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 4 Type : Video Capture Pixel Format: 'H264' (compressed) Name : H.264 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 5 Type : Video Capture Pixel Format: 'MJPG' (compressed) Name : Motion-JPEG Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 6 Type : Video Capture Pixel Format: 'YVYU' Name : YVYU 4:2:2 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 7 Type : Video Capture Pixel Format: 'VYUY' Name : VYUY 4:2:2 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 8 Type : Video Capture Pixel Format: 'UYVY' Name : UYVY 4:2:2 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 9 Type : Video Capture Pixel Format: 'NV12' Name : Y/CbCr 4:2:0 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 10 Type : Video Capture Pixel Format: 'BGR3' Name : 24-bit BGR 8-8-8 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 11 Type : Video Capture Pixel Format: 'YV12' Name : Planar YVU 4:2:0 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 12 Type : Video Capture Pixel Format: 'NV21' Name : Y/CrCb 4:2:0 Size: Stepwise 16x16 - 3280x2464 with step 2/2 Index : 13 Type : Video Capture Pixel Format: 'BGR4' Name : 32-bit BGRA/X 8-8-8-8 Size: Stepwise 16x16 - 3280x2464 with step 2/2 # 映像フォーマット一覧の確認 $ ffmpeg -f v4l2 -list_formats all -i /dev/video0 ffmpeg version N-89701-gb2be76c Copyright (c) 2000-2018 the FFmpeg developers built with gcc 4.9.2 (Raspbian 4.9.2-10) configuration: --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree libavutil 56. 7.100 / 56. 7.100 libavcodec 58. 9.100 / 58. 9.100 libavformat 58. 3.100 / 58. 3.100 libavdevice 58. 0.100 / 58. 0.100 libavfilter 7. 10.100 / 7. 10.100 libswscale 5. 0.101 / 5. 0.101 libswresample 3. 0.101 / 3. 0.101 libpostproc 55. 0.100 / 55. 0.100 [video4linux2,v4l2 @ 0x2f3d1b0] Raw : yuv420p : Planar YUV 4:2:0 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : yuyv422 : YUYV 4:2:2 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : rgb24 : 24-bit RGB 8-8-8 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Compressed: mjpeg : JFIF JPEG : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Compressed: h264 : H.264 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Compressed: mjpeg : Motion-JPEG : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : Unsupported : YVYU 4:2:2 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : Unsupported : VYUY 4:2:2 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : uyvy422 : UYVY 4:2:2 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : nv12 : Y/CbCr 4:2:0 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : bgr24 : 24-bit BGR 8-8-8 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : yuv420p : Planar YVU 4:2:0 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : Unsupported : Y/CrCb 4:2:0 : {16-3280, 2}x{16-2464, 2} [video4linux2,v4l2 @ 0x2f3d1b0] Raw : bgr0 : 32-bit BGRA/X 8-8-8-8 : {16-3280, 2}x{16-2464, 2} /dev/video0: Immediate exit requested
撮影
Azure Media Servicesは、音声データと音声コーデックを指定して送信しないとエラーになり受け付けてもらえません
- 無音(音声データなし)はNG
- 無音(音声データあり)はOK
ラズパイカメラやUSBカメラのみでマイクがない場合は、ffmpeg側で無音の音声データを付加してAzure Media Services側に送信する必要があります
# ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... $ ffmpeg -vsync passthrough -f v4l2 -vcodec h264 -framerate 30 -video_size 320x180 -i /dev/video0 -f lavfi -i aevalsrc=0 -shortest -strict -2 -c:a aac -b:a 7350 -ar 7350 -g 60 -keyint_min 60 -c:v copy -preset ultrafast -b:v 150k -maxrate 150k -bufsize 150k -f flv $INGESTURI/mystream
- $INGESTURLはAzure側でチャネルを設定した際にメモしたものです
- さらに注意点として、ffmpegで送信する場合にはINGEST_URIの後ろにmystream等の名前をつけないとエラーになります
- mystreamに特に意味はなく、なんでもOKです
ffmpegのオプションに関しては
- f fmt: force format
- V4l2: Video for linux
- alsa: audio
- hw: 1,0 audioのinput の指定
- c:v videoのcodec
- c:a audioのcodec
- framerate / フレームレート
- r / set frame rate
- s / size,set frame size(WxH)
- i / input deviceの指定
- /dev/video0 / 接続されているvideoデバイスの一つ
- vcodec / force video codec
- ultrafast /
- acodec / audio codec
- libfaac / 同上
- ab / audio bitrate(pleas use -b:a)
- b / video bitrate(please use -b:v)
- sc_thresold / シーンチェンジ検出の閾値(0でdefault, -1 でシーンチェンジ検出無効)
たまに落ちる場合は以下みたくして対応
#!/bin/bash modprobe bcm2835-v4l2 INGESTURI="rtmp://*****************************************************" # primary while : do ffmpeg -vsync passthrough -f v4l2 -vcodec h264 -framerate 30 -video_size 320x180 -i /dev/video0 -f lavfi -i aevalsrc=0 -shortest -strict -2 -c:a aac -b:a 7350 -ar 7350 -g 60 -keyint_min 60 -c:v copy -preset ultrafast -b:v 150k -maxrate 150k -bufsize 150k -f flv $INGESTURI/mystream sleep 10 done
遅延に関して
だいたい色々チューニングをした結果、16,7秒くらいの遅延が発生します。
Azure側の処理の都合上、最短で15-20秒は遅延が発生するらしいです。
Azure Media Player RTMP Latency
現在Microsoft側でも低レイテンシ版の開発をしているとのことですが、あまり優先度は高くないとのこと。
Azure Media Services: Top (187 ideas) – Customer Feedback for Microsoft Azure
ちなみにGCPの中の人とも話す機会があったのですが、大体おんなじくらいの遅延は発生しますとのこと。
これは現在のクラウドストリーミングのサービスや技術が、大人数にむけて配信することをターゲットとしており、秒単位で遅延を減らす方向にはシフトしていないとのこと。
ブラウザでの表示
AzureのUI上で確認できますが、ストリーミングをWebブラウザに表示する方法です
HTML
<head> <link href="//amp.azure.net/libs/amp/2.1.5/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet"> <script src="//amp.azure.net/libs/amp/2.1.5/azuremediaplayer.min.js"></script> </head> <body> <video id="azuremediaplayer" class="azuremediaplayer amp-default-skin amp-big-play-centered" tabindex="0"></video> </body>
$(function() { var myOptions = { "nativeControlsForTouch": false, controls: true, autoplay: true, width: "640", height: "400", } myPlayer = amp("azuremediaplayer", myOptions); myPlayer.src([ { "src": "$Streaming URL without protocol", "type": "application/vnd.ms-sstr+xml" } ]); });
tips
windowsからの配信
配信がうまくいかずに、まずは問題の切り分けとしてWindowsから配信テストを行う方法
### 接続したUSBカメラ等が認識しているか確認 $ ffmpeg -f dshow -list_devices true -i dummy [dshow @ 0000000000150980] DirectShow video devices (some may be both video and audio devices) [dshow @ 0000000000150980] "MS-M103HU USB Camera" [dshow @ 0000000000150980] Alternative name "@device_pnp_******************23196}\global" [dshow @ 0000000000150980] DirectShow audio devices [dshow @ 0000000000150980] Could not enumerate audio only devices (or none found). dummy: Immediate exit requested ## 2行目のMS-M103HU USB Cameraが今回接続したUSBカメラ(以降はこの名前をオプションとして指定する) ## Alternative nameも利用することができる。同じ種類のカメラを複数接続したときに利用するっぽい ### 検出されたカメラの仕様を確認する $ ffmpeg -f dshow -list_options true -i video="MS-M103HU USB Camera" [dshow @ 00000000003a09c0] DirectShow video device options (from video devices) [dshow @ 00000000003a09c0] Pin "Capture" (alternative pin name "0") [dshow @ 00000000003a09c0] pixel_format=yuyv422 min s=1280x720 fps=12 max s=1280x720 fps=12 [dshow @ 00000000003a09c0] pixel_format=yuyv422 min s=1280x720 fps=12 max s=1280x720 fps=12 [dshow @ 00000000003a09c0] vcodec=mjpeg min s=1280x720 fps=30 max s=1280x720 fps=30 [dshow @ 00000000003a09c0] vcodec=mjpeg min s=1280x720 fps=30 max s=1280x720 fps=30 ## このカメラだと2パターンの録画しか出来ない
テスト撮影
# ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... # -f fmt: force format # V4l2: Video for linux # alsa: 音声 # hw: 1,0 音声の入力指定 # -c:v videoのcodec # -c:a audioのcodec ### infile options ## input optionはカメラが対応していないものを指定してもエラーが返って来る # このカメラは1280x720しか対応していないので他の解像度を指定してもダメ > ffmpeg -f dshow -video_size 640x480 -i video="MS-M103HU USB Camera" [dshow @ 00000000003b0a00] Could not set video options video=MS-M103HU USB Camera: I/O error # このカメラは12FPS(yuvj)か30FPS(mjpeg)しか対応していないので他のFPSを指定してもダメ > ffmpeg -f dshow -framerate 24 -i video="MS-M103HU USB Camera" [dshow @ 00000000006809c0] Could not set video options video=MS-M103HU USB Camera: I/O error # 選択可能なFPSの場合は適したコーデックが自動で選択される > ffmpeg -f dshow -framerate 30 -i video="MS-M103HU USB Camera" Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720 [SAR 96:96 DAR 16:9], 30 fps, 30 tbr, 10000k tbn, 10000k tbc > ffmpeg -f dshow -framerate 12 -i video="MS-M103HU USB Camera" Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 12 fps, 12 tbr, 10000k tbn, 10000k tbc # コーデックを指定する場合は対応したFPSじゃないとダメ > ffmpeg -f dshow -vcodec mjpeg -framerate 12 -i video="MS-M103HU USB Camera" [dshow @ 00000000005c0c00] Could not set video options video=MS-M103HU USB Camera: I/O error ### output option # mp4ファイルで出力したいとき(yuv420p) > ffmpeg -f dshow -vcodec mjpeg -framerate 30 -video_size 1280x720 -i video="MS-M103HU USB Camera" -pix_fmt yuv420p rec.mp4 # 出力動画のFPSを落としたいとき(-r 3) > ffmpeg -f dshow -vcodec mjpeg -framerate 30 -video_size 1280x720 -i video="MS-M103HU USB Camera" -pix_fmt yuv420p -r 3 rec.mp4
実際にWindowsからストリーミング
ffmpeg \ -rtbufsize 100M \ -vsync passthrough \ -f dshow \ -vcodec mjpeg -framerate 30 \ -video_size 1280x720 \ -i video="MS-M103HU USB Camera" \ -f lavfi \ -i aevalsrc=0 -shortest \ -strict -2 \ -c:a aac \ -b:a 128k \ -ar 44100 \ -r 30 \ -g 60 \ -keyint_min 60 \ -b:v 400000 \ -c:v libx264 \ -preset ultrafast \ -bufsize 400k \ -maxrate 400k \ -f flv rtmp://<your channel>/mystream
これでもうまくいかない場合はWirecastがAzure media servicesに対応しているので、まずはWirecast経由でストリーミングできるか確認
最新動向
この投稿を書いてる途中にlow latency modeが実装されたとのこと
ポストによると8-10秒まで落とすことが出来るらしく、更に2秒以下のultra low latency modeの開発がはじまったらしい
Reduce live streaming latency for Azure Media Services live streaming – Customer Feedback for Microsoft Azure
azure.microsoft.com
さらにRTSPのサポートの開発もはじまったとのこと
Directly ingesting RTSP – Customer Feedback for Microsoft Azure