广告插播时间点

概览

Web Receiver SDK 为广告插播时间点和随播广告提供原生支持 特定媒体流中的资源。它提供用于设置广告排名、广告来源 广告插播时间点及其关联的插播时间点剪辑的行为和行为。在本指南中, Break 是指包含一个或多个广告或导视广告且 每个广告或导视广告都称为 BreakClip。 这些广告插播时间点与正在加载或播放的媒体相关联。

广告类型

Web 接收器 SDK 支持客户端广告插播 (CSAI) 和服务器 拼接广告插播 (SSAI)。客户端拼接的广告可由 或从 VASTVMAP 模板文件中提取。 服务器拼接的广告必须在内容加载之前手动指定, 嵌入式广告,或在内容播放期间作为嵌入式展开式广告动态播放 广告。下面详细介绍了每种广告类型的实现。

客户手动拼接

手动客户端拼接的广告插播时间点是一种拼接的广告插播时间点 由客户端汇总在一起,并由应用使用 SDK API。此广告类型未嵌入到主要内容的视频流中。通过 BreakClip必须提供 contentId 该广告代码是一个指向广告内容的网址, contentType 来描述广告内容的格式,以及 title

Break必须包含 isEmbeddedexpanded 设置为默认值 false。通过 position 可设置为前贴片广告中贴片广告后贴片广告广告插播时间点(有关详情,请参阅 广告插播时间点部分)。在准备 Web Receiver SDK 会生成另一个播放器实例来加载 并播放广告内容。这些广告插播时间点需要 stitched timeline,且必须是 以静态的方式添加(有关详情,请参阅 广告插播部分)。以下示例显示了 人工拼接广告的实现:

// Create the BreakClip.
let clipClient = new cast.framework.messages.BreakClip('bc_client');
clipClient.title = 'The Ad Title to be displayed during playback';
clipClient.contentId = 'https://example.com/ad.m3u8';
clipClient.contentType = 'application/vnd.apple.mpegurl';

// Optional: Used when HLS ad container formats differ from the main content's.
clipClient.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;

// Create the Break using the BreakClip id above.
let breakPostrollClient = new cast.framework.messages.Break(
    'break_postroll_client', ['bc_client'], -1);
breakPostrollClient.isEmbedded = false; // Optional: default is false.
breakPostrollClient.expanded = false; // Optional: default is false.

VAST

Web Receiver SDK 支持添加 IAB 标准 VAST(视频广告投放 模板)广告。提供 XML 模板后,系统会对其进行解析,以生成 进入广告插播时间点时,后续客户端拼接的广告插播片段。

若要制作 VAST 广告,接收方应用必须创建一个 VastAdsRequest 并在 BreakClip 中指定 vastAdsRequest 属性。VastAdsRequest 对象必须具有 adsResponse( XML 模板本身的字符串表示形式)或 adTagUrl(网址 XML 模板的托管位置)属性所定义。如果指定了网址,则 SDK 将负责提取模板。封装 Break 遵循 客户拼接的广告惯例。这些广告可以与其他 人工拼接的广告,在同一广告插播时间点或单独的插播时间点 同一组内容以下示例展示了 VAST 的基本实现 广告:

// Create the VastAdsRequest.
let vastTemplate = new cast.framework.messages.VastAdsRequest();
vastTemplate.adTagUrl = 'https://example.com/ads.xml'

// Create the BreakClip.
let clipVast = new cast.framework.messages.BreakClip('bc_vast');
clipVast.vastAdsRequest = vastTemplate;

// Create the Break using the BreakClip id above.
let breakPostrollVast = new cast.framework.messages.Break(
    'break_postroll_vast', ['bc_vast'], -1);
breakPostrollVast.isEmbedded = false; // Optional: default is false.
breakPostrollVast.expanded = false; // Optional: default is false.

