Amazon S3 への IVS 自動録画 | Low-Latency Streaming - Amazon IVS

Amazon S3 への IVS 自動録画 | Low-Latency Streaming

このセクションでは、Amazon IVS Low-Latency Streaming の S3 への自動録画機能について説明します。録画された Amazon IVS ストリームのデータストレージについて説明します。ストレージの内容とメタデータファイルスキーマについて説明します。また、録画したコンテンツの再生についても説明します。

詳細 参照

動画録画の設定と停止

Amazon IVS の使用開始で、オプション録画を使用したチャネルを作成する

API

IVS API リファレンス

コスト Amazon IVS のコスト

S3 プレフィックス

S3 プレフィックスは、録画される各ライブストリームの一意のディレクトリ構造です。ライブストリームのすべてのメディアファイルとメタデータファイルは、このディレクトリ内に書き込まれます。録画が有効なチャネルの場合、S3 プレフィックスはライブセッション開始時に生成され、録画の開始時と終了時に CloudWatch イベントに提供されます。

S3 プレフィックスの形式は次のとおりです。

/ivs/v1/<aws_account_id>/<channel_id>/<year>/<month>/<day>/<hours>/<minutes>/<recording_id>

コードの説明は以下のとおりです。

  • aws_account_id は、チャネルが作成される AWS アカウントの (AWS アカウントの作成時に生成される) ID です。

  • channel_id は、チャネル ARN のリソース ID 部分 (Amazon リソースネームの最後の部分) です。用語集 の ARN を参照してください。

  • <year>/<month>/<day>/<hours>/<minutes> は、録画開始時の UTC タイムスタンプです。

  • recording_id は、録画セッションごとに生成される一意の ID です。

例:

ivs/v1/123456789012/AsXego4U6tnj/2020/6/23/20/12/j8Z9O91ndcVs

録画の内容

録画が開始すると、動画セグメントとメタデータファイルは、チャネルに設定されている S3 バケットに書き込まれます。これらのコンテンツは、後処理またはオンデマンド動画再生として利用できます。

ライブストリームが開始し、Recording Start EventBridge イベントが発生してから、マニフェストファイルと動画セグメントが書き込まれるまでに少し時間がかかることに注意してください。Recording End イベントの送信後に、録画したストリームを再生または処理することをお勧めします。(「IVS で Amazon EventBridge を使用する」を参照してください。)

以下は、ライブの Amazon IVS セッションの録画のディレクトリ構造およびコンテンツの例です。

ivs/v1/123456789012/AsXego4U6tnj/2020/6/23/20/12/j8Z9O91ndcVs/ events recording-started.json recording-ended.json media hls thumbnails

eventsフォルダには、録画イベントに対応するメタデータファイルが含まれています。JSON メタデータファイルは、録画が開始された時、正常に終了した時、失敗して終了した時に生成されます。

  • events/recording-started.json

  • events/recording-ended.json

  • events/recording-failed.json

該当する events フォルダには、recording-started.json、および recording-ended.json または recording-failed.json のどちらかが含まれます。

これらには、録画されたセッションとその出力形式に関連するメタデータが含まれます。JSON の詳細を以下に示します。

media フォルダには、サポートされているすべてのメディアコンテンツが 2 つのサブフォルダ内に格納されています。

  • hls には、ライブセッション中に生成されたすべてのメディアファイルとマニフェストファイルが含まれており、Amazon IVS プレイヤーで再生できます。このフォルダには、標準マスターマニフェスト master.m3u8 とバイト範囲対応マニフェスト byte-range-multivariant.m3u8 の 2 種類の HLS マニフェストがあります。したがって、各レンディションフォルダには playlist.m3u8byte-range-variant.m3u8 ファイルの両方があります。(以下の「バイト範囲プレイリスト」を参照してください。)

  • thumbnails には、ライブセッション中に生成されたサムネイル画像が含まれます。サムネイルは、毎分ごとに生成されてバケットに書き込まれます。(この動作を変更するには、録画設定の thumbnailConfiguration プロパティを上書きしてください。)

重要: media フォルダ内のコンテンツは動的に生成され、最初に受信した動画セグメントの特性によって決定されます。フォルダのコンテンツは最終的な特性 (レンディションの品質など) を表していない場合があります。静的パスについて何も仮定しないでください。使用可能な HLS レンディションとそのパスを検出するには、以下で説明する JSON メタデータファイルを使用します。

バイト範囲プレイリスト

