VOD ストリーム用のマニフェスト マニピュレータ

Pod Serving API は、ユーザー向けの HLS または MPEG-DASH メディア再生リストに直接合成できるように準備されたアダプティブ ビットレートの動画広告連続配信広告にアクセスできます。

このガイドでは、VOD ストリーム用の基本的な Pod Serving マニフェスト操作サーバーの実装に焦点を当てています。

ストリーム マニフェスト リクエストを受信する

マニフェスト マニピュレータでは、動画プレーヤー クライアント アプリからのマニフェスト リクエストをリッスンする API エンドポイントを指定する必要があります。このエンドポイントは、少なくともクライアント プレーヤー アプリからストリーム ID を収集する必要があります。このストリーム ID は、連続配信広告のリクエストでアド マネージャーへのストリーミング セッションを識別するために使用されます。

また、適切なコンテンツ ストリームを識別するために、その他の情報(コンテンツ ID など)も収集する必要があります。

マニフェスト リクエスト エンドポイントの例

GET /api/stream_id/{stream_id}/video/{content_id}.{format}
Host: {your_domain}
パスパラメータ
stream_id クライアント動画プレーヤー アプリのアド マネージャー ストリーム ID。
content_id システムのコンテンツ動画に対応する仮の ID。
format ストリーム形式に対応する仮のパラメータ。次のいずれかです。
mpd MPEG-DASH ストリームの場合
m3u8 HLS ストリームの場合

コンテンツ ストリームを取得する

マニフェスト リクエストから収集したコンテンツ ID を使用して、広告と合成するコンテンツ ストリームを選択します。

連続配信広告のマニフェストをリクエストする

アド マネージャーの広告をリクエストするには、サーバーから連続配信広告のエンドポイントに POST リクエストを行い、リクエストされたエンコード プロファイル、広告タグ、ターゲティング パラメータを渡す必要があります。このリクエストには、手順 1 で収集したストリーム ID も含まれます。

代わりに、パブリッシャーの広告タグによってリクエストされた連続配信広告のマニフェスト ファイルと、それらをコンテンツに挿入するタイミングと場所に関する情報が含まれている連続配信広告オブジェクトのリストを受け取ります。

POST /ondemand/pods/api/v1/network/{network_code}/streams/{stream_id}/adpods
Host: dai.google.com
Content-Type: application/json
パスパラメータ
network_code パブリッシャーのアド マネージャー 360 ネットワーク コード。
stream_id クライアント動画プレーヤー アプリのストリーム ID。

JSON 本文

身体パラメータ
encoding_profiles Required 各広告ブレークで受け取るエンコード プロファイルの JSON 表現のリスト。下記の詳細をご覧ください

再生を可能な限りシームレスにするには、コンテンツ ストリームで使用されているエンコード プロファイルのセットと一致させる必要があります。

ad_tag Required VMAP 広告をリクエストするための広告タグ。
cuepoints Optional ミッドロール挿入点が挿入される、コンテンツ ストリーム内のキューポイントのリスト。キューポイントは浮動小数点秒数です。

位置の時間オフセットを使用したミッドロールを含む VMAP レスポンスの場合にのみ必要です。これはまれです。

content_duration_seconds Optional コンテンツの再生時間(秒単位)。

% 時間オフセットを使用したミッドロールを含む VMAP レスポンスの場合にのみ必要です。これはまれです。

manifest_type Optional リクエストされている広告ストリームのフォーマット(hls または dash)。デフォルト値は hls です。
dai_options Optional マニフェストのレンダリング方法を制御する追加オプション。 下記の詳細をご覧ください
プロファイルのエンコード
profile_name Required このエンコード プロファイルの識別子。この値には任意の文字列を指定できますが、同じストリームに同じ名前の複数のエンコード プロファイルを設定することはできません。
type Required このエンコード プロファイルによって記述されるストリームのエンコード タイプ。コンテンツ タイプは、mediaiframesubtitles です。
container_type Required このエンコード プロファイルで使用されるコンテナ形式。コンテナの形式は、mpeg2tsfmp4cmafhls_packed_audio です。
video_settings Optional エンコード プロファイル タイプが iframe の場合は必須。それ以外の場合は、メディアタイプに動画が含まれている場合にのみ許可されます。詳しくは以下をご覧ください
audio_settings Optional エンコード プロファイルに音声が含まれている場合は必須です。タイプがメディアの場合にのみ許可されます。下記の詳細をご覧ください
subtitle_settings Optional エンコード プロファイルに字幕が含まれている場合は必須。 下記の詳細をご覧ください
動画の設定
codec Required RFC6381 コーデック文字列。