当输入包含 VAST BreakClipBreak 时,Web 接收器 SDK 可以选择提取并解析该模板。解析时,SDK 将生成新的 BreakClip 并使用从中提取的值进行填充 例如 contentIdcontentTypetitleduration whenSkippableclickThroughUrl。生成的广告插播时间点剪辑的 id 为 设置为 GENERATED:N,其中 N 是一个整数,每个新变量以 1 递增 已创建 VAST 广告插播时间点,从 0 开始。然后将生成的广告添加到 BreakClip 数组。当前 Break 中每个 VAST 广告插播时间点的 id 均为 然后替换为生成的相应广告插播时间点片段的 id。摘要 下面展示了 MEDIA_STATUS 与进入此类广告插播时间点之前和之后的广告相关的信息。

VAST 广告的插播时间点之前显示的BreakBreakClip信息。

"breaks": [
  {
    "id": "break_postroll_vast",
    "breakClipIds": [
      "bc_vast"
    ],
    "position": 0,
    "isWatched": false
  }
],
"breakClips": [
  {
    "id": "bc_vast"
  }
]

VAST 广告进入休息时间后,显示的BreakBreakClip信息。

"breaks": [
  {
    "id": "break_postroll_vast",
    "breakClipIds": [
      "GENERATED:0"
    ],
    "position": 0,
    "isWatched": true
  }
],
"breakClips": [
  {
    "id": "bc_vast"
  },
  {
    "id": "GENERATED:0",
    "contentId": "https://example.com/break-clip-1.mpd",
    "contentType": "application/dash+xml",
    "title": "Ad Title Extracted from Template",
    "duration": 10,
    "whenSkippable": 5,
    "clickThroughUrl": "https://example.com/ad-target"
  }
]

VMAP 响应

网络接收器 SDK 支持 IAB VMAP(视频多广告播放列表) 标准。如果提供了 VMAP,Web 接收器 SDK 将解析 VMAP 并为任何 <AdBreak> 生成客户端拼接Break 对象 响应中的条目。它还会生成相应的BreakClips 为 VMAP 中提供的每个 <AdSource> 条目创建一个 vastAdsRequest 对象。接收者 启用 VMAP 以在内容中插入广告,应用必须创建一个 VastAdsRequest 对象并将其分配给 vmapAdsRequest 属性 MediaInformationLoadRequestData。 这些广告必须以静态方式插入(有关详情,请参阅 广告插播部分)。以下代码段概述了 创建 VMAP 请求

// Create the VastAdsRequest.
let vastTemplate = new cast.framework.messages.VastAdsRequest();
vastTemplate.adTagUrl = 'https://example.com/vmap.xml'

// Add it to the MediaInformation of the LoadRequest.
loadRequestData.media.vmapAdsRequest = vastTemplate;

嵌入式播放器

嵌入式广告插播时间点是一种在服务器端拼接的广告插播时间点 主内容的视频流中Break 的持续时间会减去 在计算媒体时间时,根据主要内容的时长计算得出。

BreakClip必须提供 duration 广告内容的特点 titleBreak必须包含 isEmbedded 设置为 trueexpanded 设为 false。通过 position 可设为前贴片广告中贴片广告插播时间点。后贴片广告插播时间点 支持精确的 position 值。有关详情,请参阅 断点定位部分。当广告被触发 则 Web Receiver SDK 会随着广告片段继续播放视频流 资源。此广告类型没有其他加载机制。 当进度条指针位于 。这些广告插播时间点需要 embedded timeline,并且必须添加 静态(有关详情,请参阅广告插播部分)。通过 下面的示例展示了 embedded 广告的基本植入方式。

// Create the BreakClip.
let clipEmbedded = new cast.framework.messages.BreakClip('bc_embedded');
clipEmbedded.title = 'The Ad Title to be displayed during playback';
clipEmbedded.duration = 15;

// Create the Break using the BreakClip id above.
let breakPrerollEmbedded = new cast.framework.messages.Break(
    'break_preroll_embedded', ['bc_embedded'], 0);
breakPrerollEmbedded.isEmbedded = true;
breakPrerollEmbedded.expanded = false; // Optional: default is false.

嵌入式展开

嵌入式展开式广告插播时间点是一种通过服务器拼接的广告插播时间点 主内容的视频流中包含 Break 的时长 。

