我需要播放一个“等一下…”在一次互动之后的留言。我需要这样做,因为我必须在返回用户之前执行一些耗时的任务。应用程序流是:
1)播放欢迎消息( TTS ) 2)从用户收集语音(Rivr语音记录交互) 3)播放“等待第二”TTS消息作为语音和相关业务流程的处理耗时(耗时数秒) 4)时间消耗任务5)播放(TTS)过程的结果和说再见。
一切正常,但是“等待一秒钟”消息就在耗时的任务和进程的综合结果之后播放(我的意思是,用户说话,必须等待),尽管在我的对话框代码中,它放在“耗时任务”之前。由于某种原因,Rivr或VoiceXML引擎正在缓冲这两条消息(3和5),同时播放它们。
我如何使Rivr“冲水”步骤3和播放“等待一秒钟”消息后,立即录音互动,让用户知道他应该等一会儿?
发布于 2015-09-19 23:17:09
VoiceXML中的快速排队
在VoiceXML中,无论何时执行提示符,它实际上都被放置在队列中。只有在等待用户输入或退出时,VoiceXML解释器才会刷新提示队列(即播放)。这种行为在VoiceXML W3C文档的W3C部分中有详细描述。
在您的示例中,您的提示符在执行长操作之前是队列,并且只在下一次交互中播放。这是一种典型的情况,有一些经典的VoiceXML解,它们在Rivr中具有等价性。
解决方案1:强制使用fetchaudio
刷新提示队列
VoiceXML规范声明提示队列将被刷新.
当解释器开始获取指定了fetchaudio的资源(例如文档)时。在这种情况下,在读取完成之前排队的提示,然后,如果实际需要获取资源(即它在缓存中未过期),则在提取完成之前一直播放。
因此,为了确保将播放提示,您可以简单地在用于获取长操作结果的<submit>
元素上设置一个set。结果是“请稍等一下”。消息将被播放,然后,将在一个循环中播放在调用中指定的文件,直到服务器返回结果为止。通常情况下,你会使用一个声音暗示正在处理的东西。
如果您不希望在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>
这是铆钉的等价物:
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);
}
如果操作时间很长,最好使用Java FutureTask
类在后台处理请求,允许对话框每X秒向调用方发送消息,而不是阻塞performLongOperation()
发布于 2015-09-19 20:45:49
有些平台等到输入或a开始发言。如果您的平台支持fetchaudio属性,则将其作为重主机任务的一部分进行播放。
https://stackoverflow.com/questions/32670820
复制相似问题