Google Home Action音频控制意图实现咨询:暂停、快进/后退
解决Google Home Action音频控制问题:暂停报错及快进/后退实现
一、先搞定「无音频正在播放」的暂停问题
你遇到的这个问题,核心是Google Assistant没识别到当前有活跃的Media Session——也就是说,你之前返回SSML音频的方式,没让Assistant建立起对正在播放媒体的跟踪。
1. 播放音频时必须初始化Media Session
别再只返回带<audio>标签的SSML了,一定要用Google Assistant的Media响应格式来返回音频。这样Assistant才会创建Media Session,后续的暂停/快进操作才能关联上。
用Node.js SDK举个例子:
app.intent('PlayAudioIntent', (conv) => { // 用media()方法构建媒体响应,而不是单纯返回SSML conv.media({ name: "我的音频内容", url: "https://你的音频地址.mp3", description: "音频描述", image: { url: "https://封面图片地址.jpg", alt: "音频封面" }, duration: 180 // 可选,但最好加上音频总时长(秒),方便后续控制 }); });
如果是直接返回Webhook JSON响应,结构大概是这样:
{ "fulfillment_response": { "messages": [ { "media_response": { "media_type": "AUDIO", "media_objects": [ { "name": "我的音频内容", "content_url": "https://你的音频地址.mp3", "description": "音频描述", "large_image": { "url": "https://封面图片地址.jpg", "accessibility_text": "音频封面" }, "duration": 180 } ] } } ] } }
2. 正确处理系统暂停意图
在Action控制台里,先启用actions.intent.PAUSE这个系统意图(不用自己训练短语,Assistant会自动识别「暂停」「停一下」这类指令)。然后在Webhook里处理这个意图时,要更新Media Session的状态,而不是随便返回一句文本:
app.intent('actions.intent.PAUSE', (conv) => { // 先判断是否有活跃的Media Session if (!conv.media?.status) { return conv.close("现在没有正在播放的音频哦"); } // 更新媒体状态为暂停 conv.media.status = 'PAUSED'; conv.close("已暂停播放"); });
这样Assistant就会知道当前媒体处于暂停状态,不会再报错「无音频正在播放」了。
二、实现快进/后退20秒功能
这个要用到Google Assistant的actions.intent.SEEK系统意图,步骤如下:
1. 启用SEEK系统意图
在Action控制台里找到并启用actions.intent.SEEK,Assistant会自动识别「快进20秒」「后退20秒」这类指令。
2. 在Webhook中处理SEEK请求
处理时需要计算目标播放偏移量,然后更新Media Session的currentOffset字段:
app.intent('actions.intent.SEEK', (conv, input, seek) => { if (!conv.media?.status) { return conv.close("现在没有正在播放的音频哦"); } // 计算目标偏移:当前偏移 ±20秒(这里固定用20秒,忽略用户可能说的其他时长) const currentOffset = conv.media.currentOffset || 0; const targetOffset = currentOffset + (seek.offset > 0 ? 20 : -20); // 确保偏移量不超出音频范围(如果设置了duration的话) const clampedOffset = Math.max(0, Math.min(targetOffset, conv.media.duration || Infinity)); // 更新偏移量,恢复播放状态(如果之前是暂停的话,也可以保持暂停,看你需求) conv.media.currentOffset = clampedOffset; conv.media.status = 'PLAYING'; conv.close(`已${seek.offset > 0 ? '快进' : '后退'}20秒`); });
如果是返回JSON响应,要在media_response里带上current_offset字段:
{ "fulfillment_response": { "messages": [ { "media_response": { "media_type": "AUDIO", "media_objects": [ { // ... 其他媒体信息 "current_offset": 40 // 更新后的播放位置(秒) } ] } } ] } }
几个小提醒
- 测试时要确保播放音频后立刻触发控制指令,别间隔太久,Media Session会超时
- 如果你用的是自定义意图(不是系统的PAUSE/SEEK),一定要确保意图触发短语足够精准,并且处理逻辑和上面一致,必须操作Media Session的状态
- 尽量提供音频的
duration字段,这样Assistant能更好地处理偏移量,避免超出音频时长
内容的提问来源于stack exchange,提问作者Igor Vargas
相关产品推荐
相关产品推荐

