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 コンテンツの長さ(秒単位)。

percentage タイム オフセットを使用してミッドロールを含む 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 です。

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

on-demandMPEG-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 連続配信広告のタイプ。連続配信広告のタイプ: premid、または post
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 に push してホストします。

コンテンツ マニフェストが暗号化されている場合は、現在の連続配信広告の開始前に見つかった最後の暗号鍵を #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 ファイルは MPEG_DASH 仕様に完全に準拠している必要があるため、最終ファイルをもう 1 回繰り返して期間の開始時間を修正し、新しく挿入された広告期間に合わせてメディアの表示時間を修正し、合成プロセスに起因するその他の競合を解決する必要があります。

サンプル コンテンツ 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>

参考情報