用于 VOD 视频流的清单操纵器

Pod Serving API 可让您访问准备好的自适应比特率视频广告连播, 使它们可以直接拼接到面向用户的 HLS 或 MPEG-DASH 媒体播放列表。

本指南重点介绍如何实现基本的 Pod Serving 清单操作 服务器。

接收视频流清单请求

您的清单操纵器必须提供 API 端点来监听清单 来自视频播放器客户端应用的请求。此端点至少必须 从客户端播放器应用中收集视频流 ID。此数据流 ID 用于 在广告连播请求中识别发送到 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 请求广告,您的服务器必须向广告发出 POST 请求 广告连播端点,传递请求的编码配置文件、广告代码和定位条件 参数。此请求还包含您在“步骤”中收集的数据流 ID 1.

反过来,您收到一个广告连播对象列表,其中包含 发布商的广告代码请求的广告连播,以及有关何时和 插入内容的位置

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 响应中包含使用 positional 时间偏移。这种情况并不常见。

content_duration_seconds Optional 内容时长(以秒为单位)。

仅在 VMAP 响应中包含使用 percentage 时间偏移。这种情况并不常见。

manifest_type Optional 所请求的广告流的格式,即 hlsdash。默认值为 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 一个整数,表示此配置文件的视频比特率上限(以字节/ 。
frames_per_second Required 视频的浮点 FPS。
resolution Required 包含视频 `width` 和 `height` 的 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

DAI 选项
dash_profile Optional 要应用于广告连播清单的 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 这些广告连播播放列表的有效期(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 开头。

示例请求 (c网址)

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

请求正文示例

这是上面 c网址 调用中引用的 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 格式的视频流,您的内容视频流将是 多变体 播放列表 多个指向单独视频流清单的链接(每个编码配置文件对应一个)。您的广告 Pod 需要插入到每个变体清单中。要想 这样做是为了准备所有变体清单,并将它们传递给 Content 分发网络 (CDN) 托管。最后的多变体播放列表是一组指向这些由 CDN 托管的链接 清单。

迭代编码配置文件

对于每个编码配置文件,从以下位置收集所有关联的广告连播清单: Ad Manager 的响应以及相关的开始时间。对于前贴片广告 请将开始时间设置为 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然后, 您需要先添加 #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 视频流比 HLS 更容易拼接。

适当准备的 MPEG DASH 媒体呈现描述 (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>

其他资源