S3 への自動録画機能では、標準の HLS プレイリストに加えて、バイト範囲プレイリストの生成がサポートされます。バイト範囲プレイリストは、HLS 仕様のバージョン 4 に準拠しています。これにより、より詳細なコンテンツクリッピングが可能になります。バイト範囲プレイリストでは、レンディションインデックスファイルの各セグメントはビデオチャンクのバイトのサブ範囲を参照し、標準の 10 秒のメディアファイルサイズよりも細かく指定できます。バイト範囲のプレイリストでは、セグメント再生時間はストリームに設定されたキーフレーム間隔と同じです。

サムネイル

録画設定の thumbnailConfiguration プロパティは、ライブセッションのサムネイルの記録を有効または無効にしたり、ライブセッションのサムネイルが生成される間隔を変更したりできます。サムネイルの間隔は 1 秒から 60 秒の範囲で設定でき、デフォルトでは、60 秒の間隔でサムネイルの記録が有効になっています。「Amazon IVS Low-Latency Streaming API Reference」を参照してください。

また、サムネイル設定には storage フィールド (SEQUENTIAL または LATEST) と解像度 (LOWEST_RESOLUTIONSDHDFULL_HD) が含まれています。各オプションの解像度は以下のとおりです。

160 <= LOWEST_RESOLUTION <= 360

360 < SD <= 480

480 < HD <= 720

720 < FULL_HD <= 1,080

マルチトラックビデオ入力を使用しているストリームに対して resolution が設定されていない場合、すべてのレンディションのサムネイルが記録されます。マルチトラックの詳細については、「Multitrack Video」を参照してください。

断片化されたストリームの結合

録画設定の recordingReconnectWindowSeconds プロパティを使用すると、ストリームが中断されて新しいストリームが開始された場合に、Amazon IVS が前のストリームと同じ S3 プレフィックスに録画を試みる時間枠 (秒単位) を指定できます。つまり、ブロードキャストが切断され、指定された時間内で再接続された場合、複数のストリームは 1 つのブロードキャストと見なされマージされます。

Amazon EventBridge の IVS 録画状態変更イベント: Amazon IVS が新しいストリームが開始されていないことを確認するまで待機するため、Recording End イベントおよび recording-ended JSON メタデータファイルは、少なくとも recordingReconnectWindowSeconds で指定した時間遅れます。

ストリームの結合機能をセットアップする手順については、「Amazon IVS の開始方法」の「ステップ 4: 任意の録画によるチャネルの作成」を参照してください。

対象

複数のストリームを同じ S3 プレフィックスに録画するには、すべてのストリームで特定の条件を満たす必要があります。

  • 動画の幅と高さが同じであること。

  • フレームレートは同じであること。

  • 後続ストリームのビットレート差は、元のストリームのビットレートの 50% 以下であること。

  • ビデオコーデックとオーディオコーデックは同じであること。

注意:

  • 最大 20 のストリームがマージされ、その後新しい S3 プレフィックスが作成されます。

  • 48 時間後、新しい S3 プレフィックスが作成されます。たとえば、最初のブロードキャストが 48 時間続き、別のブロードキャストが recordingReconnectWindowSeconds の指定時間内に開始された場合、次のブロードキャストは最初の S3 プレフィックスにはマージされません。

  • 各ストリームの開始は、前のストリームから 10 秒以上経過後に行う必要があります。

既知の問題

もし recordingReconnectWindowSeconds が有効になっていて、Web Broadcast SDK が使用されている場合、Web Broadcast SDK はビットレートと品質を動的に変更するため、同じ S3 プレフィックスへの録画が機能しない可能性があります。

JSON メタデータファイル

録画状態変更イベントが発生すると、対応する Amazon CloudWatch メトリクスが生成され、メタデータファイルが S3 プレフィックス内に書き込まれます。(「Amazon IVS Low-Latency Streaming のモニタリング」を参照してください。)

このメタデータは JSON 形式です。これには、以下の情報が含まれています。

フィールド Type 必須 説明

channel_arn

文字列 はい ライブストリームをブロードキャストするチャネルの ARN。

media

オブジェクト はい

この録画に使用できるメディアコンテンツの列挙型オブジェクトを含むオブジェクト。有効な値: "hls""thumbnails"

  • hls

オブジェクト はい

Apple HLS 形式の出力を記述する列挙型フィールド。

    • duration_ms

整数 条件付き

録画された HLS コンテンツの継続時間 (ミリ秒単位)。これは、recording_status"RECORDING_ENDED" または "RECORDING_ENDED_WITH_FAILURE" のときにのみ利用できます。録画完了前に障害が発生した場合は、0 になります。

    • path

文字列 はい

