内容启动器集成指南
本文档介绍如何将内容启动器集成到您的应用中。媒体应用通常需要与以下三个关键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"
partner-id与Fire OS启动器集成中使用的唯一标识符 (PARTNER_ID) 相同。请联系您的亚马逊代表,以获得支持和进一步说明。步骤2: 在应用中包含必要的程序包依赖项
在package.json文件中,添加@amazon-devices/kepler-media-content-launcher程序包作为依赖项。
"dependencies": {
"@amazon-devices/kepler-media-content-launcher": "^2.0.0",
},
步骤3: 实现内容启动器API
-
定义内容启动器处理程序。
实例化一个新的
ContentLauncherServerComponent。开发一个用于封装回调函数的处理程序对象。import { ILauncherResponse, IContentLauncherHandler, ContentLauncherStatusType, ContentLauncherServerComponent, ILaunchContentOptionalFields, } from '@amazon-devices/kepler-media-content-launcher'; ... // 创建一个ContentLauncherServerComponent的实例 let factory = new ContentLauncherServerComponent(); // 创建一个在请求启动内容时调用的处理程序。 const contentLauncherHandler: IContentLauncherHandler = { async handleLaunchContent( _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。 -
在交互式应用中实现Vega媒体内容启动器。
要在交互式应用中实现Vega媒体内容启动器,请先获取
IContentLauncherServerAsync的单例实例。针对ContentLauncherServerComponent实例使用getOrMakeServer方法,以实现IContentLauncherServerAsync。接下来,创建一个可实现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( _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处理程序采用一个参数来定义要播放的内容或显示搜索结果。
- 可选字段,通过指向实现
ILaunchContentOptionalFields接口的对象的指针进行传递。
内容启动器请求示例
以下示例解释了一些重要内容启动器用例的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来识别电影,然后直接播放电影。
LaunchId,则将以值的形式传递<ID>。用语音快速播放
通过语音播放电影Seabound。使用表述“Alexa, Play Seabound”(Alexa,播放Seabound)。
此处的autoPlay将为true。以下示例包含了contentSearch: IContentSearch值。应用会启动,并且应该使用ID 1700000725直接播放内容。
[
{ // 参数0
"type": 13, // ContentSearchParamType::VIDEO
"value": "Seabound", // 搜索字符串
"externalIdList": [{
"name": "streamz_us" // 您的目录ID。 将被弃用。 忽略此项
"value": "1700000725" // 目录中的ID
},
{
"name": "amzn_id"
"value": "1700000725" // 目录中的ID
}
]
}
]
streamz_us是目录ID的占位符。即使LaunchID存在于目录中,Alexa也不会使用它。用语音播放特定剧集
以下目录示例代表电视节目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将为true。contentSearch包含节目ID,而不是剧集ID。应用必须使用ID 1700000123、ContentSearchParamType::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": []
}
]
Last updated: 2026年3月23日

