在我的 Google Action 中,如何使用单个用户话语有效地结束播放一个 MP3 并“跳到”另一个 MP3?

问题描述

我有一个单场景动作,它在调用调用我的网络钩子“randomSpeech”(如下所述),它播放 MP3。我添加一个“跳过”意图来跳到下一个 MP3。当我说“跳过”时,Action 应该转换(循环)回到 webhook 'randomSpeech',并且由于有一个计数器,x,Action 应该开始播放switch 语句中的第二个 MP3。

但是,我必须说两次“跳过”这个词才能让它起作用。

  1. 我第一次说“跳过”时,系统意图 MEDIA_STATUS_FINISHED 自动调用mediaStatus”处理程序和文本“媒体已完成”。被添加到对话中。即使我已经配置了“跳过”意图来调用处理程序,'randomSpeech',它似乎没有发生,因为没有新的媒体添加到对话中。这几乎就像 'randomSpeech',完全被忽略了!
  2. 我第二次说“跳过”,第二个 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.');
  }
});


来自唯一场景的图片,“动机”:

Scene

On enter

Intent handling


进一步说明:

  • 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
  }
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...