HLS コンテンツが格納されている S3 プレフィックスからの相対パス。

    • playlist

文字列 はい

HLS マスタープレイリストファイルの名前。

    • byte_range_playlist

文字列 あり

HLS バイト範囲マルチバリアントプレイリストの名前。

    • renditions

オブジェクト はい

メタデータオブジェクトのレンディション (HLS バリアント) の配列。レンディションは必ず 1 つ以上。

      • path

文字列 はい

このレンディションの HLS コンテンツが格納されている S3 プレフィックスからの相対パス。

      • playlist

文字列 はい

このレンディションのメディアプレイリストファイルの名前。

      • byte_range_playlist

文字列 あり

このレンディションのバイト範囲プレイリストの名前。

      • resolution_height

整数 条件付き

エンコードされた動画のピクセル解像度の高さ。これは、レンディションに動画トラックが含まれている場合にのみ使用できます。

      • resolution_width

整数 条件付き

エンコードされた動画のピクセル解像度の幅。これは、レンディションに動画トラックが含まれている場合にのみ使用できます。

  • thumbnails

オブジェクト 条件付き

サムネイル出力を記述する列挙型フィールド。これを使用できるのは、サムネイル設定の recordingModeINTERVAL になっているときだけです。

    • path

文字列 条件付き

サムネイルコンテンツが格納されている S3 プレフィックスからの相対パス。これを使用できるのは、サムネイル設定の recordingModeINTERVAL になっているときだけです。

    • resolution_height

int あり

サムネイルの高さ。デフォルト: ソースレンディションの解像度。この値は、関連する録画設定でのユーザー入力の影響を受けます。具体的には thumbnailConfiguration.resolution  値です。

    • resolution_width

int あり

サムネイルの幅。デフォルト: ソースレンディションの解像度。この値は、関連する録画設定でのユーザー入力の影響を受けます。具体的には thumbnailConfiguration.resolution 値です。

  • latest thumbnail

オブジェクト あり

最新のサムネイル出力を記述する列挙型フィールド。これを使用できるのは、サムネイル設定の storage に LATEST が含まれる場合のみです。

    • resolution_height

int あり

サムネイルの高さ。デフォルトは、ソースレンディションの解像度です。この値は、関連する録画設定でのユーザー入力の影響を受けます。具体的には thumbnailConfiguration.resolution 値です。

    • resolution_width

int あり

サムネイルの幅。デフォルトは、ソースレンディションの解像度です。この値は、関連する録画設定でのユーザー入力の影響を受けます。具体的には thumbnailConfiguration.resolution 値です。

recording_ended_at

string 条件付き

録画終了時の RFC 3339 UTC タイムスタンプ。これは、recording_status"RECORDING_ENDED" または "RECORDING_ENDED_WITH_FAILURE" のときにのみ利用できます。

recording_started_atrecording_ended_atは、これらのイベントが生成されたときのタイムスタンプであり、HLS ビデオセグメントのタイムスタンプと完全に一致しない場合があります。録画時間を正確に決定するには、duration_msフィールドを使用してください。

recording_started_at

文字列 はい

録画開始時の RFC 3339 UTC タイムスタンプ。

recording_ended_atについては、上記の注意事項を参照してください。

recording_status

文字列 はい

録画ステータス。有効な値は、"RECORDING_STARTED""RECORDING_ENDED""RECORDING_ENDED_WITH_FAILURE" です。

recording_status_message

文字列 条件付き

ステータスの詳細情報。これは、recording_status"RECORDING_ENDED" または "RECORDING_ENDED_WITH_FAILURE" のときにのみ利用できます。

version

文字列 はい

メタデータスキーマのバージョン。

例: recording_started.json

{ "version": "v1", "channel_arn": "arn:aws:ivs:us-west-2:123456789012:channel/AsXego4U6tnj", "recording_started_at": "2020-06-12T12:53:26Z", "recording_status : "RECORDING_STARTED", "media": { "hls": { "path": "media/hls", "playlist": "master.m3u8", "byte_range_playlist": "byte-range-multivariant.m3u8", "renditions": [ { "path": "480p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 480, "resolution_width": 852 }, { "path": "360p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 360, "resolution_width": 640 }, { "path": "160p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 160, "resolution_width": 284 }, { "path": "720p60", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 720, "resolution_width": 1280 } ] }, "thumbnails": { "path": "media/thumbnails", "resolution_height": 480, "resolution_width": 852 }, "latest_thumbnail": { "path": "media/latest_thumbnail/thumb.jpg", "resolution_height": 480, "resolution_width": 852 } } }

例: recording_ended.json

