使用 REST API 集成“继续观看”功能

Engage SDK 提供了一个 REST API,可在 iOS 和 Roku TV 等非 Android 平台上提供一致的继续观看体验。借助该 API,开发者可以更新非 Android 平台上选择启用该功能的用户“继续观看”状态。

前提条件

  • 您必须先完成基于设备端 Engage SDK 的集成。这一关键步骤可在 Google 的用户 ID 与应用的 AccountProfile 之间建立必要的关联。
  • API 访问权限和身份验证:如需在 Google Cloud 项目中查看和启用该 API,您必须通过许可清单流程。所有 API 请求都需要进行身份验证。

获取访问权限

如需在 Google Cloud 控制台中查看和启用该 API,您的账号需要加入该计划。

  1. Google Workspace 客户 ID 应可用。如果无法使用,您可能需要设置 Google Workspace 以及您要用于调用 API 的任何 Google 账号。
  2. 使用与 Google Workspace 关联的电子邮件地址在 Google Cloud 控制台中设置账号。
  3. 创建新项目。
  4. 创建用于 API 身份验证的服务账号。创建服务账号后,您将拥有两个项目:
    • 服务账号 ID。
    • 包含服务账号密钥的 JSON 文件。请确保此文件的安全性。稍后,您需要使用此密钥向 API 验证客户端身份。
  5. Workspace 和关联的 Google 账号现在可以使用 REST API。 更改生效后,您会收到通知,告知您 API 是否已准备好供服务账号调用。
  6. 请按照这些步骤准备进行委托 API 调用。

发布接续集群

如需发布 Engage 数据,请使用以下语法向 publishContinuationCluster API 执行 POST 请求。

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/profiles/{profile_id}/publishContinuationCluster

其中:

  • package_name:媒体提供方软件包名称
  • accountId:用户账号在您系统中的唯一 ID。它必须与设备端路径中使用的 accountId 匹配。
  • profileId:用户在您系统中的账号内的个人资料的唯一 ID。它必须与设备端路径中使用的 profileId 一致。

没有个人资料的账号的网址为:

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/publishContinuationCluster

请求的载荷在 entities 字段中表示。entities 表示内容实体列表,可由以下一项或多项组成:MovieEntity、TVEpisodeEntity、LiveStreamingVideoEntity 或 VideoClipEntity。此字段是必填字段。

请求正文

字段

类型

必需

说明

实体

MediaEntity 对象列表

是

内容实体列表,最多 5 个。系统只会保留前五个,其余的都会被丢弃。允许使用空列表来表示用户已看完所有实体。

字段 entities 包含单个 movieEntity、tvEpisodeEntity、liveStreamingVideoEntity 和 videoClipEntity。

字段

类型

说明

movieEntity

MovieEntity

代表 ContinuationCluster 中影片的对象。

tvEpisodeEntity

TvEpisodeEntity

代表 ContinuationCluster 中的电视剧集的对象。

liveStreamingVideoEntity

LiveStreamingVideoEntity

ContinuationCluster 中表示直播视频的对象。

videoClipEntity

VideoClipEntity

代表 ContinuationCluster 中的视频片段的对象。

entities 数组中的每个对象都必须是可用的 MediaEntity 类型之一,即 MovieEntity、TvEpisodeEntity、LiveStreamingVideoEntity 或 VideoClipEntity,以及通用字段和类型专用字段。

以下代码段展示了 publishContinuationCluster API 的请求正文载荷。

