HGhub 开发者HPP 1.0 草案

07 · 生态与演进

← 总览

1. 版本与兼容

1.1 版本号

1.2 次版本只做增量

同一主版本内,新的次版本只能:

由此得到双向的兼容规则:

一方 必须做到
插件 忽略 params 里不认识的字段;用 hg.env.features 与"方法是否存在"探测,而不是比较版本号
宿主 忽略 meta 与返回值里不认识的字段;插件未实现的可选方法按"不支持"降级;未知错误码按 INTERNAL 处理

增量扩展保证旧插件可继续在新宿主运行;新版插件在旧宿主上运行的前提是它为新增能力提供了有效降级。 “主版本相同”不代表宿主拥有插件需要的一切功能。

1.3 必需能力与降级

1.4 主版本

破坏性变更(删除或改变既有字段的语义)才升主版本。 宿主应当在升级主版本后继续支持上一个主版本的插件一段时间,并在插件列表里标注"面向旧版协议"。

2. 对标与取舍

参考了三个以插件为核心的开源项目(结论来自阅读其源码与文档):Cloudstream(视频,Kotlin 插件)、 Venera(漫画,JS 插件)、Miru(番剧 / 漫画 / 小说,JS 插件)。

设计点 Cloudstream Venera Miru HPP 的选择
插件单元 编译后的字节码包,需要 Gradle 工程构建 单个 .js,class X extends ComicSource 单个 .js,注释头元信息 + export default class 单个 .js,export const meta + 默认导出工厂函数
元信息读取 包内清单 + 仓库索引 正则找类名后执行,读实例字段 正则扫描整个文件里的 @key value 结构化对象,可带设置项;不靠正则
批量索引 仓库文件指向若干插件列表文件 任意地址的 JSON 列表 <仓库>/index.json manifest.json,支持相对路径与 URL
更新 启动时比对版本并自动更新 比对索引版本后重新下载 无完整的更新路径 比对版本,来源地址或 updateUrl 取新文件
执行环境 与应用同进程、同权限,可调用应用的任何接口 QuickJS,所有插件共用一个引擎 不同平台用不同引擎,各有一套桥接代码 统一引擎实现,每插件独立 runtime、上下文与调度,只能经 hg.* 与外界交互
超时 / 内存上限 协程超时(默认 120 秒,插件可调);无内存上限 无 无 有(02 §7)
宿主如何调用插件 直接的方法调用 生成 JS 源码执行 把参数拼进源码字符串 参数走结构化的桥,不拼源码
网络 插件自带 HTTP 库直接联网 宿主 HTTP 封装 + 全局 fetch this.request,另可启用绕过封装的 fetch 只有 hg.http,统一经宿主网络层
分页 页码 页码 + 最大页,或 next 令牌,两套方法 仅页码 统一的不透明游标
首页 插件声明若干分区,逐区分页,可标注横版图 探索页:分区页 / 列表页 / 混合 仅"最新"列表 home 分区(可分页、可标注横版图)+ 独立的 feed
播放解析 回调式地流出一批链接;按视频托管站拆出可复用的解析器 取章节与逐图加载配置分离 新版把"列出镜像"与"解析镜像"分离 servers 列出播放线路,resolvePlayback(serverId) 按需解析;托管商解析器独立成插件,按主机模式路由
登录 数据源接口没有统一的登录流程 账号密码 / 网页 / Cookie 三种;约定抛字符串 Login expired 网页登录后写 Cookie 表单流(可多步)+ 可选网页视图;类型化的 AUTH_EXPIRED
设置 插件自绘原生设置界面 插件内声明,含回调型按钮 运行时注册 meta.settings 静态声明
界面能力 插件可直接操作原生界面 插件可弹消息、对话框、输入框 无 插件不绘制界面(见 §6 开放问题)
聚合 搜索时并行查询各插件,按来源分组 — — 同左,另有按标题与年份匹配的换源
作者支持 强类型语言 + 内置的冒烟测试工具 仅 JSDoc 桩文件 仅文档里的接口描述 计划提供类型定义、假宿主与内置自检

2.1 借鉴的做法

2.2 避开的坑

坑 出处 HPP 的做法
插件与应用同进程同权限,出现过插件弹出广告跳转、拉起其他应用 Cloudstream 插件在独立引擎里,没有界面与系统接口,结构上做不到
索引里的类型字段是自由文本,出现拼写不一致的值 Cloudstream 枚举校验,不认识的值按 other 处理
接口版本号字段存在但不生效,不兼容要到运行时报错才暴露 Cloudstream 导入时检查 meta.protocol;运行时用特性探测
所有插件共用一个引擎与全局对象,一个死循环卡住全部,插件能读到彼此的数据 Venera 每插件独立 runtime、执行调度与存储
没有调用超时与内存上限 Venera、Miru 截止时间、内存上限、崩溃后停用
把调用参数拼进 JS 源码,搜索词里的引号即可破坏调用 Miru 参数经结构化的桥传递
不同平台使用不同引擎,维护两套桥接,个别平台不可用 Miru 单一可嵌入引擎
用正则在全文件里取元信息;必填字段缺失时直接崩溃 Miru 结构化 meta;缺字段给出明确的导入错误
监视插件目录自动重载,出现插件"丢失""显示未安装" Miru 导入、更新、移除都是显式操作
没有更新路径 Miru 版本比对 + 明确的更新地址
文档与实现的字段名不一致 Venera 类型定义文件作为唯一事实来源,文档由它对照
约定抛特定字符串表示登录失效 Venera 类型化错误码