例: avc1.4d000c

bitrate Required このプロファイルの最大動画ビットレートを 1 秒あたりのバイト数で表す整数。
frames_per_second Required 動画の浮動小数点 FPS。
resolution Required 動画の「width」と「height」をピクセル単位で含む JSON エンコードの値。

例: {"width": 640, "height": 320}

音声設定
codec Required RFC6381 コーデック文字列。

例: mp4a.40.5

bitrate Required このプロファイルの最大音声ビットレートを 1 秒あたりのバイト数で表す整数。

例: 300000

channels Required 低周波数チャンネルを含む音声チャンネルの数を表す整数。
sample_rate Required 音声のサンプリング レート(ヘルツ単位)を表す整数。

例: 4800

字幕の設定
format Required インバンド字幕で使用されるファイル形式。指定できる値は webvtt または ttml です。
language Optional 字幕言語を RFC5646 言語文字列で表したもの。指定すると、この値は DASH レンダリングでのみ使用されます。

例: en-us

DAI オプション
dash_profile Optional 連続配信広告のマニフェストに適用する MPEG-DASH プロファイル。この設定は DASH マニフェストにのみ使用されます。指定できる値は live または on-demand です。デフォルト値は on-demand です。

live は、MPEG-DASH プロファイル"urn:mpeg:dash:profile:isoff-live:2011" に対応しています。

on-demand は、MPEG-DASH プロファイルurn:mpeg:dash:profile:isoff-on-demand:2011 に対応しています。

ad_pod_timeout Optional 広告の選択と連続配信広告の作成に費やす最大時間(浮動小数点秒単位)。指定した時間が経過すると、アド マネージャーは ad_pods レスポンスですでに選択されている広告を返し、処理を停止します。
sam_id Optional ストリーム アクティビティ モニターでセッションの検索に使用できる代替デバッグキーを指定します。

レスポンス

レスポンス パラメータ
valid_for 連続配信広告の再生リストの有効期間を dhms(日、時間、分、秒)形式で表します。
valid_until 連続配信広告の再生リストの有効期間を、ISO8601 の日時文字列として yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm 形式で示す日時です。
ad_pods このストリームで選択された連続配信広告のリスト。
連続配信広告
manifest_uris HLS ストリームの場合のみ。エンコード プロファイル ID と HLS マニフェスト URI のマッピング。
mpd_uri DASH ストリームの場合のみ。DASH MPD の URI。
type 連続配信広告のタイプ。連続配信広告のタイプは premidpost です。
start ミッドロールの連続配信広告のみが対象です。この連続配信広告を挿入するストリーム内の位置(浮動小数点数)。
duration この連続配信広告の再生時間(浮動小数点数)。
midroll_index ミッドロールの連続配信広告のみが対象です。現在のミッドロール連続配信広告のインデックス。インデックスは 1 で始まります。

リクエストの例(cURL)

curl -X POST \
     -d '@request-body.json' \
     -H 'Content-Type: application/json' \
  https://dai.google.com/ondemand/pods/api/v1/network/21775744923/streams/6e69425c-0ac5-43ef-b070-c5143ba68541:CHS/adpods

リクエスト本文の例

これは、上記の cURL 呼び出しで参照されている request_body.json の内容です。

