步骤2: 在多模式设备上启用您的视频技能并进行测试 (VSK Echo Show)
现在您已经创建了视频技能,是时候将其连接到多模式设备了。使用Fire TV应用,您可以在Fire TV设备上运行应用,并通过ADB进行连接。但是,多模式设备不使用应用,也无法通过ADB进行连接。相反,您将通过以下方式来运行您的视频技能:发布网页播放器,为视频技能提供网页播放器的URI,然后将您的技能与多模式设备关联。多模式设备将调用您的网页播放器(从您的服务器)以显示所请求的媒体。
- 步骤2.1: 设置示例网页播放器
- 步骤2.2: 在多模式设备上激活视频技能
- 步骤2.3: 在Alexa设备上启用您的技能
- 步骤2.4: 测试您的技能
- 步骤2.5: 查看发送给Cloudwatch的指令
- 后续步骤
步骤2.1: 设置示例网页播放器
尽管您将在集成过程的后期(具体而言是步骤5: 构建您的网页播放器)构建网页播放器,现在,先下载一个示例网页播放器项目以开始使用并观察发送到您的Lambda的Alexa指令。示例网页播放器包括视频内容的启动、基本的播放控件以及与Alexa视频JavaScript库的集成。
您可以在这里下载示例网页播放器:
要设置示例网页播放器,请执行以下操作:
- 下载sample_web_player.zip并解压文件。
- 如果您的系统上还没有Node JS和npm,请安装它们。
- 在命令行中,浏览到示例网页播放器目录。
-
运行以下命令:
npm install -g gulp http-server -
然后运行:
npm install gulp -
将网页播放器上传到网页服务器上。
对于此示例设置,您还可以使用以下网页播放器URL:
https://amzndevresources.com/video-skills-kit/sample-web-player/sample_web_player/index.html。此URL仅提供配置为静态网站的S3存储桶中的默认网页播放器代码。根据需要,更新您在步骤1中步骤1.4: 完成视频技能设置里执行的视频技能配置中的网页播放器URI。
步骤2.2: 在多模式设备上激活视频技能
您已经设置了视频技能和Lambda函数,现在应该测试您的技能并观察Alexa向您的Lambda函数发送的指令。要进行此项测试,您将需要一台实体多模式设备,例如Echo Show。
步骤2.3: 在Alexa设备上启用您的技能
要在支持Alexa的设备上测试您的技能,请执行以下操作:
-
使用您在创建视频技能时使用的相同开发者账户来设置并注册您的多模式设备。请注意以下事项:
- 如果您的设备已经注册其他用户,请恢复出厂设置并使用您的开发者账户进行注册。(或者您可以参见注销设备以通过amazon.com注销该设备。)
- 您将需要Alexa智能手机应用来完成设备设置。如果您还没有这个应用,请下载它并使用您的开发者账户登录。
- 使用您的开发者账户设置您的多模式设备(例如Echo Show)。有关详细信息,请参阅设置带屏幕的Echo设备。
- 确保您的Alexa智能手机应用和Echo Show设备都在同一WiFi网络上。
注意: 多模式设备的最终用户文档将这些类型的设备称为“带屏幕的Echo设备”。 但是,并非所有带屏幕的Echo设备都支持视频技能。例如,不支持Echo Spot。目前,所有Echo Show设备(第一代、第二代、Echo Show 5)都支持视频技能。“多模式设备”一词是指支持视频技能的Echo设备。 - 在手机上打开Alexa智能手机应用,并使用相同的开发者账户登录。
-
在底部导航栏中点击Devices(设备)
,然后选择All Devices(所有设备)。确认您的Echo设备出现在您的应用中。提示: 您可以通过询问您的Echo设备来找到它的名称:“Alexa, what's your device name?”(Alexa,你的设备名称是什么?)
Alexa智能手机应用中您的设备列表 智能手机应用的速度可能有点慢,因此,如果您按下按钮时该应用似乎没有立即响应,请耐心等待。这种速度缓慢问题将在即将发布的版本中得到解决。
-
在应用的主屏幕中,点击菜单按钮(左上角)
,然后点击Settings(设置),再点击TV & Video(电视和视频)。向下滚动列表,找出其下方显示“Enabled”(已启用)的所有技能。如果技能标示了Enabled(已启用),请点击该技能,然后单击Disable Skill(禁用技能),这样就不会启用任何电视和视频技能。(否则,其他技能可能会干扰您的测试。)
禁用视频技能 然后单击顶部的返回箭头返回至电视和视频技能的列表。
-
向下滚动列表,查找您之前创建的视频技能。它将出现在底部。单击视频技能旁边的加号按钮。

