端上约定逻辑

DCS设备端在与用户和服务端交互过程中,会碰到在播放音乐时响起闹铃的情况,会碰到在播报天气时被用户打断的情况,设备端也有可能收到无法识别的指令。在碰到这些情况时,为了保证良好产品体验,我们约定设备端对这些情况的处理逻辑。

本页面详细介绍以下设备端上的约定规则:

  • 事件与指令的字段
  • dialogRequestId与活跃对话
  • 指令执行顺序
  • 多通道音频播放

指令与事件的字段

messageId

服务端下发的每个指令,在其header参数中都有messageId,是代表该指令的唯一id。messageId并不影响实际功能,但在调试追踪问题时方便定位一个指令。

同样,设备端上报每一个事件,应该为该事件生成一个唯一的messageId,并放在事件的header参数中,以便需要时方便以messageId来定位事件。

不可省字段缺失与字段类型错误

如果因为服务端异常导致不可省字段缺失,字段类型错误,设备端不应该终止设备端应用,应用应该继续正常运行,可以放弃有问题指令的执行。

无法识别的字段

为了不断增强DuerOS交互能力,服务端在必要时会进行协议升级。为了保持对已有设备的向后兼容,服务端在进行协议升级时,会新增加字段,但不会改变已有字段。

设备端收到指令,如果指令的header参数或者payload参数多出了不能识别的字段,设备端应该忽略所有不能识别的字段,正常执行指令。

无法识别的指令

服务端协议升级也会增加新指令,但正常情况下服务端不应该对现有设备下发无法识别的新指令。如果设备端收到了无法识别的指令,应该上报ExceptionEncountered事件,但不应该终止设备端应用,应用应该继续正常运行。

dialogRequestId与活跃对话

用户每一次语音请求(包括多轮对话中的每一次语音请求)都是新一轮对话的开始。设备端应该为每一次对话创建一个唯一的dialogRequestId,并放在ListenStarted事件的header参数中。服务端下发指令时,如果指令是对用户某一个语音请求的回答,则指令的header参数中会携带对应语音请求的dialogRequestId。

活跃对话是用户最近一次发起的语音请求(对应设备端最近上报的ListenStarted事件)。每次用户发起新的语音请求时,设备端应该记录当前活跃对话的dialogRequestId,并把所有还未执行完的之前dialogRequestId(非活跃对话)对应的指令都取消掉,如果有之前dialogRequestId对应的Speak指令正在执行,也应该立即停止。

指令执行顺序

设备端收到的带有dialogRequestId的指令,应该按收到的顺序一个一个执行。对于Speak指令,把播报播完才是指令执行结束,再执行下一条指令。对于Play指令,只要把音频放到队列或者开始进行播放,即指令执行结束,可以继续执行下一条指令。

大部分指令定义中都是带dialogRequestId的,但dialogRequestId字段是可选的,服务端可以根据情况下发不带dialogRequestId的指令,设备端收到不带有dialogRequestId的指令,应该立即执行(与其他指令独立并行执行)。

多通道音频播放

音频播放通道

具有扬声器的设备端,应该支持多个音频播放通道,对应不同的端能力。DCS定义了以下三种音频播放通道:

  1. 对话通道:对应语音输入(Voice Input)和语音输出(Voice Output)端能力;用户在语音请求时,或者设备在执行Speak指令进行播报时,对话通道进入活跃状态
  2. 闹钟通道:对应闹钟(Alerts)端能力;在闹铃响起时,闹钟通道进入活跃状态
  3. 音频通道:对应音频播放器(Audio Player)端能力;在播放音频(音乐、新闻、有声资源)时,音频通道进入活跃状态

播放优先级

如果同一时刻有多个播放通道同时处在活跃状态(如正在播放音乐时闹铃响起),优先级最高的通道应该在前景(foreground),其他低优先级通道应该移到背景(background)。在最高优先级的播放通道播放完毕并退出活跃状态后,下一优先级的播放通道从背景移到前景。

移到背景的播放通道,可以暂停播放,也可以把声音减弱播放。

播放通道优先级:对话通道 > 闹钟通道 > 音频通道