{
  "encoding_profiles": [
   {
     "profile_name": "1080p",
     "type": "media",
     "container_type": "mpeg2ts",
     "video_settings": {
       "codec": "avc1.4d000c",
       "bitrate": 5000000,
       "frames_per_second": 30.0,
       "resolution": {
         "width": 1920,
         "height": 1080
       }
     },
     "audio_settings": {
       "codec": "mp4a.40.5",
       "bitrate": 300000,
       "channels": 2,
       "sample_rate": 48000
     }
   },
   {
     "profile_name": "360p",
     "type": "media",
     "container_type": "mpeg2ts",
     "video_settings": {
       "codec": "avc1.4d000d",
       "bitrate": 1000000,
       "frames_per_second": 30.0,
       "resolution": {
         "width": 640,
         "height": 360
       }
     },
     "audio_settings": {
       "codec": "mp4a.40.5",
       "bitrate": 64000,
       "channels": 2,
       "sample_rate": 48000
     }
   },
   {
     "profile_name": "subtitles-webvtt",
     "type": "subtitles",
     "subtitle_settings": {
       "format": "webvtt"
     }
   }
 ],
 "ad_tag": "https://pubads.g.doubleclick.net/gampad/ads?...",
 "manifest_type": "hls"
}

レスポンスの例

{
  "valid_for": "8h0m0s",
  "valid_until": "2023-03-24T08:30:26.839717986-07:00",
  "ad_pods": [
    {
      "manifest_urls":{
        "1080p": "https://{...}/pod/0/profile/1080p.m3u8",
        "360p": "https://{...}/pod/0/profile.m3u8",
        "subtitles-webvtt": "https://{...}/pod/0/profile/subtitles-en.vtt"
      },
      "type": "pre",
      "duration": 10.0
    },
    {
      "manifest_urls":{
        "1080p": "https://{...}/pod/1/profile/1080p.m3u8",
        "360p": "https://{...}/pod/1/profile.m3u8",
        "subtitles-webvtt": "https://{...}/pod/1/profile/subtitles-en.vtt"
      },
      "type": "mid",
      "start": 15.0,
      "duration": 15.0,
      "midroll_index": 1
    },
    {
      "manifest_urls":{
        ]"1080p": "https://{...}/pod/2/profile/1080p.m3u8",
        "360p": "https://{...}/pod/2/profile.m3u8",
        "subtitles-webvtt": "https://{...}/pod/0/profile/subtitles-en.vtt""
      },
      "type": "post",
      "duration": 10.0
    }
  ]
}

連続配信広告をコンテンツに組み込む

連続配信広告をコンテンツ ストリームに結合するプロセスは、実装、ストリーム形式、フォーマットの仕様に基づいて実装する機能によって異なります。次のワークフローは、このプロセスを処理する方法の推奨事項です。実装の正確な詳細は、ビジネスニーズやコンテンツ ストリームによって異なる可能性があります。

HLS ストリーム

HLS 形式のストリームを合成する場合、コンテンツ ストリームは、エンコード プロファイルごとに 1 つずつ、別々のストリーム マニフェストへのリンクからなるマルチバリアント プレイリストになります。連続配信広告は、これらの各バリアント マニフェストに挿入する必要があります。そのための 1 つの方法は、すべてのバリアント マニフェストを準備し、それらをコンテンツ配信ネットワーク(CDN)に渡してホスティングすることです。最終的なマルチバリエーション再生リストは、CDN でホストされるマニフェストへのリンクのセットです。

エンコード プロファイルを反復処理する

エンコード プロファイルごとに、アド マネージャーのレスポンスから、関連するすべての連続配信広告のマニフェストと、それぞれに関連付けられた開始時間を収集します。プレロール連続配信広告の場合は、開始時間を 0 に設定します。ポストロールの場合は、コンテンツの再生時間を連続配信広告の開始時間として使用します。マルチバリアント プレイリストで、各エンコード プロファイルの音声と動画の設定に一致するバリアント ストリームを特定します。

連続配信広告の配列の例
"ad_pods": [
    {
      "manifest_urls":{
        "1080p": "https://{...}/pod/0/profile/1080p.m3u8",
        "360p": "https://{...}/pod/0/profile/360p.m3u8",
        "subtitles-en": "https://{...}/pod/0/profile/subitles-en.vtt"
      },
      "type": "pre",
      "duration": 10.0
    },
    {
      "manifest_urls":{
        "1080p": "https://{...}/pod/1/profile/1080p.m3u8",
        "360p": "https://{...}/pod/1/profile/360p.m3u8",
        "subtitles-en": "https://{...}/pod/1/profile/subitles-en.vtt"
      },
      "type": "mid",
      "start": 15.0,
      "duration": 15.0,
      "midroll_index": 1
    },
    {
      "manifest_urls":{
        "1080p": "https://{...}/pod/2/profile/1080p.m3u8",
        "360p": "https://{...}/pod/2/profile/360p.m3u8",
        "subtitles-en": "https://{...}/pod/2/profile/subitles-en.vtt"
      },
      "type": "post",
      "duration": 10.0
    }
  ]