Alexa应用中的视频技能 -
单击您的技能查看其详细信息后,单击Link Your Alexa Device(关联您的Alexa设备)。
您的浏览器中会打开一个新页面,说明您的技能已成功关联。

您的技能已成功关联 -
单击应用左上角的X关闭此通知窗口。当您关闭窗口时,Alexa应用会显示与您的设备相关的技能。

您的关联设备清单 (如果需要,可以单击“Save”(保存),这并非必需。) 如果您单击返回按钮前往电视和视频技能,您将在技能旁边看到“Enabled”字样:

您的已启用技能。在此示例中,启用的技能的名称为“Hawaii Echo”。 您已经完成了Alexa智能手机应用中的配置。您可以单击主页按钮或直接关闭应用。
步骤2.4: 测试您的技能
-
现在,您的视频技能已与您的设备相关联,请转向多模式设备并说:“Alexa, go to Video Home”(Alexa,前往视频主页)。
您的视频技能的标志图像资产应出现:
您的视频技能标志显示在视频主页上 -
用手指点击您的视频技能标志。这会启动Alexa
GetDisplayableItems指令,从目录中获取与您的视频技能相关的可浏览项目。Alexa会从您的目录中返回结果。例如,如果您使用目录“hawaii_us”(包含Creative Commons资产的示例目录),则设备将显示以下内容:
您目录中的缩略图 Alexa现在正在向您的Lambda发送指令,您可以在Cloudwatch中看到这种交互。
注意: 当您进入视频主页并点击特定视频技能时,如果您提出任何请求,都将从该技能中查找媒体(而不是查看设备上所有视频技能的目录)。 这样可以避免Alexa返回其他目录中的结果。 -
对着您的多模式设备说:“Alexa, play the movie Big Buck Bunny.”(Alexa,播放电影Big Buck Bunny。)
提示: 要格外小心,应当稍许缓慢地说出Big Buck Bunny。否则,Alexa会倾向于将其解释为Bugs Bunny。视频应在设备上播放。此内容URL被硬编码到示例Lambda的响应的
playbackContextToken中。Big Buck Bunny在Echo Show上播放
步骤2.5: 查看发送给Cloudwatch的指令
当您对支持Alexa的设备说出短语时,这些短语会被处理并转换为指令。指令是从Alexa发送到Lambda进行处理的信息块(采用JSON格式)。
您可以通过Cloudwatch查看Alexa发送至Lambda函数的指令。Cloudwatch是一项AWS服务,以日志、指标和事件的形式收集Lambda(和其他服务)的监控和操作数据。每次您的Lambda函数收到来自Alexa的指令时,您都可以在Cloudwatch中查看指令和其他日志。
要在Cloudwatch中查看您的Lambda函数收到的指令,请执行以下操作:
-
您可以通过两种方式导航到Cloudwatch:
-
选项1: 在AWS中的Lambda函数内,单击Monitoring(监控)选项卡。然后单击View logs in Cloudwatch(在Cloudwatch中查看日志)按钮。这会让您直接来到您正在查看的Lambda函数的日志。

