本指南介绍了如何使用广告插播时间元数据 (ATM) 方法插入广告插播,以获取广告插播(包括前贴片广告)的精确时间和时长。
若要插入前贴片广告并管理中贴片广告插播时间点结束后返回内容,建议您调用以下 API:
- 广告连播时间元数据 (ATM) API:查询广告连播决策结果,包括广告和插播时段时长。
- 广告片段端点:请求广告或插播广告片段,并可以选择终止当前广告插播时段。
(可选)对于高并发直播活动,我们建议您调用广告插播时间点提前通知 (EABN) API,以便在广告插播开始之前安排广告决策。
前提条件
首先,您需要设置一个直播活动,并将其动态广告插播 (DAI) 类型设为广告连播投放重定向。选择以下方法之一:
- Ad Manager 界面: 为 DAI 设置直播。
- Ad Manager API:使用客户端库(可用选项)调用
LiveStreamEventService.createLiveStreamEvents
方法。将LiveStreamEvent.dynamicAdInsertionType
参数设置为POD_SERVING_REDIRECT
。
检索内容流
当用户选择直播活动时,客户端应用会向 Google Ad Manager 发出直播请求。在流式响应中,应用会提取 Google DAI 会话 ID 和元数据,以包含在流清单请求中。
以下示例将 Google DAI 会话 ID 传递给清单操纵器:
https://MANIFEST_MANIPULATOR_URL/manifest.m3u8?DAI_stream_ID=SESSION_ID&network_code=NETWORK_CODE&DAI_custom_asset_key=CUSTOM_ASSET_KEY
在处理视频内容播放请求时,存储请求中的 Google DAI 会话 ID 和 CUSTOM_ASSET_KEY,以便为广告拼接做好准备。
检索广告插播时间元数据
如需检索广告插播时间,请按以下步骤操作:
- 生成 HMAC 令牌。
- 使用 HMAC 令牌调用 ATM API。
生成已签名的 HMAC 令牌
如需对请求进行身份验证,请按以下步骤操作:
按字母顺序连接以下参数,并用波浪号
~
分隔,以创建令牌字符串:参数 必填或可选 说明 ad_break_id
必需 您指定的用于标识广告插播时间的字符串,例如 ad-break-1
。对于前贴片广告,请使用preroll
。custom_asset_key
必需 直播活动的自定义素材资源键。 cust_params
可选 自定义定位参数。如需了解详情,请参阅为视频流提供定位参数。 exp
必需 相应令牌的到期时间,以自 Unix 纪元以来经过的总秒数来衡量。 network_code
必需 您的 Google Ad Manager 广告资源网代码。如需了解详情,请参阅查找 Ad Manager 账号信息。 pd
必需 广告插播时段时长(以毫秒为单位)。对于前贴片广告,Google DAI 会使用直播活动设置替换此参数。 scte35
可选 采用 Base64 编码的 SCTE-35 信号。验证信号是否正确。如果值不正确,系统会在响应中向 X-Ad-Manager-Dai-Warning
HTTP 标头发送一条消息,并且仍会传播信号以创建广告插播时间。如需详细了解支持的广告插播标记,请参阅 HLS 集成。下载您的 Google DAI 身份验证密钥(类型为 HMAC)。如需了解详情,请参阅对 DAI 视频流请求进行身份验证。
使用下载的 HMAC 密钥生成令牌字符串的 SHA256 签名。
串联令牌字符串和生成的签名。
对串联后的字符串应用网址编码。编码后的字符串是用于对广告插播时间元数据 (ATM) API 请求进行身份验证的已签名 HMAC 令牌。
以下示例会为前贴片广告生成已签名的 HMAC 令牌:
custom_asset_key="CUSTOM_ASSET_KEY"
exp="1750700000" # Expired on Mon Jun 23 2025 13:33:20 GMT-0400 (Eastern Daylight Time)
network_code="NETWORK_CODE"
ad_break_id="preroll"
pd="0" # Pod duration value is overridden by the livestream event settings.
# The HMAC authentication key associated with your livestream event in Google Ad Manager.
secret_key="24E96382584C328087546B0E8454F26158564E8466FD2BE3D8A996B38445876C"
# Concatenate the parameters, keep the parameters alphabetically ordered by name.
token_string="ad_break_id=${ad_break_id}~custom_asset_key=${custom_asset_key}~exp=${exp}~network_code=${network_code}~pd=${pd}"
# Calculate the SHA256 signature of the token_string.
hmac_signature=$(echo -n "$token_string" | openssl dgst -sha256 -hmac "$secret_key" | awk '{print $2}')
# Concatenate the token string and the signature.
signed_token="${token_string}~hmac=${hmac_signature}"
url_encode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
# Apply URL encoding to the concatenated string.
url_encoded_signed_token=$(url_encode "$signed_token")
echo "Signed HMAC token:"
echo "${url_encoded_signed_token}"
# Example output:
# ad_break_id%3Dpreroll~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D21775744923~pd%3D180000~pod_id%3D5~hmac%3D24E96382584C328087546B0E8454F26158564E8466FD2BE3D8A996B38445876C
前贴片广告的请求时间元数据
您可以使用以下选项验证直播活动的开播前广告设置:
如需检索前贴片广告决策结果,请向 ATM API 发出请求。
以下示例针对前贴片广告发出 ATM 请求:
curl "https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/pod.json?stream_id=SESSION_ID&ad_break_id=preroll&auth-token=your_signed_HMAC_token"
请求中贴片广告的播放时间元数据
如需检索中贴片广告的广告连播元数据,请按以下步骤操作:
- 解析直播清单,以查找包含每个中贴片广告插播时间点和时长的广告标记。
- 调用 ATM API 端点以请求精确的广告插播时间和插播广告时长。该 API 会返回一个 JSON 对象,其中包含广告连播的决策结果。
以下示例针对中贴片广告发出 ATM 请求:
curl "https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/pod.json?stream_id=SESSION_ID&ad_break_id=AD_BREAK_ID&pd=AD_BREAK_DURATION&auth-token=your_signed_HMAC_token"
如果成功,您会看到类似于以下 JSON 对象的输出:
{
"status": "final",
"ads": [
{
"duration_ms": 5046,
"variants": {
"devrel1428000": {
"segment_extension": "ts",
"segment_durations": {
"timescale": 1000,
"values": [
5045
]
}
},
"devrel1928000": {
"segment_extension": "ts",
"segment_durations": {
"timescale": 1000,
"values": [
5045
]
}
}
}
}
],
"slate": {
"duration_ms": 0,
"variants": {
"devrel1428000": {
"segment_extension": "ts",
"segment_durations": {
"timescale": 1000,
"values": [
5005,
...
5046
]
}
},
"devrel1928000": {
"segment_extension": "ts",
"segment_durations": {
"timescale": 1000,
"values": [
5005,
...
5046
]
}
}
}
}
}
将广告缝合到内容清单中
以下部分将引导您逐步修改直播清单并添加广告片段。
识别广告插播时间点片段并插入不连续性
在处理每个变体清单时,请在您的信息流中识别 EXT-X-CUE-IN
和 EXT-X-CUE-OUT
标记,它们分别表示广告插播的开始和结束。
将 EXT-X-CUE-IN
和 EXT-X-CUE-OUT
标记替换为 EXT-X-DISCONTINUITY
元素,以便客户端视频播放器在内容和广告之间切换。
以下示例清单替换了 EXT-X-CUE-IN
和 EXT-X-CUE-OUT
标记:
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000,
contentorigin.com/1.ts
#EXTINF:5.000,
contentorigin.com/2.ts
#EXT-X-CUE-OUT:15.000
#EXTINF:5.000,
contentorigin.com/3.ts
#EXTINF:5.000,
contentorigin.com/4.ts
#EXTINF:5.000,
contentorigin.com/5.ts
#EXT-X-CUE-IN
#EXTINF:5.000,
contentorigin.com/6.ts
#EXTINF:5.000,
contentorigin.com/7.mp4
#EXTINF:5.000,
contentorigin.com/8.mp4
以下示例展示了一个替换清单:
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000,
contentorigin.com/1.ts
#EXTINF:5.000,
contentorigin.com/2.ts
#EXTINF:5.000,
#EXT-X-DISCONTINUITY
{... Insert ad segments here ...}
#EXT-X-DISCONTINUITY
#EXTINF:5.000,
contentorigin.com/6.mp4
#EXTINF:5.000,
contentorigin.com/7.mp4
#EXTINF:5.000,
contentorigin.com/8.mp4
Google DAI 广告片段未加密。如果您的内容已加密,请在每个广告插播时段的第一个广告片段之前插入 EXT-X-KEY:METHOD=NONE
元素,以移除加密。在广告插播时间点结束时,通过插入适当的 EXT-X-KEY
重新添加加密。
跟踪即将到来的广告插播时段的开始时间、时长和索引。
构建广告细分网址
将 EXT-X-DISCONTINUITY
标记之间的内容段替换为每个广告段的网址。如需确定要插入多少个广告片段,请使用 ATM API 的 JSON 响应中提供的 ads.segment_durations.values
。
如需在检测到 EXT-X-CUE-IN
代码时提前结束广告插播时间,请将 d=
参数添加到最终广告片段的网址中。此参数会缩短片段,以避免影响客户端视频播放器的时间轴。
以下示例将预贴片广告片段网址组装到清单中。请注意,广告片段使用从 0 开始的索引:
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/preroll/ad/0/profile/ENCODING_PROFILE/0.ts?stream_id=SESSION_ID
以下示例将中贴片广告片段网址组装到清单中:
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/AD_BREAK_ID/ad/0/profile/ENCODING_PROFILE/0.ts?stream_id=SESSION_ID
以下示例将广告片段插入到清单中:
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.00,
contentorigin.com/1.ts
#EXTINF:5.00,
contentorigin.com/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.00,
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/AD_BREAK_ID/ad/0/profile/ENCODING_PROFILE/0.ts?stream_id=SESSION_ID
#EXTINF:5.00,
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/AD_BREAK_ID/ad/0/profile/ENCODING_PROFILE/1.ts?stream_id=SESSION_ID
#EXTINF:5.00,
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/AD_BREAK_ID/ad/0/profile/ENCODING_PROFILE/2.ts?stream_id=SESSION_ID
#EXT-X-DISCONTINUITY
#EXTINF:5.00,
contentorigin.com/6.mp4
#EXTINF:5.00,
contentorigin.com/7.mp4
#EXTINF:5.00,
contentorigin.com/8.mp4
构建补位广告片段
为了填补广告与内容之间的空白,请插入可选广告片段。
使用 ATM API 的 JSON 响应中的 slates.segment_durations.values
数组来确定每个广告插播片段的时长。根据需要循环播放片段时长序列,以填充整个广告插播时间。
以下示例组装了一个插播广告片段:
https://dai.google.com/linear/pods/v1/adv/network/NETWORK_CODE/custom_asset/CUSTOM_ASSET_KEY/ad_break_id/AD_BREAK_ID/slate/0/profile/ENCODING_PROFILE/0.ts?stream_id=SESSION_ID
示例中的 slate/0
表示平板电脑迭代次数。请参考客户端视频播放器的兼容性和缓存功能,以确定是应从 0
开始,并在每次循环播放平板时递增此数字,还是应在所有迭代中都将其保持为 0
。
管理返回内容
在插入广告插播时间点中的所有片段后,请选择以下方法之一来过渡回内容流:
方法 | 说明 | 对客户端视频播放器的影响 |
---|---|---|
填充平板电脑片段 | 插入板岩片段并循环播放板岩。填充时长并在每次 slate 迭代之间插入 EXT-X-DISCONTINUITY 元素。 |
无效果。 视频播放器会返回到内容,时间轴不会发生变化。 |
重新对齐单个平板电脑细分受众群 | 插入单个 Slate 片段。使用 d= 参数填充时长,直到内容开始。 |
无效果。 视频播放器会返回到内容,时间轴不会发生变化。 |
立即返回 | 插入内容片段。 | 视频播放器的时间轴已更改。 您的客户端视频播放器必须处理更改后的时间轴。 |
可选:安排广告插播时间
为了提高填充率,请发送广告插播提前通知 (EABN),其中包含广告连播时长、自定义定位参数和 SCTE-35 信号数据。如需了解详情,请参阅发送提前插播广告通知。