as

Settings
Sign out
Notifications
Alexa
亚马逊应用商店
AWS
文档
Support
Contact Us
My Cases
新手入门
设计和开发
应用发布
参考
支持

内容启动器集成指南

内容启动器集成指南

本文档介绍如何将内容启动器集成到您的应用中。媒体应用通常需要与以下三个关键API集成:

  1. 内容启动器API
  2. Vega媒体控制API
  3. 账户登录API

内容启动器API和Vega媒体控制API在交互式组件中实现,该组件是处理Vega媒体查询的主要组件。账户登录API以服务组件的形式实现。

步骤1: 更新应用的清单文件

在应用的manifest.toml文件中,添加对内容启动器的支持。此示例假设您的程序包ID为com.amazondeveloper.keplervideoapp。将此程序包ID替换为您的应用的程序包ID。

您的应用必须经过正确配置之后才能与Vega媒体内容启动器API交互。

已复制到剪贴板。

schema-version = 1

[package]
title = "<应用标题>"
id = "com.amazondeveloper.media.sample"

[components]
[[components.interactive]]
id = "com.amazondeveloper.media.sample.main"
runtime-module = "/com.amazon.kepler.keplerscript.runtime.loader_2@IKeplerScript_2_0"
launch-type = "singleton"
# 类别“com.amazon.category.kepler.media”仅对主要组件是必需的,该组件在
# 清单的 [[extras]] 部分中使用“component-id”值进行标识。
categories = ["com.amazon.category.main", "com.amazon.category.kepler.media"]

[processes]
[[processes.group]]
component-ids = ["com.amazondeveloper.media.sample.main"]

[offers]
[[offers.interaction]]
id = "com.amazondeveloper.media.sample.main"

[[message]]
uri = "pkg://com.amazondeveloper.media.sample.main"
# 匹配 [[offers.interaction]] 中使用的权限。如果未添加权限,则使用“*”。
sender-privileges = ["*"]
receiver-privileges = ["self"]

[[offers.module]]
id = "/com.amazondeveloper.media.sample.module@ISomeUri1" 
includes-messages = ["pkg://com.amazondeveloper.media.sample.main"]

[[extras]]
key = "interface.provider"

component-id = "com.amazondeveloper.media.sample.main"