BreakClip必须提供 duration 广告内容的特点 titleBreak必须包含 isEmbedded 设置为 trueexpanded 设置为 true。通过 position 可设为前贴片广告中贴片广告插播时间点。后贴片广告插播时间点 支持 position 正值。有关详情,请参阅 断点定位部分。当广告被触发 则 Web Receiver SDK 会随着广告片段继续播放视频流 资源。此广告类型没有其他加载机制。 当进度条指针位于 。这些广告插播时间点需要 embedded timeline,可添加 静态动态(有关详情,请参阅 广告插播部分)。以下示例显示了 embedded expanded 广告的植入方式:

// Create the BreakClip.
let clipEmbeddedExpanded =
    new cast.framework.messages.BreakClip('bc_embedded_expanded');
clipEmbeddedExpanded.title = 'The Ad Title to be displayed during playback';
clipEmbeddedExpanded.duration = 15;

// Create the Break using the BreakClip id above.
let breakPrerollEmbeddedExpanded = new cast.framework.messages.Break(
    'break_preroll_embedded_expanded', ['bc_embedded_expanded'], 0);
breakPrerollEmbeddedExpanded.isEmbedded = true;
breakPrerollEmbeddedExpanded.expanded = true;

播放器时间轴类型

创建播放器实例时,Web Receiver SDK 会选择一个时间轴类型, 支持在内容播放期间播放广告。每个时间轴都允许 要添加的广告插播时间点类型时间轴类型由 广告类型显示在 MediaInformationLoadRequestData。 如果存在嵌入式广告插播时间点,则会选择 embedded 时间轴。如果 存在客户端拼接的广告插播时间点时,系统会选择 stitched 时间轴。 如果没有广告,SDK 会默认使用 embedded 时间轴。时间轴一旦选定,便无法针对当前进行更改。 媒体项。下表提供了每个时间轴的详细说明。