查看您的Lambda函数的Cloudwatch日志 -
选项2: 单击AWS顶部导航栏中的Services(服务)菜单,然后选择Cloudwatch。在左侧边栏中单击Logs(日志)。默认情况下,会显示一个以您的Lambda函数命名的日志。选择包含您的Lambda函数的日志。
注意: 如果您看不到自己的Lambda函数,请确保您位于正确的AWS区域。
-
-
为您的日志选择最新的日志流。
提示: 流只是日志的分组。Cloudwatch会定期创建新的日志流,因此,如果您没有看到最新的日志,请通过单击返回一个级别以查看Cloudwatch是否创建了新的日志流。另请注意,日志流按相反的时间顺序列出,最新的日志位于最上面。但是,当您深入研究特定日志时,该日志的内容会按时间顺序列出,其中最旧的日志消息会位于最上面。 -
查找一条显示
Interaction starts(交互开始)的日志消息。这是事件日志的开头,该事件包含Alexa的请求和来自Lambda的响应。示例Lambda代码以此消息作为每个事件的前缀,因而此注释将多次出现。
Cloudwatch日志 -
展开包含
Alexa Request: GetPlayableItems(Alexa请求:GetPlayableItems)的日志消息。这里实际上有多种交互、一些
GetDisplayableItems指令和其他GetPlayableItems。首先,当您按下视频技能的标志时,这会触发来自Alexa的GetDisplayableItems指令,但没有关于所请求媒体的任何具体信息。您的Lambda会使用您希望多模式设备在那里显示的项目进行响应。这些项目显示在多模式设备提供的浏览模板中。接下来,当您说“Alexa, play the movie Big Buck Bunny”(Alexa,播放电影Big Buck Bunny)时,这会触发Alexa的
GetPlayableItems指令。此请求包含一个带有entities块的payload,其中包含用户请求的视频 (value: Big Buck Bunny)。尝试在Cloudwatch中找到这个具有值Big Buck Bunny的特定日志。Alexa指令: GetPlayableItems
{ "directive": { "profile": null, "payload": { "minResultLimit": 1, "entities": [ { "externalIds": null, "type": "MediaType", "value": "MOVIE", "entityMetadata": null, "mergedGroupId": 0 }, { "externalIds": { "hawaii_us": "tt1254207" }, "type": "Video", "value": "Big Buck Bunny", "entityMetadata": null, "mergedGroupId": 1 } ], "timeWindow": null, "locale": "en-US", "contentType": null, "maxResultLimit": 40 }, "endpoint": { "cookie": {}, "endpointId": "ALEXA_VOICE_SERVICE_EXTERNAL_MEDIA_PLAYER_VIDEO_PROVIDER", "scope": { "token": "1bdaa2eb-4aa3-d0dc-fb10-7a5513981cf8", "type": "BearerToken" } }, "header": { "payloadVersion": "3", "messageId": "8dd96f67-9b5e-4db4-803b-2f6d71a4a62e", "namespace": "Alexa.VideoContentProvider", "name": "GetPlayableItems", "correlationToken": null } } }当用户请求播放电影时,Alexa会将其解释为快速播放场景,并首先发送
GetPlayableItems指令。该指令中的payload包含Alexa认为用户在要求的值:"value": "Big Buck Bunny"。此时,通常您的Lambda代码可能会执行查找或其他查询,以确定用户真正要求的是什么媒体。Alexa刚刚完成了将用户的表述解析为结构化有效负载供您处理的工作。如果用户说了较为笼统的话,比如“Avengers”,您可能需要澄清用户真正需要的是哪部Avengers电影。或者,如果用户说:“Play Mozart in the Jungle”(播放Mozart in the Jungle),您需要澄清具体是哪一季和哪一集。
您的Lambda向Alexa返回
GetPlayableItemsResponse响应,其中包含您目录中与用户请求相匹配的所有作品。(在示例Lambda中,响应是预定义的,而不是通过某些后端服务动态查询的。) 展开Lamba Response: GetPlayableItemsResponse日志消息(在Alexa Request: GetPlayableItems下)以查看所请求媒体的mediaIdentifier:Lambda响应: GetPlayableItemsResponse
{ "event": { "header": { "correlationToken": "dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg==", "messageId": "5f0a0546-caad-416f-a617-80cf083a05cd", "name": "GetPlayableItemsResponse", "namespace": "Alexa.VideoContentProvider", "payloadVersion": "3" }, "payload": { "nextToken": "fvkjbr20dvjbkwOpqStr", "mediaItems": [ { "mediaIdentifier": { "id": "tt1254207" } } ] } } }在这种情况下,只有一个
mediaIdentifier,但其他场景可能会返回更多匹配的作品。此时,Alexa可能会询问用户想要播放哪部作品。在Alexa知道要播放的正确媒体之后,它会向您的Lambda发送另一个请求。此请求是一个
GetPlayableItemsMetadata指令。该指令要求提供在Lambda的GetPlayableItemsResponse中返回的媒体的元数据(元数据包括运行时间、用户进度和其他外部元数据):Alexa指令: GetPlayableItemsMetadata
{ "directive": { "profile": null, "payload": { "locale": "en-US", "mediaIdentifier": { "id": "tt1254207" } }, "endpoint": { "endpointId": "ALEXA_VOICE_SERVICE_EXTERNAL_MEDIA_PLAYER_VIDEO_PROVIDER", "cookie": {}, "scope": { "token": "1bdaa2eb-4aa3-d0dc-fb10-7a5513981cf8", "type": "BearerToken" } }, "header": { "payloadVersion": "3", "messageId": "3b4041f4-6114-4034-b295-e3afd2df8e19", "namespace": "Alexa.VideoContentProvider", "name": "GetPlayableItemsMetadata", "correlationToken": null } } }然后,您的Lambda执行查询以收集有关该特定视频的元数据,并在
GetPlayableItemsMetadataResponse中返回信息:Lambda响应: GetPlayableItemsMetadataResponse
{ "event": { "header": { "correlationToken": "dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg==", "messageId": "38ce5b22-eeff-40b8-a84f-979446f9b27e", "name": "GetPlayableItemsMetadataResponse", "namespace": "Alexa.VideoContentProvider", "payloadVersion": "3" }, "payload": { "searchResults": [ { "name": "Big Buck Bunny", "contentType": "ON_DEMAND", "series": { "seasonNumber": "1", "episodeNumber": "1", "seriesName": "Blender Foundation视频", "episodeName": "Pilot" }, "playbackContextToken": "{\"streamUrl\": \"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4\", \"title\": \"Big Buck Bunny\"}", "parentalControl": { "pinControl": "REQUIRED" }, "absoluteViewingPositionMilliseconds": 1232340 } ] } } }请注意此处返回的
playbackContextToken值。此值是一个同时包含streamUrl和title参数的对象,它包含播放视频的URL。多模式设备会将此playbackContextToken发送给您的网页播放器,然后您的网页播放器将开始播放视频。注意: 在此示例Lambda中,播放媒体的内容URL直接在playbackContextToken中提供。但是,在您的实现中,您无需在此处包含用来播放媒体的URL。相反,您只需提供某种媒体标识符。无论您发送什么标识符,亚马逊都会将该标识符发送给您的网页播放器(托管在您的服务器上)。然后,您的网页播放器需要实现逻辑,以将您的标识符转换为实际媒体播放URL。使用这种方法,您就不会将您的媒体播放URL暴露给亚马逊。但是,这种更复杂的逻辑(用于将标识符转换为媒体的媒体播放URL)并未在此简单的Lambda代码中实现,您也无需遵循此模式。有关playbackContextToken和网页播放器的更多详细解释,请参见步骤4: 了解您的网页播放器如何获取媒体播放URL中解释了该过程。为什么有两个调用,即为什么有GetPlayableItems,然后是GetPlayableItemsMetadata?
您可能想知道为什么Alexa进行了两次调用来获取用户请求的内容。打个比方,假设一位顾客走进一家快餐店,对柜台的工作人员说:“我想要一个汉堡。“ 工作人员意识到顾客想要一个汉堡,但是餐厅的菜单上有多种匹配的汉堡包。因此,工作人员回答说:“我们有几种类型的汉堡包。您想要豪华汉堡、基础汉堡还是我们的每日特惠汉堡?”
顾客对此进行澄清,表示他想要一个“豪华汉堡”。 因此,工作人员返回有关豪华汉堡的信息(价格、内含食材、调味品等)以履行订单。
自然语言是指不断地来回提出请求和进行回应,以澄清意图。当多模式设备和用户发出媒体请求时,也会进行多次请求和响应交互,以澄清用户真正想要的媒体。如您所见,多模式设备上的交互与Fire TV应用集成中的交互有很大不同。在Fire TV应用集成中,您的Lambda函数向Alexa发回了一条简短的成功消息,但仅此而已。但是,通过多模式设备的实现,在您的后端服务检索到正确的信息后,您实际上会向Alexa发回详细的响应。有多个使用请求和响应的来回引用。
后续步骤
现在,您已经探索了向Lambda发送事件的一些初始工作流程,让我们更深入和全面地了解示例Lambda代码中的情况。继续执行步骤3: 了解Alexa指令和预期响应。