{ "version": "v1", "channel_arn": "arn:aws:ivs:us-west-2:123456789012:channel/AsXego4U6tnj", "recording_ended_at": "2020-06-14T12:53:20Z", "recording_started_at": "2020-06-12T12:53:26Z", "recording_status": "RECORDING_ENDED", "media": { "hls": { "duration_ms": 172794489, "path": "media/hls", "playlist": "master.m3u8", "byte_range_playlist": "byte-range-multivariant.m3u8", "renditions": [ { "path": "480p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 480, "resolution_width": 852 }, { "path": "360p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 360, "resolution_width": 640 }, { "path": "160p30", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 160, "resolution_width": 284 }, { "path": "720p60", "playlist": "playlist.m3u8", "byte_range_playlist": "byte-range-variant.m3u8", "resolution_height": 720, "resolution_width": 1280 } ] }, "thumbnails": { "path": "media/thumbnails", "resolution_height": 480, "resolution_width": 852 }, "latest_thumbnail": { "path": "media/latest_thumbnail/thumb.jpg", "resolution_height": 480, "resolution_width": 852 } } }

例: recording_failed.json

{ "version": "v1", "channel_arn": "arn:aws:ivs:us-west-2:123456789012:channel/AsXego4U6tnj", "recording_ended_at": "2020-06-14T12:53:20Z", "recording_started_at": "2020-06-12T12:53:26Z", "recording_status": "RECORDING_ENDED_WITH_FAILURE", "recording_status_message": "InternalServerException", "media": { "hls": { "duration_ms": 172794489, "path": "media/hls", "playlist": "master.m3u8", "renditions": [ { "path": "480p30", "playlist": "playlist.m3u8", "resolution_height": 480, "resolution_width": 852 }, { "path": "720p60", "playlist": "playlist.m3u8", "resolution_height": 720, "resolution_width": 1280 } ] }, "thumbnails": { "path": "media/thumbnails", "resolution_height": 480, "resolution_width": 852 }, "latest_thumbnail": { "path": "media/latest_thumbnail/thumb.jpg", "resolution_height": 480, "resolution_width": 852 } } }

録画のレンディションの検出

Amazon IVS チャネルへコンテンツをストリーミングする場合、auto-record-to-s3 はソースビデオを使用して複数のレンディションを生成します。Amazon IVS Player は、Adaptive Bitrate Streaming (ABR) を使用して、必要に応じてレンディション (ビットレート) を自動的に切り替え、さまざまなネットワーク条件に応じて再生を最適化します。

ライブストリーミング中に生成された各レンディションは、S3 録画プレフィックス内の固有のパスに記録されます。解像度の詳細、パス、およびプレイリストファイル名は、録画の開始および終了時に JSON メタデータファイルに保存されます。録画設定の renditionSelection の値が ALL の場合、すべてのレンディションが記録対象として選択されます。renditionSelection が CUSTOM の場合、オプション (LOWEST_RESOLUTIONSDHD、FULL_HD) から 1 つ以上を選択する必要があります。各オプションの解像度は以下のとおりです。

160 <= LOWEST_RESOLUTION <= 360

360 < SD <= 480

480 < HD <= 720

720 < FULL_HD <= 1,080

重要: 静的レンディションのパスまたは生成されたレンディションのリストを仮定しないでください。これらは変更される可能性があります。特定のレンディションが Amazon IVS 録画で常に使用可能であると前提にしないでください。利用可能なレンディション、解像度、パスを決定するには、メタデータファイルを参照してください。

録画プレフィックス内の event/recording_started.json または event/recording_ended.json ファイルには、録画プレフィックス内のメディアファイルのパスと名前が含まれています。すべての path 要素は、階層内の前のパスに関連しています。media > hls の要素は HLS アセットを表しており、マスタープレイリスト名とパスがこのレベルで定義されています。

S3 録画プレフィックスとメタデータファイルを使用して、マスタープレイリストパスを生成する方法を示す Python コードスニペットを次に示します。

def get_master_playlist(metadata_json, s3_recording_prefix): return s3_recording_prefix + '/' + metadata_json['media']['hls']['path'] + '/' + metadata_json['media']['hls']['playlist']

media > hls > renditions の要素は、記録されたレンディションのリストを表します。resolution_height および resolution_width プロパティは、動画の解像度を特定するために使用されます。path および playlist 要素は、レンディションプレイリストパスを取得するために使用されます。これらのフィールドを使用して、後処理に使用するレンディションを決定します。