时间轴类型 说明
嵌入式时间轴 表示支持广告的媒体时间 内嵌在主内容中的 (嵌入式嵌入式展开式广告插播时间点)。 如果存在未展开的广告插播时间点,则时长 该费用是从 内容。另一方面,如果展开后的广告 广告时段即被视为 部分内容。
拼接时间轴 表示支持广告的媒体时间 从外部媒体文件获取 (手动客户端拼接VASTVMAP 广告插播时间点。添加后,广告插播时长为 未包含在主要内容时长内。

下面的图 1 到 3 显示了一些包含不同广告类型及其广告类型的内容 相应的时间轴值此内容配置了前贴片广告插播时间点 包含两个广告插播时间点,以及包含中贴片广告后贴片广告的广告插播时间点 一个广告插播时间点自内容开始播放以来的挂钟时间。 主要内容的媒体时间,以及插播时间点的当前时间 每个数字下方对齐播放的广告插播时间点片段

<ph type="x-smartling-placeholder">
</ph> 客户拼接的广告的时间轴 <ph type="x-smartling-placeholder">
</ph> 图 1:表示某些内容的时间轴及其 3 个客户端拼接的广告插播时间点。


<ph type="x-smartling-placeholder">
</ph> 服务器拼接的嵌入式广告的时间轴 <ph type="x-smartling-placeholder">
</ph> 图 2:表示某些内容及其 3 个服务器拼接的嵌入式广告插播时间点的时间轴。


<ph type="x-smartling-placeholder">
</ph> 服务器拼接的嵌入式展开式广告的时间轴 <ph type="x-smartling-placeholder">
</ph> 图 3:表示某些内容及其 3 个由服务器拼接的嵌入式展开式广告插播时间点的时间轴。

断点定位

借助 Web Receiver SDK,开发者可以指定广告插播时间点的位置 方法是设置 position 属性。Break此值对应于主要内容的媒体时间 可用于创建 pre-rollmid-rollpost-roll 广告插播时间点。 这些变量的定义如下:

广告插播位置 说明
前贴片广告 在主要内容之前播放的广告插播时间点。这是 通过将 breakPosition 设置为 0 来表示
中贴片广告 在内容播放过程中播放的广告插播时间点。它用 将 breakPosition 设为广告插播时间点的时间 开头大于主要内容的开头,并且 广告插播时间点的结束时间早于主要内容的结束时间 。
后贴片广告 在主要内容之后播放的广告插播时间点。这是 通过将 breakPosition 设置为 -1 来表示 拼接的时间轴。对于嵌入式 breakPosition时间轴 应设置为主要内容的时长减去 插播广告的时长不支持直播内容。

互操作性矩阵

表 1 概述了各种广告类型和 与广告相关功能的兼容性。

<ph type="x-smartling-placeholder">
</ph> 表 1:Google Ads 互操作性矩阵
功能支持 客户手动拼接的广告 VAST VMAP 响应 嵌入式广告 嵌入式展开式广告
兼容 VAST 客户手动拼接 不适用 嵌入式展开 嵌入式播放器
时间轴 已缝制 已缝制 已缝制 嵌入式播放器 嵌入式播放器
广告插播 静态 静态 静态 静态 静态、动态
广告移除
前贴片广告
中贴片广告
后贴片广告
广告跳过
中断搜寻拦截器
中断片段加载拦截器

事件

当发生按键中断事件时,投放 SDK 将分派以下类型的事件: BreaksEvent。 接收器应用可以使用 PlayerManager 来订阅这些消息 addEventListener API。

这些事件可用于分析和广告播放跟踪。当 VMAP (视频多广告播放列表)和 VAST(视频广告投放模板)广告 响应中提供的所有标准跟踪事件都会自动 所有事件

表 2 中列出了这些事件类型,并详细介绍了 。

<ph type="x-smartling-placeholder">
</ph> 中断事件生命周期
图 4:广告插播事件生命周期。
<ph type="x-smartling-placeholder">
</ph> 表 2:广告插播事件及其说明。
中断事件 说明
BREAK_STARTED 在主要内容的当前媒体时间等于 未观看广告插播时间点的 position
BREAK_CLIP_LOADING 仅在拼接的时间轴插播时间点开始加载时触发。
BREAK_CLIP_STARTED 在广告插播时间点开始播放时触发。
BREAK_CLIP_ENDED 在广告插播片段结束时触发。通过 <ph type="x-smartling-placeholder"></ph> endedReason 将填充到以下值中:
  • 拼接的时间轴插播时间点剪辑完整播放。
  • 拼接的时间轴插播时间点剪辑过渡到另一个广告插播剪辑。
  • 系统会跳过任何广告插播时间点。
  • 最后一个插播时间点剪辑在一个后贴片插播插播时间点完全播放。
  • 出现错误。
BREAK_ENDED 在广告插播时间点的最后一个片段结束时触发。

插入广告

借助 Cast SDK,应用可在不同时刻插入和移除广告 。广告插播有静态动态两种类型。 静态广告插播要求在 LoadRequestData 然后再创建播放器动态广告插播利用 BreakManager addBreak 用于在已加载内容中插入中断的 API。每种插入类型 方法与某些广告类型兼容。兼容性 互操作性矩阵一文。

静态广告插播

静态广告插播的特点是先添加相关的广告元数据, 以及创建玩家所需的功能此信息在 MediaInformationLoadRequestData。例如,您可以在已连接的发件人的 原始加载请求,也可以由网络接收器应用插入 会拦截 LOAD 请求。将 LoadRequestData 返回给 Web Receiver SDK 进行处理,则创建播放器。详情请访问: 加载媒体。示例 展示了在 LOAD 请求中添加的手动客户端拼接的广告 拦截器。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {

  // Create the BreakClip.
  let clipClient = new cast.framework.messages.BreakClip('bc_client');
  clipClient.title = 'The Ad Title to be displayed during playback';
  clipClient.contentId = 'https://example.com/ad.mp4';
  clipClient.contentType = 'video/mp4';

  // Create the Break using the BreakClip id above.
  let breakPostrollClient = new cast.framework.messages.Break(
      'break_postroll_client', ['bc_client'], -1);

  // Set the ad information in the load request data.
  let media = loadRequestData.media;
  media.breakClips = [clipClient];
  media.breaks = [breakPostrollClient];

  return loadRequestData;
});

