VOD 串流資訊清單操控器

Pod 供應 API 提供可自動調整的位元率影片廣告連播,使其直接拼接至面向使用者的 HLS 或 MPEG-DASH 媒體播放清單。

本指南著重於實作 VOD 串流的基本 Pod 服務資訊清單操控伺服器。

接收串流資訊清單要求

資訊清單操控工具必須提供 API 端點,以監聽來自影片播放器用戶端應用程式的資訊清單要求。此端點至少必須從用戶端播放器應用程式收集串流 ID,這個串流 ID 會用來在 Pod 請求中識別與 Ad Manager 的串流工作階段。

您還需要收集其他資訊,才能找出適當的內容串流,例如內容 ID。

資訊清單要求端點範例

GET /api/stream_id/{stream_id}/video/{content_id}.{format}
Host: {your_domain}
路徑參數
stream_id 用戶端影片播放器應用程式的 Ad Manager 串流 ID。
content_id 在您系統中內容影片對應的假設 ID。
format 與串流格式相對應的假設參數。以下其中之一:
mpd 適用於 MPEG-DASH 串流
m3u8 適用於 HLS 串流

擷取內容串流

請使用從資訊清單要求收集的內容 ID,選取要與廣告拼接的內容串流。

請求廣告連播資訊清單

若要向 Ad Manager 請求廣告,您的伺服器必須向 Pod 端點發出 POST 要求,傳送要求的編碼設定檔、廣告代碼和指定參數。這項要求也會包含您在步驟 1 收集的串流 ID。

會傳回 Pod 物件清單,其中包含發布商廣告代碼要求的廣告連播資訊清單檔案,以及這些 Pod 應插入內容的時機和位置等資訊。

POST /ondemand/pods/api/v1/network/{network_code}/streams/{stream_id}/adpods
Host: dai.google.com
Content-Type: application/json
路徑參數
network_code 發布商的 Ad Manager 360 聯播網代碼。
stream_id 用戶端影片播放器應用程式的串流 ID。

JSON 主體

內文參數
encoding_profiles Required 針對每個廣告插播接收的編碼設定檔 JSON 表示法清單。請參閱以下詳細資訊

為了盡可能提供流暢的播放體驗,這個值應與內容串流中所用的編碼設定檔組合相符。

ad_tag Required 用來請求 VMAP 廣告的廣告代碼。
cuepoints Optional 內容串流中插入片中廣告的提示點清單。提示點的測量單位為浮點秒數。

只有包含使用位置時間偏移的片中廣告的 VMAP 回應才需要。這種情況並不常見。

content_duration_seconds Optional 內容時間長度 (以秒為單位)。

只有包含片中廣告的 VMAP 回應 (使用 percentage 時間偏移) 才需要提供。這種情況並不常見。

manifest_type Optional 所請求的廣告請求格式,可以是 hlsdash。預設值為 hls
dai_options Optional 其他選項可控管資訊清單的轉譯方式。請參閱以下詳細資訊
編碼設定檔
profile_name Required 此編碼設定檔的 ID。這個值可以是您選擇的任何字串,但同一串流中不能有多個名稱相同的編碼設定檔。
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 一個整數,代表這個設定檔的影片位元率上限 (以每秒位元組為單位)。
frames_per_second Required 影片的浮點 FPS。
resolution Required 包含影片的「寬度」和「高度」(以像素為單位) 的 JSON 編碼值。

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

音訊設定
codec Required RFC6381 轉碼器字串。

範例:mp4a.40.5

bitrate Required 一個整數,代表這個設定檔的音訊位元率上限 (以每秒位元組為單位)。

範例:300000

channels Required 代表音訊聲道數的整數,包括低頻率聲道。
sample_rate Required 代表赫茲音訊取樣率的整數。

範例:4800

字幕設定
format Required 頻內字幕使用的檔案格式。支援的值為 webvttttml
language Optional 字幕語言,以 RFC5646 語言字串表示。如有提供,這個值只會用於 DASH 算繪。

範例:en-us

動態廣告插播選項
dash_profile Optional 要套用至 Pod 資訊清單的 MPEG-DASH 設定檔。這項設定僅適用於 DASH 資訊清單。允許的值為 liveon-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 Manager 會傳回 ad_pods 回應中已選取的所有廣告,並停止處理。
sam_id Optional 指定替代偵錯金鑰,可用於在串流活動監控器中查詢工作階段。

回應

回應參數
valid_for 這些 Pod 播放清單有效的時間長度,格式為 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 格式拼接串流,內容串流會是多重變化版本播放清單,內含不同串流資訊清單的連結,每個編碼設定檔各一個。您必須將廣告連播插入這些變化版本資訊清單中。其中一個做法是準備所有變數資訊清單,並將其傳送至內容傳遞聯播網 (CDN) 進行代管。最終的多變化版本播放清單是一組指向這些 CDN 託管資訊清單的連結。

疊代編碼設定檔

針對每個編碼設定檔,從 Ad Manager 的回應收集所有相關聯的廣告 Pod 資訊清單,以及相關開始時間。如果是片頭廣告連播,請將開始時間設為 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

在各個變化版本資訊清單中插入廣告

針對每個變數串流,查看內容資訊清單的區段,維持已播放的內容總時間。前往廣告連播的起始位置時,請從廣告連播的資訊清單中擷取區隔清單,在兩個 #EXT-X-DISCONTINUITY 標記中納入區隔清單,然後在內容資訊清單中的目前位置插入該清單。繼續執行此程序,直到所有廣告連播和變化版本串流都處理完畢為止。

產生的資訊清單必須符合 HLS 標準。因此,根據內容資訊清單納入的規格功能,您可能需要進行最終傳遞,以修正媒體序列編號、內容時間長度、停止序號和任何其他標記,以便將新廣告區隔納入考量。修復與標準之間的任何差異後,請將每個使用者專屬的變化版本資訊清單推送至 CDN 進行託管。

如果內容資訊清單已加密,您必須將最後找到的加密金鑰儲存在 #EXT-X-KEY 標記中目前 Pod 的開頭。接著,您必須新增 #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 格式拼接串流,則只需要產生單一檔案。這樣一來,DASH 串流的拼接方式會比 HTTP 即時串流更容易。

正確準備的 MPEG DASH 媒體呈現說明 (MPD) 檔案應由多個時段組成,每個句號都包含多個表示法。每個表示法都必須與其中一個編碼設定檔相符。從 Ad Manager 傳回的每個廣告連播,也是 MPD 檔案,其中包含一個具有比對表示法的連續時段。

如要將這些 MPD 檔案拼接在一起,請先記下每個廣告連播的開始時間。針對片頭廣告,請在內容時段前插入片頭廣告連播。針對片尾廣告,請在所有內容時段後插入片尾廣告連播時段。疊代內容 MPD 中的時段,追蹤所有已處理內容時段的播放時間。如果觸及時段與廣告連播開始時間相對應,請在該邊界插入相符片中廣告 Pod 的 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>

Pod 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>

其他資源