[extras.value.application]
[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.IContentLauncherServer"

# 只有当 [[extras]] 部分中指定的“component-id”不同于您在此处提供的“component-id”时,
# override_command_component字段才是必需的。这样一来,您就可以不使用extras中最初定义的组件,
# 而使用其他组件来执行命令,从而能够灵活进行
# 配置设置。

# 例如,如果您在内容启动器界面之外还使用账户登录界面,
# 您需要使用以下行覆盖账户登录状态属性
# 才能被定向到服务组件:
# override_command_component = { Status = "com.amazondeveloper.media.sample.interface.provider" }
attribute_options = ["partner-id"]
static-values = { partner-id = "<您的合作伙伴ID>" }

[needs]

[[needs.module]]
id = "/com.amazon.kepler.media@IContentLauncher1"

步骤2: 在应用中包含必要的程序包依赖项

package.json文件中,添加@amazon-devices/kepler-media-content-launcher程序包作为依赖项。

已复制到剪贴板。

"dependencies": {
    "@amazon-devices/kepler-media-content-launcher": "^2.0.0",
},

步骤3: 实现内容启动器API

  1. 定义内容启动器处理程序。

    实例化一个新的ContentLauncherServerComponent。开发一个用于封装回调函数的处理程序对象。

    已复制到剪贴板。

    import {
    ILauncherResponse,
    IContentLauncherHandler,
    ContentLauncherStatusType,
    ContentLauncherServerComponent,
    IContentSearch,
    ILaunchContentOptionalFields,
    } from '@amazon-devices/kepler-media-content-launcher';
    
    ...
    // 创建一个ContentLauncherServerComponent的实例
    let factory = new ContentLauncherServerComponent();
    
    // 创建一个在请求启动内容时调用的处理程序。
    const contentLauncherHandler: IContentLauncherHandler = {
       async handleLaunchContent(
          contentSearch: IContentSearch,
          autoPlay: Boolean,
          _optionalFields: ILaunchContentOptionalFields,
       ): Promise<ILauncherResponse> {
          console.log('Content_Launcher_Sample: handleLaunchContent invoked');
    
          // 在此处迭代以获取数据,
          // 用于处理启动请求的业务逻辑
    
          let launcherResponse = factory
                .makeLauncherResponseBuilder()
                .contentLauncherStatus(ContentLauncherStatusType.SUCCESS)
                .build();
          return Promise.resolve(launcherResponse);
       },
    };
    

    处理程序应处理请求,向ILauncherResponse返回Promise,然后使用ContentLauncherServerComponent的实例进行创建。对于LauncherResponse,如果您的应用成功处理了请求,请将contentLauncherStatus状态设置为ContentLauncherStatusType.SUCCESS。如果您的应用由于授权问题而无法处理请求,请将状态设置为ContentLauncherStatusType.AUTH_FAILED。对于其他所有情况,请将状态设置为ContentLauncherStatusType.URL_NOT_AVAILABLE

  2. 在交互式应用中实现Vega媒体内容启动器。

    要在交互式应用中实现Vega媒体内容启动器,请先获取IContentLauncherServerAsync的单例实例。为此,您可以针对ContentLauncherServerComponent实例使用getOrMakeServer方法。接下来,创建一个可实现IContentLauncherHandler接口的处理程序对象,以处理内容启动请求。通过为IContentLauncherServerAsync实例调用setHandlerForComponent方法,将该处理程序与正确的组件相关联。传递处理程序和相应的IComponentInstance。在交互式应用中,您可以使用useComponentInstance方法获取IComponentInstance。对于React Native应用,请在useEffect挂钩中设置处理程序。在组件完成挂载和IComponentInstance变得可用之后,处理程序便应该立即对内容启动器进行初始化。这会将内容启动器功能与组件的生命周期紧密集成。它还允许您的应用从初始化之时起便可高效地处理Vega内容启动器命令。此设置对于含有多个组件的应用非常重要,因为它可以确保每个组件都使用IComponentInstance,从而防止回调路由发生混淆。

    已复制到剪贴板。

    import { useComponentInstance , IComponentInstance } from '@amazon-devices/react-native-kepler';
    
    export const App = () => {
    
    const componentInstance: IComponentInstance = useComponentInstance();
    
    useEffect(() => {
       const factory = new ContentLauncherServerComponent();
    
       const contentLauncherHandler: IContentLauncherHandler = {
    
          async handleLaunchContent(
          contentSearch: IContentSearch,
          autoPlay: boolean,
          _optionalFields: ILaunchContentOptionalFields,
          ): Promise<ILauncherResponse> {
          console.log('Content_Launcher_Sample:已引用handleLaunchContent。');
    
          // 在此处迭代以
          // 获取数据..
    
          const launcherResponse = factory
             .makeLauncherResponseBuilder()
             .contentLauncherStatus(ContentLauncherStatusType.SUCCESS)
             .build();
    
          return Promise.resolve(launcherResponse);
          },
       };
    
       const contentLauncherServer = factory.getOrMakeServer();
       contentLauncherServer.setHandlerForComponent(contentLauncherHandler,componentInstance);
    
       return () => {};
    }, []);
    
    // 在此处为您的提供方应用创建用户界面。
    };
    

实现详情

IContentLauncherHandler处理程序采用三个参数来定义要播放的内容或显示搜索结果。

  • 指向实现IContentSearch接口的对象的指针。
  • 名为autoPlay的布尔值。
  • 其他可选字段,通过指向实现ILaunchContentOptionalFields接口的对象的指针进行传递。

使用autoPlay来确定要执行的操作。

如果autoPlay为true,则它是一个快速播放请求。请求的内容应直接开始播放,无需用户进一步交互。如果autoPlay为false,则显示搜索结果。然后,用户便可查看可用选项并从中进行选择。

检索contentSearch:IContentSearch值。

此参数包括用户通过内容启动器和Alexa发送的内容。以下架构适用于存储在contentSearch:IContentSearch中的值。

已复制到剪贴板。

1    "parameterList": [{
1.1     "type": "<实体类型>",
1.2     "value": "<实体值>",
1.3     "externalIdList": [{
1.3.1          "name": "<externalId名称>",
1.3.2          "value": "<externalId值>"
        }]
      }]

1 ParameterList有一个或多个条目。contentSearch.getParameterList().length用于检索完整列表。

1.1 <实体类型> 表示参数中列出的实体的类型。有关所有支持的实体类型的列表,请参阅枚举ContentSearchParamType(仅提供英文版)。例如,如果是电影或电视节目,则“type”“ContentSearchParamType::VIDEO”。调用getParamType() 来获取类型。

1.2 <实体值> 表示类型中提及的实体的值。调用getValue() 来检索此字段。

1.3 parameterList有一个或多个外部ID。使用getExternalIdList().length来获取列表的大小。getExternalIdList() 将提供externalIdList的完整列表。

1.3.1 getName() 通常会检索 <externalId名称>。如果externalId名称是amzn_id,请查找其值。

1.3.2 <externalId值> 表示externalId的值。要检索该值,请使用getValue()getValue() 包含目录集成中使用的 <ID> 或 <launchId> 值,以便您知道用户想要观看哪些内容。

示例: 提取和搜索请求的搜索参数

以下代码示例演示了如何提取和搜索请求的搜索参数。这种方法将各种信息整合到一个您可以使用handleLaunchContent方法加以修改和使用的字符串中。

此示例使用以下Alexa表述启动一个剧集:“watch The SeaShow: The Real story, season two, episode five in Streamz.”(在Streamz中观看The SeaShow: The Real story第2季第5集)。

已复制到剪贴板。

// 用于获取数据的迭代器。
let searchParameters = contentSearch.getParameterList();
if (searchParameters.length > 0) {
   for (var j = 0; j < searchParameters.length; j++) {
      let paramType = searchParameters[j].getParamType();
      let searchString = searchParameters[j].getValue();

      let additionalInfoList = searchParameters[j].getExternalIdList();
      for (var i = 0; i < additionalInfoList.length; i++) {
         let searchName = additionalInfoList[i].getName();
         let entityID = additionalInfoList[i].getValue();

         if (searchName == 'amzn_id') {
         // 使用此实体ID从您的目录中获取精确内容。

         } else {
            // ex: 
            // entityID= "ENTITY_ID" :
            // searchName = "amzn1.p11cat.merged-video.087c9371-6bb7-5edb-bcef-f8717fde0a8a"
            //
         }
      }
   }
   if (autoPlay) {
      console.log(`Content_Launcher_Sample: 快速播放`);

      // 使用上面检索到的数据在此处处理播放逻辑。
   } else {
      console.log(`Content_Launcher_Sample: 应用内搜索`);

      // 使用上面检索到的数据在此处处理搜索逻辑。
   }
} else {
   console.log('Content_Launcher_Sample: 获取搜索字符串时出错');
}
// 用于获取数据的迭代器。

内容启动器请求示例

下面的示例解释了一些关键内容启动器用例的contentSearch参数值。列出了所有支持的用例。将针对每个用例调用内容启动器并启动应用。

以下streamz_us的示例目录包括电影Seabound和电视节目The SeaShow: The Real Story的示例条目。

已复制到剪贴板。

...
<Movie>
  <ID>1700000725</ID>
  <Title locale="en-US">Seabound</Title>
  <Offers>
    <SubscriptionOffer>
      <LaunchDetails>
        <Quality>超高清</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>tv.streamz/movie/46720001</LaunchId>
      </LaunchDetails>
    </SubscriptionOffer>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>标清</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>tv.streamz/movie/467200002</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
</Movie>

<TvShow>
  <ID>1700000123</ID>
  <Title locale="en-US">The SeaShow: The Real story</Title>
  <Offers>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>高清</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>459800033</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
</TvShow>

<TvSeason>
  <ID>1700000234</ID>
  <Title locale="en-US">第1季</Title>
    <Offers>
     <FreeOffer>
       <Regions>
         <Territories>US</Territories>
       </Regions>
       <LaunchDetails>
         <Quality>高清</Quality>
         <Subtitle>en-US</Subtitle>
         <LaunchId>453200012</LaunchId>
        </LaunchDetails>
     </FreeOffer>
   </Offers>
   <ShowID>1700000123</ShowID>
   <SeasonInShow>2</SeasonInShow>
</TvSeason>

<TvEpisode>
  <ID>1700000825</ID>
  <Title locale="en-US">The Seashow.Story Starts</Title>
  <Offers>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>高清</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>453100008</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
  <ShowID>1700000123</ShowID>
  <SeasonID>1700000234</SeasonID>
  <EpisodeInSeason>5</EpisodeInSeason>
</TvEpisode>
...

通过遥控器启动内容

使用遥控器在Vega TV主页屏幕上启动电影Seabound

已复制到剪贴板。

"parameterList": [
  {                                           // 参数0
      "type": 13,                             // ContentSearchParamType::VIDEO,
      "value": ,                              // 将不会填充内容标题
      "externalIdList": [{
          "name": "catalogContentId",          // 将被弃用。 忽略此项
          "value": "tv.catalog/movie/46720000" // 目录中的ID或LaunchId
      }, 
      {
          "name": "amzn_id",          
          "value": "tv.catalog/movie/46720000" // 目录中的ID或LaunchId
      }
     ]
  }
]

应用应对LaunchId使用tv.streamz/movie/46720000来识别电影,然后直接播放电影。

用语音快速播放

通过语音播放电影Seabound。使用表述“Alexa, Play Seabound”(Alexa,播放Seabound)。

这里的autoPlay将为truecontentSearch: IContentSearch的值将如以下示例所示。应用将启动,它应该使用ID 1700000725直接播放内容。

已复制到剪贴板。

[
    {                             // 参数0
        "type": 13,               // ContentSearchParamType::VIDEO
        "value": "Seabound",      // 搜索字符串
        "externalIdList": [{
            "name": "streamz_us"   // 您的目录ID。 将被弃用。 忽略此项
            "value": "1700000725" // 目录中的ID
        },
        { 
            "name": "amzn_id"  
            "value": "1700000725" // 目录中的ID
        }
      ]
    }
]

用语音播放特定剧集

下面的目录示例代表电视节目SeaShow: The Real story、该电视节目的季以及剧集。通过使用Alexa表述“Alexa, Play Season 2 Episode 5 from The SeaShow: The Real story”(Alexa,播放The SeaShow: The Real story的第2季第5集),将调用应用来播放特定剧集。

这里的autoPlay将为truecontentSearch将只有节目的ID,没有剧集ID。应用必须使用ID 1700000123ContentSearchParamType::SEASON以及ContentSearchParamType::EPISODE值来识别确切的剧集。

已复制到剪贴板。

[
  {                // 参数0
    "type": 13,    // ContentSearchParamType::VIDEO
    "value": "Season Two Episode Five The SeaShow: The Real story", 

    "externalIdList": [{
       "name": "streamz_us",   // 将被弃用,忽略此项
       "value": "1700000123" // 目录中节目的ID
     },
     {
      "name": "amzn_id",
      "value": "1700000123" // 目录中节目的ID
    }]
  },
  {                // 参数1
    "type": 14,    // ContentSearchParamType::SEASON
    "value": "2",  // 目录中的季编号
    "externalIdList": []
  },
  {               // 参数2
    "type": 15,   // ContentSearchParamType::EPISODE
    "value": "5", // 目录中的剧集编号
    "externalIdList": []
  }
]

使用语音在应用内搜索内容标题

使用语音搜索电影Seabound。为此,使用表述“Alexa, find Seabound in Streamz”(Alexa,在Streamz中查找Seabound)。

应用必须显示含有Seabound和相关内容的搜索结果。搜索逻辑由应用决定。这里的autoPlay将为falsecontentSearch: IContentSearch将具有以下值。

已复制到剪贴板。

[
  {                      // 参数0
    "type": 13,          // ContentSearchParamType::VIDEO
    "value": "Seabound", // 搜索中要使用的搜索关键字
    "externalIdList": [{
        "name": "streamz_us",  // 将被弃用。 忽略此项
        "value": "1700000725"  // 目录中的ID
    },
   {
        "name": "amzn_id",
        "value": "1700000725" // 目录中的ID
    }
   ]
  }
]

使用语音在应用内搜索流派

通过表述“Alexa, find comedy movies in Streamz”(Alexa,在Streamz查找喜剧电影),使用语音搜索流派。

autoPlay将为falsecontentSearch: IContentSearch将具有以下值。Alexa将返回多个流派和类型。您可以选择自己的逻辑来实现搜索。

已复制到剪贴板。

 [
  {                               // 参数0
    "type": 6,                    // ContentSearchParamType::GENRE
    "value": "Comedy",           // 搜索中要使用的搜索关键字
    "externalIdList": []
  },
 {                                // 参数1
    "type": 6,                    // ContentSearchParamType::GENRE
    "value": "Dark Comedy",       // 搜索中要使用的搜索关键字
    "externalIdList": []
  },
 {                                // 参数2
    "type": 6,                    // ContentSearchParamType::GENRE
    "value": "Romantic Comedy",   // 搜索中要使用的搜索关键字
    "externalIdList": []
  },
 {                                // 参数3
    "type": 13,                   // VIDEO的ContentSearchParamType::TYPE
    "value": "comedy movies",     // 搜索中要使用的搜索关键字
    "externalIdList": []
  }
]

使用语音在应用内搜索演员

通过表述“Alexa, find Sean Connery movies in Streamz”(Alexa,在Streamz查找Sean Connery出演的电影),使用语音搜索演员。

autoPlay将为falsecontentSearch: IContentSearch将具有以下值。

已复制到剪贴板。

[
  {                                 // 参数0
    "type": 0,                      // ContentSearchParamType::ACTOR
    "value": "Sean Connery"         // 搜索中要使用的搜索关键字
    "externalIdList": []
  },
  {                                    // 参数1
    "type": 13,                       // VIDEO的ContentSearchParamType::TYPE
    "value": "Sean Connery movies",   // 搜索中要使用的搜索关键字
    "externalIdList": []
  }
]

Last updated: 2025年9月30日