マルチバリエーション コンテンツ再生リストの例
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs0",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="https://{...}/subitles-en.vtt"
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://{...}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://{...}/360p.m3u8
収集されたバリアント データの例
Encoding profile: "1080p"
Profile settings: {...}
Content manifest: https://{...}/1080p.m3u8
Ad pods (start time -> manifest):
    0 -> https://{...}/pod/0/profile/1080p.m3u8
   15 -> https://{...}/pod/1/profile/1080p.m3u8
  600 -> https://{...}/pod/2/profile/1080p.m3u8

各パターンのマニフェストに広告を挿入する

バリアント ストリームごとに、コンテンツ マニフェストのセグメントを通過し、コンテンツの経過時間の合計を維持します。連続配信広告の開始位置が来たら、連続配信広告のマニフェストからセグメントのリストを抽出し、セグメントのリストを 2 つの #EXT-X-DISCONTINUITY タグで囲み、コンテンツ マニフェストの現在の位置にリストを挿入します。すべての連続配信広告とパターン ストリームの処理が完了するまでこのプロセスを続けます。

作成されるマニフェストは HLS 標準に準拠している必要があります。そのため、コンテンツ マニフェストに組み込まれている仕様の機能によっては、結合されたマニフェストを最後に処理して、メディア シーケンス番号、コンテンツ継続時間、不連続シーケンス番号、新しい広告セグメントを考慮するために更新する必要があるその他のタグを修正する必要があります。標準との不一致を修正したら、ユーザー固有の各バリアント マニフェストを CDN にプッシュしてホストします。

コンテンツ マニフェストが暗号化されている場合は、現在の連続配信広告の開始前に検出された最後の暗号鍵を #EXT-X-KEY タグに保存する必要があります。その後、各連続配信広告の最初のセグメントの前に #EXT-X-KEY:METHOD=NONE タグを追加して、暗号化を解除する必要があります。最後に、各連続配信広告の後のコンテンツの最初のセグメントの前に、保存されている #EXT-X-KEY タグのコピーを追加して、コンテンツの暗号化を元に戻す必要があります。

収集されたバリアント データの例
Encoding profile: "1080p"
Content manifest: https://{...}/1080p.m3u8
Ad pods (start time -> manifest):
    0 -> https://dai.google.com/{...}pod/0/profile/1080p.m3u8
   15 -> https://dai.google.com/{...}pod/1/profile/1080p.m3u8
  600 -> https://dai.google.com/{...}pod/2/profile/1080p.m3u8
コンテンツ マニフェストの例

これは、収集されたバリアント データにリストされる https://{...}/1080p.m3u8 マニフェストの内容です。

#EXTM3U
{...}
#EXTINF:5.000,
https://{...}/1080p/content-segment-0.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-1.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-2.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-3.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-4.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-5.ts
{...}
連続配信広告のマニフェストの例

これは、収集されたバリアント データにリストされている https://dai.google.com/{...}/pod/1/profile/1080p.m3u8 マニフェストの内容です。

#EXTM3U
{...}
#EXTINF:5.000,
https://dai.google.com/{...}/0.ts
#EXTINF:5.000,
https://dai.google.com/{...}/1.ts
#EXTINF:5.000,
https://dai.google.com/{...}/2.ts
合成されたバリアント マニフェストの例

これは、合成されたバリアント マニフェストであり、CDN に渡され、https://cdn.{...}/{userid}/1080p.m3u8 でホストされます。

