问题描述
我有一个单场景动作,它在调用时调用我的网络钩子“randomSpeech”(如下所述),它播放 MP3。我添加了一个“跳过”意图来跳到下一个 MP3。当我说“跳过”时,Action 应该转换(循环)回到 webhook 'randomSpeech',并且由于有一个计数器,x,Action 应该开始播放switch 语句中的第二个 MP3。
但是,我必须说两次“跳过”这个词才能让它起作用。
- 我第一次说“跳过”时,系统意图 MEDIA_STATUS_FINISHED 自动调用“mediaStatus”处理程序和文本“媒体已完成”。被添加到对话中。即使我已经配置了“跳过”意图来调用处理程序,'randomSpeech',它似乎没有发生,因为没有新的媒体添加到对话中。这几乎就像 'randomSpeech',完全被忽略了!
- 我第二次说“跳过”,第二个 MP3 终于开始播放了。
我的主要问题是,如何才能让用户只需说一次“跳过”?
let x = 1;
app.handle('randomSpeech',(conv) => {
switch(x) {
case(1):
conv.add(new Media({
mediaObjects: [
{
name: 'NEVER GIVE UP',description: 'some athlete',url: 'http://zetapad.com/speeches/nevergiveup.mp3',image: {
large: {
url: 'https://www.keepinspiring.me/wp-content/uploads/2020/02/motivation-gets-you-started-jim-ryun-quote-min.jpg'
}
}
}
],mediaType: 'AUdio',optionalMediaControls: ['PAUSED','STOPPED'],startOffset: '5s'
}));
x++;
break;
case(2):
conv.add(new Media({
mediaObjects: [
{
name: 'SPEECHLESS',description: 'Denzel Washington (feat Will Smith)',url: 'http://zetapad.com/speeches/denzel.mp3',image: {
large: {
url: 'https://www.keepinspiring.me/wp-content/uploads/2020/02/motivational-quotes-2-min.jpg'
}
}
}
],'STOPPED']
}));
break;
}
});
app.handle('media_status',(conv) => {
const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved;
switch(mediaStatus) {
case 'FINISHED':
conv.add('Media has finished.');
break;
case 'Failed':
conv.add('Media has Failed.');
break;
case 'PAUSED' || 'STOPPED':
if (conv.request.context) {
// Persist the media progress value
const progress = conv.request.context.media.progress;
}
conv.add(new Media({
mediaType: 'MEDIA_STATUS_ACK'
}));
break;
default:
conv.add('UnkNown media status received.');
}
});
来自唯一场景的图片,“动机”:
进一步说明:
- MEDIA_STATUS_PAUSED / MEDIA_STATUS_FINISHED / MEDIA_STATUS_STOPPED 都只调用“media_status”微信
解决方法
你问题的核心问题是“跳过”是一个内置的媒体播放器命令(虽然这不是很清楚documented),所以当用户说“跳过”时,播放器会处理这个因为音频是 completed,所以它发送 MEDIA_STATUS_FINISHED
Intent,就像用户一直在听一样。
好消息是 - 您实际上希望以相同的方式处理这两种情况!因此,如果用户跳到下一个音频,或完成第一个音频并且它应该前进到下一个音频 - 您想要播放下一个音频。
在您的代码中,“播放下一个音频”都是作为 switch 语句的一部分完成的。因此,您可能应该将其单独放入常规 JavaScript 函数中。然后,您可以从已设置的不同处理程序调用该函数。
它可能看起来像这样(没有一些代码细节):
function nextAudio( conv ){
// Code goes here to figure out the next audio to play and send it back
}
app.handle('randomSpeech',(conv) => {
nextAudio( conv );
}
app.handle('media_status',(conv) => {
const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved;
switch(mediaStatus) {
case 'FINISHED':
nextAudio( conv );
break;
// Other media status cases can go here
}
});