求含全部必需指令的Alexa音乐技能示例代码及开发疑问解答
Alexa音乐技能开发问题解答
一、技能目录需上传的内容
- 技能元数据:含技能名称、描述、图标、关键词等基础信息,需符合Alexa技能商店规范
- 交互模型:定义用户语音指令(如“播放我的收藏歌单”),配置意图、槽位和样本话语
- 后端代码包:实现核心逻辑的代码(支持Node.js、Python等语言),必须包含所有必需指令的处理逻辑
- 合规文档:若涉及版权音乐,需提供授权证明;同时需上传隐私政策、使用条款等文件
二、必需指令的功能实现
GetPlayableContent
- 核心功能:根据用户语音请求(指定歌手、歌单、专辑等),返回匹配的可播放内容列表
- 关键返回数据:每个内容项的唯一ID、标题、艺术家、专辑信息、播放时长,以及符合Alexa格式要求的音频流地址
- 处理逻辑:对接音乐数据源,匹配用户请求内容,筛选出合规可播放项,按Alexa规范格式返回
Initiate
- 核心功能:启动播放会话,处理用户首次播放请求(如“打开我的音乐技能并播放XX歌单”)
- 必做操作:按需验证用户身份、初始化播放会话状态,调用
AudioPlayer接口发送首个音频播放指令,同时向Alexa返回播放启动响应 - 注意:响应必须包含
AudioPlayer.Play指令,正确设置播放行为(如REPLACE_ALL)
GetNextItem
- 核心功能:处理“下一首”请求,返回当前播放项的后续可播放内容
- 必做操作:读取当前会话的播放队列状态,定位下一个待播放内容,返回其音频流地址和元数据,同时调用
AudioPlayer接口发送下一首播放指令 - 注意:若播放队列已到末尾,需返回无后续内容的响应,或按业务逻辑处理循环播放
三、包含必需指令的Node.js示例代码
const Alexa = require('ask-sdk-core'); // GetPlayableContent指令处理器 const GetPlayableContentHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'Alexa.Music.Playback.GetPlayableContent'; }, handle(handlerInput) { const query = handlerInput.requestEnvelope.request.contentQuery; // 模拟对接音乐数据源获取内容 const playableItems = [ { id: 'track_001', title: '示例歌曲1', artist: '示例歌手', album: '示例专辑', duration: 180000, audioUrl: 'https://your-audio-host.com/track1.mp3' } ]; return handlerInput.responseBuilder .addDirective({ type: 'Alexa.Music.Playback.GetPlayableContent.Response', playableContent: { items: playableItems.map(item => ({ id: item.id, content: { title: item.title, artist: { name: item.artist }, album: { name: item.album }, duration: item.duration }, audioSource: { streamUrl: item.audioUrl, protocol: 'HTTP', format: 'MP3' } })) } }) .getResponse(); } }; // Initiate指令处理器 const InitiateHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'Alexa.Music.Playback.Initiate'; }, handle(handlerInput) { const contentId = handlerInput.requestEnvelope.request.playableContentId; const audioInfo = { url: 'https://your-audio-host.com/track1.mp3', title: '示例歌曲1', artist: '示例歌手' }; return handlerInput.responseBuilder .addAudioPlayerPlayDirective('REPLACE_ALL', audioInfo.url, contentId, 0, null) .getResponse(); } }; // GetNextItem指令处理器 const GetNextItemHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'Alexa.Music.Playback.GetNextItem'; }, handle(handlerInput) { const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); const currentTrackId = sessionAttributes.currentTrackId; // 模拟获取下一首内容 const nextTrack = { id: 'track_002', title: '示例歌曲2', artist: '示例歌手', audioUrl: 'https://your-audio-host.com/track2.mp3' }; sessionAttributes.currentTrackId = nextTrack.id; handlerInput.attributesManager.setSessionAttributes(sessionAttributes); return handlerInput.responseBuilder .addDirective({ type: 'Alexa.Music.Playback.GetNextItem.Response', nextItem: { id: nextTrack.id, content: { title: nextTrack.title, artist: { name: nextTrack.artist } }, audioSource: { streamUrl: nextTrack.audioUrl, protocol: 'HTTP', format: 'MP3' } } }) .addAudioPlayerPlayDirective('REPLACE_ALL', nextTrack.audioUrl, nextTrack.id, 0, null) .getResponse(); } }; // 技能入口 exports.handler = Alexa.SkillBuilders.custom() .addRequestHandlers( GetPlayableContentHandler, InitiateHandler, GetNextItemHandler ) .lambda();
内容的提问来源于stack exchange,提问作者Prit
相关产品推荐
相关产品推荐

