# 缓存直连与失败转发

2026-10-04。已在两个现有项目接入，未发布业务 API、App 安装包或 OTA。Web10/App50 仍按本站及 App 内开播计数，同集当天重播不重复扣次。

## 当前行为

普通视频使用 Media3 或 Apple 系统下载器先直连来源。实际网络、连接超时或指定 HTTP 错误导致失败后，复用同一订单、同一资产及原许可申请转发，不重新扣次、不延长许可。等待 Wi-Fi、空间不足、容量超限、解析及证书错误不会自动转发。转发也失败后停止自动回退，用户可以重试。现有解码器支持的CENC缓存已追加RAM HLS路径，详情见[内存解码缓存](dramivio-decoded-offline-development.md)。

替换下载前保存转发意图，再确认删除失败的直连任务，最后用同一个资产标识加入原生队列。更换地址时丢弃旧的部分文件，避免不同来源的片段混用。响应丢失或重启继续原操作；账号切换、取消和实际删除失败均阻止迟到的新任务。用户点重试时重新读取原生状态，不会删除已经开始的转发任务。

服务端复用现有渠道解析、出网代理、MP4 Range 和 HLS 网关。申请转发只提交 orderId/assetId；私有平台重新检查实际 Better Auth 会话、App 安装批准、订单归属、来源权限和缓存策略。准备阶段只读取地址元数据，普通转发首次资源GET/HEAD才访问上游；CENC转换首次GET才启动，HEAD不读取视频。视频只经过服务器内存，最终缓存文件在 App 本机；没有接入 Redis 或新增业务表/数据库迁移。

## 接口及复用

| 入口 | 用途 |
| --- | --- |
| POST /api/consumer/offline/relay | 将已签发资产交给现有内存网关，不接收客户端视频地址 |
| GET/HEAD /api/consumer/offline/media/… | 请求已有能力对应的 MP4、HLS 清单和分片，每次重新校验原许可 |
| `POST /api/consumer/offline/media/<capability>/release` | 原生终态空通知，仅关闭当前RAM转发；不修改许可/订单或扣次 |
| 私有 readOfflineTransfer(database,args) | 读取原许可与来源信息，不预留、扣次或签发 |
| createOfflineAPI(owner).relay(orderId,assetId) | 现有 App API 中的窄参数请求 |
| createOfflineQueue(deps).tick() | 在已有队列中判断实际失败、保留恢复记录并替换原生任务 |
| 原生 enqueueWithRelay | Media3/AVFoundation 原下载器，要求同 API 地址和受控媒体路径、无来源或登录请求头 |

转发能力和原登录凭据保存在 Go 内存，最多30分钟且不超过原许可/安装批准时间；登录凭据不会返回给下载器或发送给上游。每账号在同一设备最多两条转发，与既有播放共用后台并发上限。关闭转发、修改渠道/代理、取消订单和程序关闭会释放相应内存会话；订单取消同时取消已开始请求所关联的媒体上下文。

当前 runtime11 原生包已包含新队列与转发释放方法；旧二进制没有新方法时，不发起缓存转发请求。react-native-video 补丁仍固定6.19.2，当前包含26个源码文件，并已在干净依赖包验证应用一致。

## 首段转发验证（历史阶段）

以下339/256等为首次转发接入时的历史范围。该段是首次转发接入的历史结果；最新 App371、平台273、runtime11 CENC 三集缓存和注册设备结果见[最新状态](dramivio-development-status.md)与[CENC runtime11 验证](dramivio-cenc-runtime11-validation.json)。[原生终态释放](dramivio-native-release-development.md)。

| 检查 | 结果 | 实际范围 |
| --- | --- | --- |
| 平台全量 | 256/256 | 真实隔离 PostgreSQL、Better Auth 和业务；邮件与安装批准使用夹具 |
| App全量及类型 | 339/339，类型通过 | 实际 API、队列、存储、React 页面；原生和网络为明确适配器 |
| Go/认证/数据库联测 | 通过 | 真实邮箱登录、标准渠道解析、原许可丢失恢复、MP4 Range、HLS 分片、两条上限、禁转发及取消，无第二次扣次 |
| Go相关回归、竞态和构建 | 通过 | 消费者、渠道、代理、内存媒体和 Emby；新 RAM 状态的并发检查及当前程序编译 |
| Android原生 | 32/32 | 实际 Media3、SQLite 和缓存；传输字节为夹具，含网络失败与重启分类 |
| Apple SDK | 185项 | 实际 Foundation/AVFoundation、URL/会话策略和本机文件；不是完整iOS安装包或后台真机下载 |
| 当前代码包与依赖补丁 | 通过 | Android/iOS Hermes导出；干净依赖包应用补丁并逐文件比对 |

覆盖同集原到期时间、响应丢失、重启恢复、取消/换号、物理清理失败、Wi-Fi与空间、不循环回退、API地址/路径/凭据隔离、来源/线路失效释放、共用播放容量和迟到列表操作。计数包含既有回归，不能相加作为独立验收数。本轮由主 Agent 实施并复核，没有新一轮独立子 Agent 复审。

## 边界与后续拆解

1. 用真实标准 API 来源验收直连成功、区域不可达、短期地址失效及 HLS 子请求，记录首帧/下载成功率、直连比例和实际转发字节；不能保证不可达来源仍产生零流量费用。
2. runtime11 Android36 已验收普通及三集 CENC 缓存、断网冷启动、位置补传；物理真机及完整 iOS 仍需验收系统后台、强退、取消中传输、来电和账号切换。Apple SDK 测试不替代 UIKit/React 完整构建与真机；剩余尚未入原生的选集仍由前台 JS 调度。
3. CENC 已沿用既有许可和 RAM 解码路径接入缓存；runtime11 App 已完成隔离 CENC 下载、断网播放和位置补传，真实来源与生产 DRM 仍未验收。
4. 来源 URL 和短时转发 URL 可以被复制到外部程序，均不能当作 DRM。标准 App 先直连；服务端不能独立证明客户端是否真的连接失败。每个资源请求校验身份与许可，单次已开始的长响应没有持续账号轮询；渠道/线路变更、禁转发和订单取消可主动取消媒体上下文。
5. SMTP、实际 App 安装资格与邀请观看证明、正式环境及完整设计状态验收继续按既有任务拆解。Redis 如启用必须关闭视频缓存持久化；当前实现不依赖它。

[当前开发状态](dramivio-development-status.md) · [普通渠道开播](dramivio-site-direct-development.md) · [缓存容量](dramivio-offline-capacity-development.md) · [验证记录](dramivio-consumer-validation.json)