动态广告插播

动态广告插播是指在内容播放期间设置广告插播时间点 。方法是获取 BreakManager 的实例并调用 该 addBreak API。此方法至少需要两个参数: 嵌入式展开式 Break和 一个数组 BreakClip。 包含了可选的第三个属性,用于将更改强制发送到 设置为 true 时,通过 MediaStatus 广播已连接的发送者。时间 添加广告插播时间点和广告插播时间点,对应的 ID 必须是唯一的。这些广告 只能在创建播放器后添加。Web Receiver SDK 触发 该 PLAYER_LOADING 事件。请参见下面的示例,了解在 一个事件处理脚本,用于响应流的 ID3 元数据的变化;以及 会创建 BreakBreakClip 对象,以将其插入时间轴。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

playerManager.addEventListener(cast.framework.events.EventType.ID3, (event) => {

  // Create the BreakClip.
  let clipEmbeddedExpanded = parseBreakClipFromData(event.segmentData);
  let breakEmbeddedExpanded = parseExpandedBreakFromData(event.segmentData);

  // Add the break and break clip.
  breakManager.addBreak(breakEmbeddedExpanded, [clipEmbeddedExpanded]);
});

动态广告移除

要移除动态插播时间点,应用应调用 removeBreakById 。该函数会获取要暂停的插播时间点的字符串标识符。 从时间轴中移除指定的 breakId 必须指向嵌入式 展开的广告插播时间点。如果检测到任何其他类型的广告插播时间点 仍然保留在时间轴上请参阅下面的示例,了解如何移除中断。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

breakManager.removeBreakById('break_midroll_embedded_expanded');

中断行为

SDK 定义了播放器进入和离开插播时间点时的默认行为 并使用提供的一些 API 进一步自定义 在 BreakManager

默认广告插播行为

通过常规播放或搜寻 Break 进入 Break 时, SDK 将通过检查 该 isWatched 属性。创建后,此属性的广告插播时间点的默认值为 false。如果 该属性为true,因此当进入到主视图时,将不会播放插播时间点 内容将继续播放。如果属性为 false,则插播时间点将为 。

在跳转过去的广告插播时间点时,默认实现会获取所有 Breakposition 介于跳转操作 seekFromseekTo 值。在此插播列表中,SDK 将播放 positionBreak。 最接近 seekTo 值,并且其 isWatched 属性设置为 false。然后,该广告插播时间点的 isWatched 属性设置为 true,并且 播放器将开始播放其广告插播片段。观看插播时间点后 主内容将从 seekTo 位置继续播放。如果没有 存在广告插播时间点,则不播放任何插播时间点,主要内容会继续播放 在 seekTo 位置播放。

在广告插播时间点播放期间,SDK 会将所有相关更新广播到已连接的 发件人应用 MediaStatus。 这些应用将使用广播,通过读取 该 breakStatus 属性。此属性仅在广告插播时间点播放期间定义。

接收器应用还可以直接查询与 进度条指针相对于 BreakClip 当前时间的位置 通过调用 PlayerManager 显示 getBreakClipCurrentTimeSec。 同样,应用也可通过以下方式查询当前 BreakClip 的时长: 呼叫 getBreakClipDurationSec

自定义广告插播行为

默认行为 您可以使用 setBreakClipLoadInterceptorsetBreakSeekInterceptor BreakManager 中提供的方法。

中断跳转拦截器

暂停跳转拦截器允许应用控制跳转行为 。请求查找操作时会触发该函数 在一个或多个插播时间点向前或向后跳转。调用时, BreakSeekData 会作为参数传递给回调函数。BreakSeekData 对象 包含一系列 Break 对象的 position 属性设置为当前值之间的一个数字 进度条指针时间定义为 seekFrom 以及跳转目标时间 seekTo

此拦截器允许相应广告插播时间点中的 Break 对象 。实现时,中断跳转拦截器必须指定哪个广告 通过返回选择性修改的 BreakSeekData 对象来暂停播放。通过 播放器会继续播放返回值中包含的所有插播时间点。如果某个值 为 null 或者从中断搜寻拦截器未返回任何内容,则中断 跳过。