3. 客户端实现基线

HGhub 0.0.1 是保留既有前端风格的新插件视频播放器,不延续旧平台业务,也不迁移旧账号与片库。

完整目标见 08,实际已完成范围见 实现进度。

4. 实现要点(非规范)

5. 路线图

阶段 内容 完成标志
P0 协议类型与校验、假 hg、虚构 JSON/HTML 源及依赖 Cookie 的源与解析器夹具;独立 runtime、取消与预算;hg.http/storage/cookies/log/crypto/codec/html;本地导入、初始化与 endpoints;media/search/resolver;媒体会话、HLS 与 progressive 虚构链路跑通导入 → 能力/线路初始化 → 搜索 → 详情 → 播放 → 刷新;验证取消、MP4 拖动、HLS 密钥与解析器资源归属;五端验证核心传输,完成后冻结核心 1.0 契约
P1 全新的插件片库;feed/catalog/comments/interact/auth/ui、封面变换;插件页、基础日志、自检;移除宿主站点知识 点播功能经外部插件使用,多来源主键已就绪;公开树与发布产物无真实上游知识
P2 manifest.json 与任意 URL 导入、更新检查、订阅;home 与综合编排;分类分栏、搜索范围与聚合展示;移除独立排行榜 同时启用多个插件,失败互不拖累;同版本覆盖、升级、降级及播放中延后自动更新可用
P3 换源与来源关联、季集匹配;articles/library/progress/updates;网络请求面板与完善的作者文档 换源保留旧来源与进度,不错配季集;作者可依据类型和虚构样例独立实现插件
P4 live、纯直播源路径;可选 hg.webview;声明支持的 DASH 与分片变换;跨端能力验收 频道播放/刷新、网页登录和所声明可选特性通过目标平台验收,完成 1.0 能力实现

这些阶段是实现顺序,不表示可以把未实现模块对外声称为已支持。冻结后发布为完整 1.0 的宿主必须满足所有必需契约; P0 至 P3 的中间构建标注为开发版。可选特性仅在实际实现并通过验收后声明。

5.1 P0 验证资产

虚构示例只连接本地测试夹具或保留示例域名,使用虚构 ID、密钥和响应,不提供任何真实影视来源。 测试夹具通过测试配置放宽本地地址策略,不改变生产默认网络规则。协议示例不是面向用户分发的内容插件。

至少覆盖:JSON 点播源、HTML 点播源、需 Cookie 的数据源 → 独立解析器、首次 endpoints 无选择、 同插件交错调用与取消、运行时超额重建、分页恢复、HLS 子资源归属、Range、有效期刷新与插件更新使旧会话结束。 类型定义与返回值校验同步维护;类型能编译不代替实际媒体链路验收。

6. 候选扩展与开放问题

6.1 1.0 之后的候选

方向 说明
网页视图提链 宿主在后台加载播放页并截获其中的媒体请求,把地址交还插件。Cloudstream 以此应对难以还原的页面脚本;五端的实现成本高,需单独评估
一键导入链接 注册应用链接(如 hghub://import?url=…),网页上点一下即可导入插件或插件列表
体验增强类数据源 弹幕、字幕库、影视资料、观看记录同步
阅读类内容 漫画、小说;需要新增一组能力,文件格式与运行时不变
下载 1.0 不要求下载界面;后续复用媒体会话、解析链和刷新语义,不假定一个静态 URL 足够完成长时间下载

6.2 开放问题

问题 现状 备选
逐请求的媒体钩子 只有静态请求头与字节变换 允许插件对每个分片请求动态改写地址或请求头(Cloudstream 有此接口);代价是播放期间高频唤醒插件
独立音轨 依赖 HLS / DASH 清单自带的音轨 在 PlaybackInfo 里增加外挂音轨列表
调用中途的用户输入 不支持:插件在方法执行期间不能弹窗提问 用插件页的表单(ui)或网页视图;若确实需要,可让 INTERACTION_REQUIRED 携带一个表单
令牌的存放 插件级明文存储,认证范围由插件决定 系统安全存储作为后续可选能力,不作为重构前置要求
限速默认值 API 默认 5 次/秒,突发 15;媒体独立排队 根据真实运行调优宿主策略,不改变协议固定数据契约