通话、会议与抢麦
约 3914 字大约 13 分钟
2026-10-16
先读控制公共规则,再按 Topic、method 和方向查阅。应用侧使用鉴权命令提交、事件拉取与确认;事件结构不表示已启用 WebSocket 推送。能力可用性见支持范围。
callControl · SIG↑
- 方向:设备→平台;应答:callState。
- 触发、权限与状态:不带candidateSessionId的cancel只允许尚未接通的呼叫;已接通用sessionEnd。带candidateSessionId的cancel仅撤本端原转接账本绑定的候选,原主通话保持active。hold只保留会话/信令,停止本端发声与转发麦克风;resume重新获得焦点。转接先新建候选呼叫并得到对方接听/媒体连通,再提交替换;失败保留原通话。AI转人工不默认共享转写/图像。
- 正常设备转接保留原被叫会话腿,以新候选替换转接发起方;成功仅结束发起方原腿,原被叫与候选继续同一呼叫组。候选会话只授权候选本人接听/协商/结束,不授予发起设备冒用该会话的权限。
- 超时、幂等、迟到及清理采用本页公共行为和公共约定;成功应答不能代替独立完成状态。
- 场景:呼叫等待转接与AI转人工。
| 字段 | 类型 | 必填条件 | 值与含义 |
|---|---|---|---|
| operation | string | 必填 | cancel/hold/resume/transfer/escalate |
| expectedRevision | uint | 必填 | 本呼叫控制修订号 |
| target | Party | 转接或转人工必填 | 服务端可解析的目标 |
| candidateSessionId | string | cancel时可选,其他操作禁止 | 撤销原主体、原本端session、原转接账本代次共同绑定的候选;不是发起者身份,expectedRevision仍核原主通话 |
| consentIds | string[] | 仅escalate且shareContext=true时必填;其他情况禁止 | 1至16项不重复的同意引用,每项为不超过128字节的合法ID;仅语法合法不代表授权成立 |
| shareContext | boolean | 仅escalate时可选;其他操作禁止 | 缺省false;false不携带consentIds,不共享上下文 |
{
"msgToken": "s13-8",
"method": "callControl",
"sessionId": "s13-session",
"params": {
"operation": "cancel",
"expectedRevision": 0
}
}对应呼叫等待转接与AI转人工:M03;其他操作按条件字段校验。
AI转人工的候选关联与第三屏障(部分实现,端云待验)
escalate作用于原AI会话,不套用人际transfer的“发起方退出”规则。平台校验原AI主体、目标权限及双方实际人际媒体能力后,一次性分配候选人工腿、本端新人工腿和呼叫组;用原AI会话的callState受理回执关联,随后分别发送普通sessionInvite。新邀请只使用现有邀请字段,不得把原AI sessionId、人工候选sessionId或呼叫组当本端新腿身份。
目标service必须有服务端真实解析与授权结果;当前该解析及AI转人工入口未实现,不默认选管理员、设备所有者或其他在线端。shareContext=false保持不共享;true及consentIds的签署者/接收者/用途/范围/到期/撤销校验和实际交付全部待实现,未支持时明确拒绝,不静默忽略也不因接听而授予转写/图像权限。
先发原callState关联再发邀请,但接收端不能依赖跨回调绝对到达顺序:同一鉴权Topic上的候选邀请最多有界暂存一个、最长到原候选截止;仅在原token、原AI session、localSessionId和callGroupId全部匹配后准入,未关联邀请不抢占AI。普通人工来电仍走普通来电策略,不自动绑定正在进行的AI转人工。
候选等待与媒体协商期间原AI保持运行。本端候选可准备Peer,但不启动第二套物理麦克风采集、不向候选预送AI音频/正文;原采集归属仍是AI。双方原腿的accept、ICE/DTLS、匹配mediaRevision的实际mediaState只是网络屏障,不证明麦克风/扬声器已经移交。第三屏障复用focusControl/focusState:平台再次核原授权、候选代次与截止后,先对原AI实际租约发送完整["microphone","speaker"]组的suspend,收到原token的实际suspended回执,才对原关联本端新人际腿发送同组acquire。共享驱动复用唯一物理采集实例、围栏旧AI转发并实际安装新人际采集/播放归属;只在整组完成后报告acquired,不能把排队、SDP或单轨active作为完成。
平台收到原acquired后还须再次核当前授权、原连接、候选/媒体代次、绝对期限及设备全局CAS,将整组回执和人际路由提交结果持久确认。此后才发送两个人际腿的sessionEstablished,再发送原AI的callState.transferred与sessionEnded。sessionEstablished是最终提交确认,不是触发尚未证实的本地移交。候选在提交前不得转发真实人际音频;原AI模型/会话保留到提交已明确成功,旧AI结束不得关闭已移交的人际驱动或Peer。
已实现三屏障协调核心、完整microphone/speaker仲裁驱动及实际输入票据接口;现行独立桌面焦点宿主仍只装配speaker/display,新共享宿主与后端最终移交尚未闭环,不能声明端云整组移交完成。缺原AI真实租约、缺实际microphone/speaker整组能力、缺唯一共享驱动或缺候选授权关联均不能准入,不凭当前会话补造focusId。通用后端焦点入口只接已established会话;后继专属入口仅可对原已授权escalate账本绑定的prepared候选特批建立前的原焦点请求与回执,且固定原本端腿/呼叫组/连接/能力/代次/截止,不泛化接纳negotiating会话。详情及逐报文见呼叫等待转接与AI转人工:M65起,实际实现与验收范围见支持范围。
失败按阶段处理:尚未实际suspend时,只清候选、原仍授权AI保持运行;已suspend且明确未acquire、路由明确未提交时,复核原AI授权/用户意图/截止与当前CAS,发送原完整组restore,收到实际restored才可呈现AI输入/播放恢复。恢复拒绝或未知不假报active。acquire或路由提交未知时,保留原操作、原字节和截止作有界查询/原token重放,不盲恢复造成双重采集,也不报transferred。路由已经提交后发生本地媒体故障,按新人际失败路径收尾,不擅自回滚已变路由或复活旧AI。原AI自身被撤权或用户结束AI则按原终态结束,取消尚未提交候选,不能借“保留AI”绕过授权。原token重放不新建腿、不续期、不重复切换;旧候选/旧定时器不影响新意图。
callState · SIG↓
- 方向:平台→设备;应答:—。
- 触发、权限与状态:应答或独立事件。held等属于呼叫子状态,业务session仍为established;cancelled随后结束相关呼叫腿。设备主动转接请求不授予目标权限。等待呼叫30秒,转接45秒;候选失败恢复原活动通话,不抢占新通话。
- 转接异步
failed必须关联原requestToken,只表示本次操作失败;原呼叫组与原两会话腿继续,不能据该事件清理原媒体或忙线。人际transfer的transferred后只结束发起方原腿,不结束留存方与候选;AIescalate则保留原设备作为新人工腿参与者,仅在两腿实际切换完成后结束旧AI腿。 - 撤候选成功返回
state=active、原candidateSessionId和reason=candidateCancelled;独立结果事件还关联撤候选请求的requestToken。这不是cancelled呼叫终态,不结束原任一腿;同token回放优先,不以旧候选ID或旧计时器撤新候选。 - 请求失败与呼叫失败分开:原token去重优先于修订检查。过期修订返回409、
reason=staleRevision;接听已先提交(包括媒体仍在协商)或已建立后请求cancel返回409、reason=invalidState。两者均携带当前呼叫控制currentRevision,不返回成功state/revision、不发state=failed、不关闭或改变原呼叫;权限拒绝仍走原鉴权错误语义。 - 公共入口拒绝与上述业务拒绝分开:入口尚未核实原呼叫修订时,沿用
reason=requestConflict等有限公共错误,不填或伪造currentRevision。这类reason-only错误仍关联原session/token,不表示当前呼叫状态改变。 - 超时、幂等、迟到及清理采用本页公共行为和公共约定;成功应答不能代替独立完成状态。
- 场景:呼叫等待转接与AI转人工。
| 字段 | 类型 | 必填条件 | 值与含义 |
|---|---|---|---|
| state | string | 成功应答或独立状态事件必填 | ringing/waiting/held/active/transferring/transferred/cancelled/failed;控制请求被拒绝不填 |
| revision | uint | 成功应答或独立状态事件必填 | 单调呼叫控制修订号;不是mediaRevision |
| reason | string | 失败应答或取消必填 | 固定原因;已核实修订的409使用staleRevision/invalidState,入口沿用公共错误原因;原取消使用callerCancelled,候选取消使用candidateCancelled;设备转接操作失败限定transferRejected/transferTimeout/transferMediaFailed/transferUnavailable/transferRevisionChanged/transferPermissionRevoked |
| currentRevision | uint | 409且reason为staleRevision/invalidState时必填 | 服务器已核实的当前呼叫控制修订号,可为0;拒绝不推进此修订;未知修订的入口错误不填 |
| candidateSessionId | string | transferring/transferred/候选取消必填;failed已分配时携带 | 候选呼叫,不能作为原本端身份 |
| localSessionId | string | 已分配双腿的escalate受理/完成/失败/候选取消必填;其他操作省略 | 适用能力见支持范围:接收者获授权的新humanCall会话腿,非原AI腿、非候选人工腿;请求不能自报 |
| callGroupId | string | 与上述localSessionId同时必填;其他操作不强加 | 适用能力见支持范围:平台持久绑定两个人际腿的组,与两份sessionInvite.callGroupId一致;不授予另一腿身份 |
| requestToken | string | 转接完成、失败或候选取消的独立事件必填;旧控制事件可选 | 原操作token |
escalate分支的条件关联字段不修改旧人际控制应答;未声明对应能力的设备和未支持AI转人工的消费者不能突然收到这些字段或候选邀请。原AI会话上eventSeq继续其现有水位(不重置为1);新两腿各自独立水位。失败示例和完整双腿报文见呼叫等待转接与AI转人工:M48至M64。
此设计复用既有会话方法但不是已实现字段扩展:escalate操作失败复用transferRejected/transferTimeout/transferMediaFailed/transferUnavailable/transferRevisionChanged/transferPermissionRevoked,并明确仅作用于该原操作。撤候选成功仍用active/candidateCancelled,不产生原AI结束。成功切换后旧AI sessionEnded.reason=transferred是本扩展对基础终态契约的条件设计补充,不能推广至任意会话;当前基础终态表未包含该新增分支,生产接线时须同步严格解析器并回归旧消费者,未实现前不向其发送。候选失败使用基础既有userRejected/inviteTimeout/mediaFailed/permissionRevoked/userHangup原因,不创造候选成功或旧AI失败事实。
{
"msgToken": "s13-8",
"method": "callState",
"sessionId": "s13-session",
"data": {
"state": "cancelled",
"revision": 1,
"reason": "callerCancelled"
},
"code": 200
}对应呼叫等待转接与AI转人工:M04;其他操作按条件字段校验。
接听先提交时,同一cancel请求仅收到请求拒绝,调用者如要结束已接听呼叫须另发sessionEnd:
{
"msgToken": "s13-8",
"method": "callState",
"sessionId": "s13-session",
"code": 409,
"data": { "reason": "invalidState", "currentRevision": 0 }
}floorControl · SIG↑
- 方向:设备→平台;应答:floorState。
- 触发、权限与状态:只有获得有效租约的端才能上行并被转发;先到先得,冲突409不排隐式队列。释放、失联或租约到期撤销,平台停转发、设备停采集;续约不改变优先权,半租期续约。PTT属于人际/群组发言控制,不使用AI interactionMode。
- 超时、幂等、迟到及清理采用本页公共行为和公共约定;成功应答不能代替独立完成状态。
- 场景:按键对讲与多人抢麦。
| 字段 | 类型 | 必填条件 | 值与含义 |
|---|---|---|---|
| operation | string | 必填 | acquire/renew/release |
| expectedRevision | uint | 必填 | 当前发言权修订号 |
| floorId | string | 必填 | 会话内抢麦组 |
| leaseId | string | renew/release必填 | 平台授予租约 |
| leaseMs | uint | acquire/renew必填 | 1000至10000毫秒 |
{
"msgToken": "s12-1",
"method": "floorControl",
"sessionId": "s12-session",
"params": {
"operation": "acquire",
"expectedRevision": 0,
"floorId": "room-a",
"leaseMs": 5000
}
}对应按键对讲与多人抢麦:M01;其他操作按条件字段校验。
floorState · SIG↓
- 方向:平台→设备;应答:—。
- 触发、权限与状态:平台应答或撤销事件;即使控制丢失也按租约到期停发。优先级强制抢麦只允许经平台配置的紧急角色,先撤旧租约再发新租约,不能信任payload自报角色。
- 超时、幂等、迟到及清理采用本页公共行为和公共约定;成功应答不能代替独立完成状态。
- 场景:按键对讲与多人抢麦。
| 字段 | 类型 | 必填条件 | 值与含义 |
|---|---|---|---|
| state | string | 必填 | granted/released/expired/denied |
| revision | uint | 必填 | 发言权修订号 |
| floorId | string | 必填 | 组ID |
| leaseId | string | granted必填 | 租约ID |
| holderId | string | granted必填 | 已鉴权参与者 |
| expiresAt | int64 | granted必填 | Unix毫秒 |
| reason | string | denied/expired必填 | 原因 |
{
"msgToken": "s12-1",
"method": "floorState",
"sessionId": "s12-session",
"data": {
"state": "granted",
"revision": 1,
"floorId": "room-a",
"leaseId": "lease-a",
"holderId": "member-a",
"expiresAt": 1900000000000
},
"code": 200
}对应按键对讲与多人抢麦:M02;其他操作按条件字段校验。
更新日志
2026/10/17 03:27
查看所有更新日志
d04e1-docs(AI与音视频): 按公共主线与场景分支整合接入手册于