#EXTM3U
{...}
#EXTINF:5.000,
https://{...}/1080p/content-segment-0.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-1.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.000,
https://dai.google.com/{...}/0.ts
#EXTINF:5.000,
https://dai.google.com/{...}/1.ts
#EXTINF:5.000,
https://dai.google.com/{...}/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.000,
https://{...}/1080p/content-segment-3.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-4.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-5.ts
{...}

マルチバリエーション再生リストを作成する

完成したバリアント マニフェストごとに CDN アドレスを一致するエンコード プロファイルの詳細とともに収集し、その結果を新しいマルチバリアント マニフェストにアセンブルします。このユーザー固有のマニフェストは、ステップ 1 で受信したマニフェスト リクエストへのレスポンスとして返されます。

最終的なマルチバリエーション再生リストの例
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs0",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="https://cdn.{...}-subitles-en.vtt"
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/{userid}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://cdn.{...}/{userid}/360p.m3u8

MPEG DASH ストリーム

MPEG DASH 形式のストリームを合成する場合は、ファイルを 1 つだけ生成すれば済みます。これにより、HLS よりも DASH ストリームの合成が容易になります。

適切に準備された MPEG DASH Media Presentation Description(MPD)ファイルは、複数の期間で構成され、それぞれに複数の表現が含まれている必要があります。各表現は、いずれかのエンコード プロファイルと一致する必要があります。アド マネージャーから返される各連続配信広告も MPD ファイルです。MPD ファイルには、対応する表現を含む一連のピリオドが含まれています。

これらの MPD ファイルをつなぎ合わせるには、まず、各連続配信広告の開始時間をメモします。プレロールの場合は、任意のコンテンツ期間の前にプレロール連続配信広告の期間を挿入します。ポストロールの場合は、すべてのコンテンツ期間の後にポストロール連続配信広告期間を挿入します。処理されたすべてのコンテンツ期間の再生時間を追跡しながら、コンテンツ MPD 内の期間を反復処理します。連続配信広告の開始時間に対応する期間の境界に達したら、一致するミッドロール連続配信広告の MPD ファイルからその境界内の期間を挿入します。

最終的に合成された MPD ファイルは MPEG_DASH 仕様に完全に準拠している必要があります。そのため、最終ファイルの反復処理をもう一度行い、期間の開始時間を修正したり、新しく挿入された広告期間に合わせてメディアの表示時間を修正したり、合成プロセスで生じ得るその他の競合を解決したりする必要があります。

コンテンツの MPD の例

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H10M00.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
  <ProgramInformation moreInformationURL="http://.../info">
    <Title>Example Stream</Title>
  </ProgramInformation>
  <Period duration="PT0H0M15.000S" id="content-period-1">
    ...
  </Period>
  <Period duration="PT0H0M15.000S" id="content-period-2">
    ...
  </Period>
  <Period duration="PT0H0M15.000S" id="content-period-3">
    ...
  </Period>
  ...
</MPD>

連続配信広告の JSON の例

[{
  "mpd_uri": "https://{...}pod/1.mpd",
  "type": "mid",
  "start": 15.0,
  "duration": 15.0,
  "midroll_index": 1
}]

連続配信広告の MPD の例

これは、上記の連続配信広告 JSON の mpd_uri の内容です。

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H0M15.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
  <ProgramInformation moreInformationURL="http://.../info">
    <Title>Ad Pod 1</Title>
  </ProgramInformation>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-1">
    ...
  </Period>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-2">
    ...
  </Period>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-3">
    ...
  </Period>
  ...
</MPD>

合成された MPD の例

これを最初のストリーム マニフェスト リクエストに対するレスポンスとして使用します。

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H10M15.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
  <ProgramInformation moreInformationURL="http://.../info">
    <Title>Example Stream</Title>
  </ProgramInformation>
  <Period duration="PT0H0M15.000S" id="content-period-1">
    ...
  </Period>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-1">
    ...
  </Period>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-2">
    ...
  </Period>
  <Period duration="PT0H0M5.000S" id="ad-pod-1-period-3">
    ...
  </Period>
  <Period duration="PT0H0M15.000S" id="content-period-2">
    ...
  </Period>
  <Period duration="PT0H0M15.000S" id="content-period-3">
    ...
  </Period>
  ...
</MPD>

補足資料