1

我需要在交互后立即播放“等一下……”消息。我需要这个,因为我必须在返回给用户之前执行一些耗时的任务。应用流程是:

1)播放欢迎信息(TTS) 2)收集用户语音(Rivr 语音记录交互) 3)播放“等一下”TTS 信息,因为语音和相关业务流程的处理很耗时(需要几秒钟) 4)[时间消费任务] 5)播放(TTS)过程的结果并说再见。

一切正常,但是在耗时的任务以及过程的综合结果(我的意思是,用户说话并且必须等待)之后立即播放“等待一秒钟”消息,即使在我的 Dialog 代码中它被放置在之前“耗时任务”。出于某种原因,Rivr 或 VoiceXML 引擎正在缓冲两个消息(3 和 5)一起播放它们。

如何使 Rivr “刷新”第 3 步并在录制交互后立即播放“等一下”消息,以便用户知道他应该等一下?

4

2 回答 2

1

VoiceXML 中的提示排队

在 VoiceXML 中,每当执行提示时,它实际上都放在队列中。VoiceXML 解释器仅在等待用户输入或退出时才会刷新提示队列(即播放它)。VoiceXML W3C 文档的Prompt Queuing and Input Collection部分详细描述了此行为。

在您的情况下,您的提示在进行长时间操作之前是排队的,并且仅在下一次交互期间播放。这是一种典型的情况,在 Rivr 中有经典的 VoiceXML 解决方案具有它们的等价物。

解决方案 1:使用强制刷新提示队列fetchaudio

VoiceXML 规范声明提示队列将被刷新...

当解释器开始获取指定了 fetchaudio 的资源(例如文档)时。在这种情况下,将在 fetchaudio 之前排队的提示播放到完成,然后,如果确实需要获取资源(即它在缓存中不是未过期的),则播放 fetchaudio 直到获取完成。

因此,为了确保播放提示,只需在<submit>用于获取长操作结果的元素上设置一个 fetchaudio 即可。大意是“请稍等”。消息将被播放,然后,在 fetchaudio 中指定的文件将循环播放,直到服务器返回结果。通常,您会使用提示正在处理某事的声音。

如果您不想在 VoiceXML 等待操作完成时听到任何声音,您可以提供一个包含静音的音频文件。另一个技巧是指定一个不存在的文件。这适用于某些 VoiceXML 平台。YMMV。

VoiceXML 可能如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml">
  <form id="form">
    <block>
      <prompt>Please wait a moment.</prompt>
      <submit fetchaudio="/audio/fetch.wav" method="post" next="/long-operation" />
    </block>
  </form>
</vxml>

使用 Rivr,它是:

context.getFetchConfiguration().getDocumentFetchConfiguration()
  .setFetchAudio("/audio/fetch.wav");

Message message = new Message("wait-message", 
  new SpeechSynthesis("Please wait a moment."));

DialogueUtils.doTurn(message, context);
performLongOperation();

解决方案2:插入人工等待状态

另一个强制播放提示队列的技巧是创建一个超时为 0 的虚拟交互。这是强制解释器播放消息。我们必须小心在提示符上禁用插入,否则 DTMF 输入可能会中断消息。这是一个虚拟输入的示例:

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml">
  <form id="form">

    <field name="dummy">
      <property name="timeout" value="0ms" />
      <grammar src="builtin:dtmf/digits" />
      <prompt>Please wait a moment.</prompt>
      <filled>
        <goto nextitem="submit" />
      </filled>
      <noinput>
        <goto nextitem="submit" />
      </noinput>
      <nomatch>
        <goto nextitem="submit" />
      </nomatch>
    </field>

    <block name="submit">
      <submit fetchaudio="audio/fetch.wav" method="post" next="/long-operation" />
    </block>

  </form>
</vxml>

这是 Rivr 等价物:

DtmfRecognition dummyRecognition = new DtmfRecognition(new GrammarReference("builtin:dtmf/digits"));

SpeechSynthesis message = new SpeechSynthesis("Please wait a moment.");

Interaction interaction = OutputTurns.interaction("wait-message")
                .addPrompt(dummyRecognition, message).build();

DialogueUtils.doTurn(interaction, context);
performLongOperation();

如果你想在你的应用程序中重用这个模式,你可以创建一个函数:

private void forcePlayMessage(VoiceXmlDialogueContext context,
                              String messageName,
                              AudioItem... audioItems)
                throws Timeout, InterruptedException {
    DtmfRecognition dummyRecognition = new DtmfRecognition(new GrammarReference("builtin:dtmf/digits"));
    Interaction interaction = OutputTurns.interaction(messageName)
            .addPrompt(dummyRecognition, audioItems).build();
    DialogueUtils.doTurn(interaction, context);
}

如果操作很长,最好使用 JavaFutureTask类在后台处理您的请求,允许您对话每隔 X 秒向您的调用者发送消息,而不是阻塞performLongOperation()

于 2015-09-19T23:17:09.937 回答
0

一些平台等到输入或 a 才开始说话。如果您的平台支持 fetchaudio 属性,请将其作为繁重的主机任务的一部分播放。

于 2015-09-19T20:45:49.180 回答