请参阅下面的示例,了解拦截器的简单实现, 覆盖默认行为,以便使用 但已观看的广告插播时间点除外。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

breakManager.setBreakSeekInterceptor((breakSeekData) => {

  // Filter the breaks array by removing watched breaks.
  const unwatchedBreaks =
      breakSeekData.breaks.filter(adBreak => !adBreak.isWatched);
  breakSeekData.breaks = unwatchedBreaks;

  return breakSeekData;
});

中断片段加载拦截器

使用广告插播时间点加载拦截器,可以修改 BreakClip 对象 。

只针对以下情况调用广告插播片段加载拦截器: 拼接的时间轴中断 并且可以使用 setBreakClipLoadInterceptor。 在进入 Break 之前,系统会针对每个单独的对象调用一次此拦截器 该插播时间点中定义的BreakClip。SDK 会将原始 BreakClip 对象作为回调函数的参数。然后,应用可以修改 此 BreakClip 并将其返回,以便 SDK 可以提取并显示插播时间点 更新后的配置。如果返回 null 或未返回任何内容,则 视频剪辑会跳过。

请参见下面的示例,了解如何将广告插播时间点的 contentUrl 修改为 实用函数调用 getUrlFromClipId,其中 BreakClipid 映射到网址。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

breakManager.setBreakClipLoadInterceptor(
    (breakClip, breakClipLoadInterceptorContext) => {

  // Obtains the URL of a break clip id from a function call.
  breakClip.contentUrl = getUrlFromClipId(breakClip.id);

  return breakClip;
});

跳过广告

Web Receiver SDK 提供了用于跳过广告插播时间点和单个广告插播时间点的 API 。通过该 SDK,用户还可以选择跳过广告插播时间点剪辑, 与发送方应用或智能显示屏设备进行互动。

用户可跳过的广告插播时间点剪辑

将广告插播时间点设置为可跳过后,用户可以与已连接的发送者互动 应用和智能显示屏设备,则可以选择跳过 播放中断片段。将 whenSkippable 属性设置为非负秒数,则启用 BreakClip 对象。广告播放完毕后,播放器会将广告插播时间点剪辑 。将此值设置为 0 让用户能够立即跳过插播时间点剪辑。

// Create the BreakClip.
let clip = new cast.framework.messages.BreakClip('bc');
clip.title = 'The Ad Title to be displayed during playback';
clip.whenSkippable = 10; // Users can skip the clip after 10 seconds of playback.

此信息可在发送方的原始加载请求或 接收器应用。用户跳过时,拼接时间轴的广告插播时间点中的插播时间点剪辑 会停止播放当前的插播时间点剪辑。播放器会加载下一个 中断剪辑(如果有)或加载主要内容。跳过之后,广告插播时间点会是 嵌入式时间轴广告插播时间点会寻找到广告插播时间点的结尾处,并且 。

以编程方式跳过广告

系统还可以自动跳过广告,无需与用户互动。

要跳过整个暂停播放,应用应将 isWatched 属性更改为 trueBreak此操作可在加载期间随时执行 序列或内容播放。isWatched 属性由 播放器。position在 之后,玩家将决定是否要进入插播时间点。 请参阅下面的示例,它会循环遍历所有断点并修改 值。

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

playerManager.addEventListener(cast.framework.events.EventType.PLAYER_LOADING,
    (event) => {

  // Obtain the breaks and iterate through each item to skip all ad breaks.
  let breaks = breakManager.getBreaks();
  breaks.forEach((brk) => {
    brk.isWatched = true;
  });
});

要以编程方式跳过特定的广告插播片段中断片段加载拦截器。修改者 返回 null 或未在回调函数中返回值,剪辑中的 则会跳过该广告插播时间点

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const breakManager = playerManager.getBreakManager();

breakManager.setBreakClipLoadInterceptor(
      (breakClip, breakClipLoadInterceptorContext) => {
  return null;
});