{
  "entities": [
    {
      "movieEntity": {
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "name": "Movie1",
        "platform_specific_playback_uris": [
        {
          "uri": "https://www.example.com/movie_entity_uri_for_android",
          "platforms": [
            "PLATFORM_ANDROID_TV",
            "PLATFORM_ANDROID"
          ]
        },
        {
          "uri": "https://www.example.com/movie_entity_uri_for_iOS",
          "platforms": [
            "PLATFORM_IOS"
          ]
        }
        ],
        "poster_images": [
          {
            "url": "http://www.example.com/movie1_img1.png",
            "width": 1920,
            "height": 1080,
            "accessibility_text": "Movie 1 HD poster"
          },
          {
            "url": "http://www.example.com/movie1_imag2.png",
            "width": 640,
            "height": 360,
            "accessibility_text": "Movie 1 SD poster"
          }
        ],
        "last_engagement_time_millis": 864600000,
        "duration_millis": 5400000,
        "last_play_back_position_time_millis": 3241111
      }
    },
    {
      "tvEpisodeEntity": {
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "name": "TV SERIES EPISODE 1",
        "platform_specific_playback_uris": [
        {
          "uri": "https://www.example.com/episode_entity_uri_for_android_mobile",
          "platforms": [
            "PLATFORM_ANDROID"
          ]
        },
        {
          "uri": "https://www.example.com/episode_entity_uri_for_android_tv",
          "platforms": [
            "PLATFORM_ANDROID_TV"
          ]
        },
        {
          "uri": "https://www.example.com/episode_entity_uri_for_iOS",
          "platforms": [
            "PLATFORM_IOS"
          ]
        }
        ],
        "poster_images": [
          {
            "url": "http://www.example.com/episode1_img1.png",
            "width": 1920,
            "height": 1080,
            "accessibility_text": "Episode 1 HD poster"
          },
          {
            "url": "http://www.example.com/episode1_imag2.png",
            "width": 640,
            "height": 360,
            "accessibility_text": "Episode 1 SD poster"
          }
        ],
        "last_engagement_time_millis": 864600000,
        "duration_millis": 1800000,
        "last_play_back_position_time_millis": 2141231,
        "episode_display_number": "1",
        "season_number": "1",
        "show_title": "title"
      }
    },
    {
      "liveStreamingVideoEntity": {
        "name": "Live Sports Championship",
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "last_engagement_time_millis": 1780978284000,
        "last_play_back_position_time_millis": 1800000,
        "duration_millis": 7200000,
        "platform_specific_playback_uris": [
          {
            "uri": "https://www.example.com/live_streaming_entity_uri_for_android_tv",
            "platforms": ["PLATFORM_ANDROID_TV"]
          }
        ],
        "poster_images": [
          {
            "url": "http://www.example.com/live_stream_image1.png",
            "width": 1920,
            "height": 1080,
            "accessibility_text": "Live Sports Championship Cover Image"
          }
        ],
        "start_time_epoch_millis": 1780976484000,
        "broadcaster": "Global Sports Network",
        "broadcaster_icon": {
          "url": "https://www.example.com/gsports.jpg",
          "width": 512,
          "height": 512,
          "accessibility_text": "Global Sports Network Logo"
        }
      }
    },
    {
      "videoClipEntity": {
        "name": "How to Brew the Perfect Espresso",
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "last_engagement_time_millis": 1780978284000,
        "last_play_back_position_time_millis": 120000,
        "duration_millis": 600000,
        "platform_specific_playback_uris": [
          {
            "uri": "https://www.example.com/video_clip_entity_uri_for_android_tv",
            "platforms": ["PLATFORM_ANDROID_TV"]
          }
        ],
        "poster_images": [
          {
            "url": "http://www.example.com/video_clip_image1.png",
            "width": 1920,
            "height": 1080,
            "accessibility_text": "Espresso Tutorial Cover Image"
          }
        ],
        "created_time_epoch_millis": 1780900000000,
        "creator": "Coffee Enthusiast John",
        "creator_image": {
          "url": "https://www.example.com/image/thumb/creators/john_avatar.jpg",
          "width": 256,
          "height": 256,
          "accessibility_text": "John's Avatar"
        }
      }
    }
  ]
}

删除 Engage 数据

使用 clearCluster API 移除 Engage 数据。

如需删除延续集群数据,请使用以下语法向 clearCluster API 执行 POST 请求。

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/profiles/{profile_id}/clearCluster

其中:

  • package_name:媒体提供方软件包名称。
  • accountId:用户账号在您系统中的唯一 ID。它必须与设备端路径中使用的 accountId 匹配。
  • profileId:用户在您系统中的账号内的个人资料的唯一 ID。它必须与设备端路径中使用的 profileId 一致。

没有个人资料的账号的网址为:

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/clearCluster

clearCluster API 的载荷仅包含一个字段 reason,其中包含一个 DeleteReason,用于指定移除数据的原因。

{
  "reason": "DELETE_REASON_LOSS_OF_CONSENT"
}

测试

成功发布数据后,请使用用户测试账号验证预期内容是否显示在目标 Google 平台(例如 Google TV 以及 Android 和 iOS 版 Google TV 移动应用)上的“继续观看”行中。

在测试中,请留出几分钟的合理传播延迟时间,并遵守观看要求,例如观看电影的一部分或看完一集。如需了解详情,请参阅面向应用开发者的“接下来观看”指南。