「IVS Recording State Change」の EventBridge イベントをサブスクライブすることで、録画に使用できる最も高いレンディションプレイリストを特定できます。(「IVS で Amazon EventBridge を使用する」を参照してください。) これらのイベントへサブスクライブされた Lambda 関数の使用例を示す Python スクリプトを以下に示します。

import json import boto3 s3 = boto3.resource('s3') def get_highest_rendition_playlist(bucket_name, prefix_name): object_path = "{}/events/recording-started.json".format(prefix_name) object = s3.Object(bucket_name, object_path) body = str(object.get()['Body'].read().decode('utf-8')) metadata = json.loads(body) media_path = metadata["media"]["hls"]["path"] renditions = metadata["media"]["hls"]["renditions"] highest_rendition = None highest_rendition_size = 0 for rendition in renditions: current_rendition_size = rendition["resolution_height"] if (current_rendition_size > highest_rendition_size): highest_rendition_size = current_rendition_size highest_rendition = rendition highest_rendition_playlist = media_path + '/' + highest_rendition['path'] + '/' + highest_rendition['playlist'] return highest_rendition_playlist def lambda_handler(event, context): prefix_name = event["detail"]["recording_s3_key_prefix"] bucket_name = event["detail"]["recording_s3_bucket_name"] rendition_playlist = get_highest_rendition_playlist(bucket_name, prefix_name) print("Highest rendition playlist: {}/{}".format(prefix_name, rendition_playlist)) return { 'statusCode': 200, 'body': rendition_playlist }

プライベートバケットからの録画コンテンツの再生

Amazon S3 への自動録画機能で録画されたオブジェクトは、デフォルトではプライベートです。したがって、これらのオブジェクトは S3 のダイレクト URL を使用してアクセスして再生することはできません。Amazon IVS プレーヤーまたは別のプレーヤーを使用して再生するために HLS マスターマニフェスト (m3u8 ファイル) を開こうとすると、エラー (「You do not have permission to access the requested resource」など) が表示されます。代わりに、Amazon CloudFront CDN(コンテンツ配信ネットワーク)を使用してこれらのファイルを再生することができます。

Amazon CloudFront ディストリビューション

CloudFront ディストリビューションは、プライベートバケットからコンテンツを配信するように設定できます。通常、これは、読み取りが CloudFront が提供するコントロールをバイパスするオープンにアクセス可能なバケットを持つよりも望ましいです。オリジンアクセスコントロール (OAC) を作成すると、プライベートバケットからサービスを配信するようにディストリビューションを設定できるようになります。OAC は特別な CloudFront ユーザーで、プライベートオリジンバケットに対する読み取りアクセス許可を持ちます。ディストリビューションの作成後、CloudFront コンソールまたは API を使用して OAC を作成することができます。「新しいオリジンアクセスコントロールの作成」を参照してください。

Amazon CloudFront からの再生

OAC を使用してディストリビューションを設定し、プライベートバケットへのアクセス許可を取得すると、CloudFront URL を介してビデオファイルを使用できるようになります。CloudFront の URL は、AWS CloudFront コンソールの [詳細] タブにある [ディストリビューションドメイン名] です。次のように表示されます。

a1b23cdef4ghij.cloudfront.net

録画した動画をディストリビューションでストリーミングするには、master.m3u8 ファイルのオプジェクトキーを使います。次のように表示されます。

ivs/v1/012345678912/a0bCDeFGH1IjK/2021/4/20/12/03/aBcdEFghIjkL/media/hls/master.m3u8

CloudFront URL の末尾にオブジェクトキーを追加します。最終的にページ URL は次のようになります。

https://a1b23cdef4ghij.cloudfront.net/ivs/v1/012345678912/a0bCDeFGH1IjK/2021/4/20/12/03/aBcdEFghIjkL/media/hls/master.m3u8

ウェブブラウザから再生するには、必ず CloudFront と S3 バケットの両方で CORS を設定してください。CloudFront の設定には、「オリジンリクエストポリシーの作成」の手順に従い、CORS-S3 オリジンリクエストポリシーと SimpleCORS レスポンスヘッダーポリシーを CloudFront ディストリビューションにアタッチします。以下の設定コンソールページの例を参照してください。

コンソール設定の例のページ。キャッシュキーとオリジンリクエストを制御するには、キャッシュポリシーとオリジンリクエストポリシーを使用することをお勧めします。

S3 CORS 設定については、「CORS の設定」を参照して、S3 バケットに適切なルールを作成してください。

録画した動画を、バケットから直接再生しているかのように再生できるようになりました。

詳細については、「Amazon S3 オリジンへのアクセスの制限」を参照してください。