# RTC API 对接:持续录制、档案、播放与下载 适用 1.0.0.158。一个会议用 `roomId` 标识,一次录制用 `recordingId` 标识;同一会议可以有多次录制。会中主持人或具 `rtc.manage` 的业务 API 可以启停;会后查看使用独立 `rtc.recordings.view/play/download` 权限或该业务后端签发的短时档案票据。入会 RTC Token 不能替代档案票据。 ## 会中:允许、启动、查询、停止 | 接口 | 入参 | 返回与确认 | 权限/特殊情况 | |---|---|---|---| | `PUT /api/v2/rtc/rooms/{roomId}/recording-policy` | JSON `{ "enabled": true/false }` | 房间录制策略 | 会议所有者或超级管理员;**允许录制不等于已经开始**。 | | `POST /api/v2/rtc/rooms/{roomId}/recording/continuous/start` | 房间 ID,无请求体 | `recordingId`、`Starting/Recording`、时间原点 | `rtc.manage`;同房间已有活动任务时返回当前任务,不新开第二份。 | | `GET /api/v2/rtc/rooms/{roomId}/recording/continuous/current` | 房间 ID | 当前任务或空 | 业务后台可轮询;空只表示没有**活动**录制。 | | `POST /api/v2/rtc/rooms/{roomId}/recording/continuous/{recordingId}/stop` | 指定任务 ID | `Stopping`,随后 `Stopped` | `rtc.manage`;`Stopping` 时原轨还在封口,不能立刻下载。 | | `POST /api/v2/rtc/session/rooms/{roomId}/recording/continuous/start` / `.../{recordingId}/stop` | 会中设备 Token;停止带录制 ID | 同一任务状态 | 仅**当前主持人**;主持移交后旧主持人返回403。 | | `GET /api/v2/rtc/session/rooms/{roomId}/recording/continuous/current` | 当前设备 Token | 当前状态或空 | 已准入普通成员也能知道会议正在录制。 | | `GET /api/v2/rtc/rooms/{roomId}/recording/continuous/runs` / `GET /api/v2/rtc/session/rooms/{roomId}/recording/continuous/runs` | 房间 ID、对应业务或档案身份 | 历史任务列表 | 与查询当前活动任务不同;访问范围由档案权限决定。 | 旧 `recording/start`、`recording/stop`、`recording/targets` 是**逐 Publication** 的兼容入口,不应拿来代替整场持续录制。会中原始音视频按现有编码复制到独立轨,不额外生成实时混流;成员/屏幕兼容副本与整场 MP4 在会后处理。静音或断网时段保留真实缺口,不能用旧画面冒充实时画面。 ## 业务后端:按会议签短时档案票据 ```http POST /api/v2/rtc/rooms/{roomId}/recordings/access Authorization: Bearer <业务后端平台会话或 API Token> Content-Type: application/json {"actions":["view","play","download"],"lifetimeSeconds":120} ``` 请求 `actions` 只允许 `view/play/download`,默认 `view+play`,请求 `play` 或 `download` 时服务端也加入 `view`;有效期限制 30–600 秒,默认 120。响应包含 `token`、`roomId`、实际 `actions`、`expiresAtUtc`。签发者不能授予自己没有的权限,使用时继续复核原会话/API Token、账号、权限和会议范围。将短票据交给获准客户端,长期管理 Token 留在业务后端。 | 动作 | 权限 | 能做什么 | 不能做什么 | |---|---|---|---| | `view` | `rtc.recordings.view` | 列表、清单、公开事件、附件预览 | 不能播放媒体或下载 ZIP。 | | `play` | `rtc.recordings.play`,同时需 `view` | HTTP Range 播放本次录制文件和整场 MP4 | 不是下载授权。 | | `download` | `rtc.recordings.download`,同时需 `view` | 下载本次文件、附件、ZIP 与整场 MP4 | 不包含其他会议或私聊内容。 | 票据查询用 `Authorization: Bearer <档案票据>`;资源返回的短时 URL 中可能带 `rtc_archive_token`,只用于获准的只读路径,过期后重新签发,禁止公开转发。`rtc.manage` 管理员具备管理路径,但业务终端只拿最小档案动作。 ## 查询任务、时间线和设备 | 接口 | 入参 | 返回 | 特殊情况 | |---|---|---|---| | `GET /api/v2/rtc/recordings` | `roomId`、`search`、`state`、`fromUtc/toUtc`、`participantId/deviceSessionId`、`page/pageSize` | `total/page/pageSize/items[]`,每项含 `recordingId`、状态、开始时间、人数/设备数 | 页大小 1–100;时间过滤录制开始时间左闭右开;授权、筛选先于计数和分页。 | | `GET /api/v2/rtc/session/rooms/{roomId}/playback/recordings/{recordingId}/manifest` | `afterSequence`、`maxEvents` | `originAtUtc`、`durationMilliseconds`、`tracks[]`、`composites[]`、`events[]`、`hasMoreEvents/nextSequence` | 每页事件可能不完整;按 `nextSequence` 续读。文件偏移和事件偏移共用原点。 | | `GET .../full-exports` | `recordingId` | 每次导出的 ID、区间、状态、文件 | `Pending/Running/Failed` 不应出现假播放链接。 | 上述 `GET .../full-exports` 的完整前缀为 `/api/v2/rtc/session/rooms/{roomId}/playback/recordings/{recordingId}`。`tracks[]` 按 `participantId + deviceSessionId + mediaKind` 分路;同一成员换机可有多台设备,设备会话不是硬件 ID。`events[]` 包含服务端允许回放的公开聊天、白板、控制和设备发言事件。私发消息/附件不会因主持身份自动变公开;旧客户端或旧任务缺事件时显示“未知”,不要推断历史。 ## 媒体、附件、ZIP 与整场导出 以下读取接口共享前缀 `/api/v2/rtc/session/rooms/{roomId}/playback/recordings/{recordingId}`,均会复核文件/附件是否确实归属本次会议和录制。 | 方法与后缀 | 所需动作 | 返回/用途 | 特殊情况 | |---|---|---|---| | `GET /files/{fileId}/media` | `play` | 原轨或成员副本,支持 HTTP Range | 播放器保存当前位置;短票据过期时换 URL。 | | `GET /files/{fileId}/download` | `download` | 指定文件附件响应 | 不能用猜到的 `fileId` 读其他任务。 | | `GET /attachments/{attachmentId}/content` | `view` | 本次公开图片、视频、PDF或文本预览 | 其他类型可能返回415;私聊或区间外引用不可见。 | | `GET /attachments/{attachmentId}/download` | `download` | 获准公开附件下载 | 附件仍按原会议可见范围检查。 | | `GET /package` | `download` | 本次原轨、成员/屏幕副本、公开事件及附件 ZIP | 大包流式返回;不可用附件在清单中说明,不伪造文件。 | | `GET /full-exports/{exportId}/media` / `/download` | `play` / `download` | 已完成的固定布局 MP4,播放支持 Range | 只有 `Available` 的整场导出可读取。 | 业务后台按需排队整场导出: ```http POST /api/v2/rtc/rooms/{roomId}/recording/continuous/{recordingId}/full-exports Authorization: Bearer <具备 rtc.manage 的业务 API Token> Content-Type: application/json {"startMilliseconds":0,"endMilliseconds":60000} ``` 起止是相对录制原点的毫秒,`start < end` 且不能越过有效范围;返回导出任务 ID 后查询状态。失败的会后成员/屏幕副本和整场导出分别有 `.../composites/{compositeId}/retry`、`.../full-exports/{exportId}/retry` 管理入口,重试需仍有原轨和授权。整场导出完成后再取得可播放成品。 ## 失败处理 | 结果 | 处理 | |---|---| | 401 | 票据过期、签发者源凭据撤销;从业务后端重新取得,不使用 RTC 入会 Token。 | | 403 | 缺动作或当前用户无此会议档案权限;停止重试并请求授权。 | | 404 | 会议、录制、文件、附件不属于同一可见范围;重新查列表和清单。 | | 415 | 不支持站内预览的附件格式;有 `download` 权限时走下载入口。 | | `Starting/Recording/Stopping` | 会中任务状态,`Stopping` 后继续等 `Stopped` 和文件索引。 | | `Pending/Running/Failed/Available` | 副本或导出状态;只把 `Available` 作为可播放产物。 | 无 UI 的 Web、Android、iOS、UniApp 档案函数和回放设备发言的使用方法见[档案 SDK 参考](../sdk/archive-api.md)。