10日ほど前にリリースされたAWSのストリーミング動画(Interactive Video Service)に認証を付けてみた(Notユーザ認証)
参考URL
https://dev.classmethod.jp/articles/update-amazon-interactive-video-service-auth/
Interactive Video Service(ivs)は、チャネルを新規作成すると、いきなりストリーミング配信が出来る。
利用可能なリージョンは三箇所(オレゴン・バージニア・アイルランド)のみ。最初のリージョンを指定してない状態だと、なぜか普通にチャンネル生成できた…。バグ?
やる事リスト
1, ivsで再生キー(公開鍵)を生成
2, 秘密鍵をSecret Managerに登録
3, 秘密鍵をTokenに変換するlambda関数を生成
4, 再生URLにtokenパラメータを付与する
5, 不要になったらキーペアを削除する
1, 配信者はコンソールから、配信サーバのURL(rtmps://ハッシュっぽい値.global-contribute.live-video.net:443/app/ ポートを:443と指定しないと配信出来なかった!)とストリームキー(パスワード)が取得できる。
PCにOBS Studio(配信ソフト)か、スマホでStreamlabsをインストールして、配信環境を整える。
2, 配信し始めると、10数秒たって、コンソールのライブストリームから動画が視聴できるようになる。
3, 再生URLも表示されているが、そのままではブラウザで表示されない。amazon-ivs-playerというのをJSで実行する必要がある。
player.load内のURLを、コンソールの再生URLに変更すれば、ストリーミング視聴が出来るようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<head> <script src="https://player.live-video.net/1.0.0/amazon-ivs-player.min.js"></script> <style> </style> </head> <body> <video id="video-player" playsinline></video> </body> <script> // This shows how to include the Amazon IVS Player with a script tag from our CDN // If self hosting, you may not be able to use the create() method since it requires // that file names do not change and are all hosted from the same directory. (function (IVSPlayerPackage) { // First, check if the browser supports the IVS player. if (!IVSPlayerPackage.isPlayerSupported) { console.warn("The current browser does not support the IVS player."); return; } const PlayerState = IVSPlayerPackage.PlayerState; const PlayerEventType = IVSPlayerPackage.PlayerEventType; // Initialize player const player = IVSPlayerPackage.create(); player.attachHTMLVideoElement(document.getElementById("video-player")); // Attach event listeners player.addEventListener(PlayerState.PLAYING, function () { console.log("Player State - PLAYING"); }); player.addEventListener(PlayerState.ENDED, function () { console.log("Player State - ENDED"); }); player.addEventListener(PlayerState.READY, function () { console.log("Player State - READY"); }); player.addEventListener(PlayerEventType.ERROR, function (err) { console.warn("Player Event - ERROR:", err); }); player.addEventListener(PlayerEventType.TEXT_METADATA_CUE, (cue) => { const metadataText = cue.text; const position = player.getPosition().toFixed(2); console.log( `PlayerEvent - TEXT_METADATA_CUE: "${metadataText}". Observed ${position}s after playback started.` ); }); // Setup stream and play player.setAutoplay(true); player.load( "https://fcc3ddae59ed.us-west-2.playback.live-video.net/api/video/v1/us-west-2.893648527354.channel.DmumNckWFTqz.m3u8" ); player.setVolume(0.5); })(window.IVSPlayer); </script> |
このファイルさえあれば、どこでもいいのでデスクトップでも、S3でも、自分のブログでもストリーミング配信できるようになる。
ただ、全世界に公開するだけならyoutubeで無料で出来るので、ユーザ認証を行って、特定のユーザだけに見せたい!(そして視聴ログも欲しい!)
4, チャネルの編集画面の最後にある、動画再生のトークン認証要件を有効にして、保存。
有効にすると、コンソール内でプレビューも出来なくなる!
5, 左のサイドバーの再生キーをクリックして、再生キーのボタンを押して、playback-key-1など適当なキー名を入力すると、private-key.pemが自動ダウンロードされる。
aws-cliから、AWS Secrets Managerにアップロードする。–cli-binary-format raw-in-base64-outオプションを付けないと、Invalid base64エラーになる。
1 |
aws secretsmanager create-secret --name ivsprivate --cli-binary-format raw-in-base64-out --secret-binary file://C:\Users\ユーザー名\Downloads\private-key.pem |
ARNが返ってくるので、メモしておく(Secret Managerのリージョンは東京でOK)
6, 認証トークンを発行するlambdaを生成するために、ローカルでソース生成
1 2 3 4 5 |
mkdir ivs cd ivs npm init -y npm install jsonwebtoken |
ivs/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Need to install this using npm install jsonwebtoken var jwt = require('jsonwebtoken'); const aws = require('aws-sdk'); var globalPem; exports.handler = async (event) => { if (globalPem === undefined) { await getPemKey('さっき作ったプライベート鍵のSecret ManagerのARN'); } var payload = { "aws:channel-arn": "ストリーミング配信チャネルのARN", "aws:access-control-allow-origin": "*" }; var token = jwt.sign(payload, globalPem, { algorithm: 'ES384', expiresIn: '2 days' }); var tokenObj = { token }; const response = { statusCode: 200, body: JSON.stringify(tokenObj), headers: { 'Access-Control-Allow-Origin':'*', }, }; return response; }; async function getPemKey(pemId) { const secretsManager = new aws.SecretsManager({ apiVersion: '2017-10-17' }); const secret = await secretsManager.getSecretValue({ SecretId: pemId }).promise(); globalPem = secret.SecretBinary; } |
7, このフォルダをZIP圧縮して、lambda関数にアップロードする。
普通にlambda関数を新規作成。ロール・ポリシーのJSON記述でシークレットのARNを指定して、ポリシー名(ivs-getsecrets)を作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "secretsmanager:GetSecretValue" ], "Resource": [ "秘密鍵をアップロードしたSecret ManagerのARN" ], "Effect": "Allow" } ] } |
ZIP圧縮したソースをアップロードして、テストが問題なければLAMBDA関数は完成。
※まとめたフォルダをZIP圧縮するとエラーになるので、ファイル・フォルダを直接ZIP化する必要がある。
テスト結果にtokenが生成されるので、それをコピペして、動画URLの最後に ?token=トークンの値 を付与すると、ちゃんと再生されるようになる。
tokenの値を変更したり、再生キーを削除すると、当然エラーになって再生できない。
手動では出来たけど、これを自動化して、ユーザログインと紐付けないと駄目なんだよな~。他のアプリとか考えると自由度があっていいんだろうけど。
あと、ストリーミング専用サービスなので、後で見る用に録画とか出来ない…。