# 自定义渠道

本文记录首轮已实现的标准API渠道契约及过渡管理入口。管理员从当前Web“更多 → 渠道管理”添加标准JSON API；普通账号不能修改配置。最终按[设计实施路线](dramivio-existing-project-plan.md)迁入成熟开源后台，用户端自动聚合、不提供频道范围步骤；不以原后台存在为理由删掉设计要求。

## 接入字段

| 字段 | 说明 |
| --- | --- |
| 名称 | 仅用于运营识别；最终用户页面不出现供应商名或频道范围筛选 |
| 根地址 | 公共HTTPS域名的根地址，仅443端口；不带账号、查询参数或路径，创建后固定 |
| 目录路径 | 默认`/catalog`，创建时可设置为`/v1/catalog`等同域相对路径，创建后固定 |
| 详情路径 | 默认`/dramas/{id}`，必须有且只有一个`{id}`，创建后固定 |
| 启用 | 参与合法账号的目录、搜索与播放；关闭后服务端限制旧数据与媒体请求 |
| proxyRouteId | 可绑定后台自定义出网线路；空值表示服务器直连，用户仍访问网站媒体网关；修改必须带原revision |

首版格式`json-api-v1`是明确契约，并不代表任意第三方JSON返回结构都能直接识别。首版不支持上游Cookie、Bearer/API密钥配置或后台执行脚本。指定网站需要按该站真实接口增加独立适配器及测试。

[代理线路与无落盘转发](dramivio-proxy-relay.md)补充HTTP(S)/SOCKS5线路管理、目录/详情/封面/HLS密钥范围、版本撤销和流量复用。代理凭据与上游API凭据是不同能力；添加出网代理不自动提供源站Cookie或任意请求头。网站视频只流式转发或短期RAM缓存，新建和恢复服务器下载/合并关闭，App本机缓存另行授权。

## 目录

请求：`GET /catalog?page=1&pageSize=50&q=关键词`。`q`在搜索时提供；每页最多50条，响应最多2MB。剧ID必须稳定且只含字母、数字、点、下划线、短横线或波浪线，不能把剧名当ID。

```json
{
  "data": [
    {
      "id": "drama-001",
      "title": "样例短剧",
      "coverUrl": "https://cdn.example.com/cover.jpg",
      "intro": "剧情简介",
      "episodeCount": 2,
      "tags": ["悬疑"],
      "category": "悬疑",
      "releaseStatus": "finished"
    }
  ],
  "hasMore": false
}
```

空目录应返回`data:[]`、`hasMore:false`。分页重复或到达本轮抓取预算时停止，保留已读数据并报告部分更新，不能把部分目录当成全库完成。

## 详情与集数

请求：`GET /dramas/drama-001`。

```json
{
  "id": "drama-001",
  "title": "样例短剧",
  "episodeCount": 2,
  "chapters": [
    {"id": "episode-001", "episode": 1, "title": "第1集", "videoUrl": "https://cdn.example.com/001.m3u8"},
    {"id": "episode-002", "episode": 2, "title": "第2集", "videoUrl": "https://cdn.example.com/002.mp4"}
  ]
}
```

详情ID必须与请求一致，集ID和集号不可重复。视频、分片、密钥和重定向必须符合公共HTTPS访问规则。是否支持特定编码/加密/下载格式仍由现有媒体引擎验证；填写URL不等于取得内容许可或具备DRM能力。

## 修改、停用与归档

服务端生成不可复用的`custom-...`渠道ID。编辑、启停、归档均携带读取时的`revision`；过期版本返回409，不自动覆盖。后台保留输入，可读取最新配置后重做修改。

名称和启停可修改；根地址、目录路径、详情路径创建后固定，更换接口须归档旧渠道再创建新渠道。停用可重新启用；归档不可重新启用，旧剧目和观看事实保留，不能把旧ID重新指向另一个渠道。配置保存到独立`data/channels.json`；备份应包含该文件，配置损坏时接口报错并保留原文件。

渠道存储按服务实例隔离；本地JSON方案只支持当前单进程写入，不把多个实例同时挂一个目录当成分布式配置。内置原站源仍保留；账号权限由服务端收敛，新源不自动绕过被限制账号的授权范围。

## API

- `GET /api/ui/admin/channels`：管理员配置列表。
- `POST /api/ui/admin/channels`：新建或更新。
- `POST /api/ui/admin/channels/test`：测试未保存草稿的目录连接/格式，返回样例；这不是视频播放验收。
- `POST /api/ui/admin/channels/archive`：归档。

沿用现有管理员会话、浏览器身份和同源防护，不以客户端的管理员字段或渠道请求头授予权限。测试、目录与媒体实际网络连接均检查公共地址，防止重定向/DNS将请求导向内网。

自定义渠道的原始MP4/HLS经服务端受控网关交给原生播放器。停用会关闭服务端播放会话及相关任务，限制后续请求，不能抹去已缓冲的片段。已经下载到手机的本地文件仍可能离线播放，本轮不包含离线许可证撤销或DRM。App观看记录目前沿用设备观看身份，保存每剧最后观看的集号和位置，不等于永久逐集观看事实或邮箱账号跨设备同步。

新App以`mode:proxy`和`client.native:true`申请媒体，避免原生网络栈把Cookie随CDN跳转转发。原生媒体流量经过Go服务，需按带宽容量部署；不支持HLS Content Steering。发布时先关闭旧客户端使用的内置直连策略，再升级Go，最后升级App。旧Go严格解析客户端字段，未识别`native`时返回400，不能先单独发布新App。新Go对缺少该标记的旧客户端保留原协议，旧App仍须更新。

## 验证

Go测试覆盖配置、权限、持久化、版本冲突、目录/详情、分页、撤权与请求安全；Web测试覆盖表单和动态清单。App仍需真机验证渠道刷新、长按取消和弱网播放。没有真实上游时只确认契约fixture，不能声称所有外部源已可用。
