HGhub 开发者HPP 1.0 草案

01 · 插件文件与导入

← 总览

1. 插件文件

一个插件就是一个 .js 文件,对应一个数据源或解析器。 没有压缩包,没有附带文件。

文件有且只有两个导出:

导出 说明
export const meta 元信息:一个普通对象(§2)
export default 工厂函数:接收宿主 API hg,返回插件对象(见 02 §3)

1.1 最小示例

export const meta = {
  id: "demo",
  name: "示例源",
  version: "1.0.0",
  protocol: 1,
  description: "一句话简介",
};

export default function (hg) {
  return {
    media: {
      async getDetail({ id }, ctx) {
        const res = await hg.http.fetch({
          url: `https://api.demo.example/series/${id}`,
          responseType: "json",
          signal: ctx.signal,
        });
        return toDetail(res.data);
      },
      async resolvePlayback({ mediaId, episodeId }, ctx) {
        /* … */
      },
    },
    search: {
      async search({ query, cursor }, ctx) {
        /* … */
      },
    },
  };
}

2. 元信息(meta)

字段 必需 说明
id 是 插件的唯一标识。小写字母、数字、.、_、-,以字母或数字开头,≤ 64 字符
name 是 展示名称,≤ 60 字符
version 是 三段非负十进制整数版本(如 1.2.0),各段为安全整数、无多余前导零;不接受预发布与构建后缀
protocol 是 插件面向的协议主版本,当前为 1
description 否 简介,≤ 500 字符
author 否 作者名
homepage 否 主页或反馈地址
updateUrl 否 检查更新时取回新文件的地址(§5.2)
kind 否 source(默认)或 resolver;解析器见 06 §3
matches 解析器必需 主机模式数组,声明该解析器能处理哪些播放页(写法见 06 §3)
defaultHeaders 否 媒体请求的默认请求头,优先级见 05 §7.4
timeouts 否 各类调用的时间预算(秒),上限见 02 §5.2
features 否 数组,声明用到的宿主可选特性(如 ["webview"]),仅供界面提示
requires 否 必需的宿主能力数组:{ type: "feature" | "api", name: string };如 { type: "feature", name: "webview" } 或 { type: "api", name: "html.parse" },缺失时保留文件但不可启用
allowInsecureHttp 否 true 时允许插件使用 http: 地址(接口与媒体);默认只允许 HTTPS
linkDomains 否 主机名数组。用户粘贴这些域名下的链接时,宿主交给本插件的 media.matchUrl 处理(见 06 §2)
mature 否 true 表示含成人内容;宿主默认隐藏这类插件,用户需在设置中开启
settings 否 用户可调的设置项(§2.1)

规则:

插件实现了哪些能力不需要在 meta 里声明:宿主在首次启用时执行工厂、校验能力方法并缓存结果, 再按 02 §6 完成默认线路初始化。初始化完成前不向首页、搜索等业务入口发布该插件。 缓存与插件文件版本及内容修订绑定;同版本覆盖也必须使缓存失效。requires 的兼容行为见 07 §1。

2.1 请求头与时间预算

export const meta = {
  id: "demo", name: "示例源", version: "1.0.0", protocol: 1,
  // 90% 的图片与流都要同一个 Referer,逐条写是噪音,写漏一条就是 403
  defaultHeaders: { Referer: "https://www.example.com/", "User-Agent": "Mozilla/5.0 …" },
  // 上游慢时可以放宽;宿主会夹在上限内(02 §5.2)
  timeouts: { read: 25, playback: 45 },
};

2.2 设置项

settings: [
  { key: "quality", type: "select", label: "默认清晰度", default: "auto",
    options: [{ value: "auto", label: "自动" }, { value: "1080", label: "1080P" }] },
  { key: "preferHevc", type: "switch", label: "优先 HEVC", default: false },
  { key: "apiKey", type: "password", label: "接口密钥" },
]

每项包含 key、type、label,以及可选的 description、default。

type 值类型 额外字段
text 字符串 placeholder
password 字符串(界面掩码显示) placeholder
switch 布尔 —
number 数字 min、max
select 字符串 options: [{ value, label }]

宿主负责渲染设置表单并保存用户的值;插件通过 hg.settings 读取(见 04)。

3. 导入方式

方式 说明
本地 .js 文件 可一次选择多个
本地 manifest.json 按其中的列表批量导入(§4)
URL 下载后按内容识别单个 JS 插件或 JSON 插件列表,支持无扩展名的下载接口
粘贴代码 以 UTF-8 源码导入单个插件;无来源 URL 时需 updateUrl 才能检查更新

URL 路径扩展名与 Content-Type 仅作提示,不作为拒绝依据。宿主先尝试解析为 JSON 插件列表, 否则按 JS 模块读取元信息;识别失败时报告具体错误,不把 HTML 错误页保存为插件。 相对地址以重定向后的最终列表 URL 为基准;下载仍受宿主网络规则与对应文件大小限制约束。

导入单个插件的流程:

取得文件内容 → 读取 meta 并检查必需字段与 protocol → 写入插件目录并记录来源 → 完成

4. 插件列表(manifest.json)

{
  "name": "某某的插件集",
  "description": "可选的说明",
  "plugins": [
    {
      "id": "demo",
      "name": "示例源",
      "version": "1.0.0",
      "description": "一句话简介",
      "url": "demo.js"
    },
    {
      "id": "another",
      "name": "另一个源",
      "version": "0.3.1",
      "url": "https://cdn.example.com/plugins/another.js"
    }
  ]
}
字段 必需 说明
name 否 列表名称
description 否 列表说明
plugins 是 插件条目数组
plugins[].url 是 插件文件地址。可以是绝对 URL,或相对于 manifest.json 自身位置的相对路径
plugins[].id 是 与插件文件内 meta.id 一致
plugins[].name 是 展示名称
plugins[].version 是 与插件文件内 meta.version 一致
plugins[].description 否 简介

规则:

4.1 订阅

从 URL 导入插件列表后,宿主可以把该地址保存为"订阅":之后用户可以一键刷新, 看到列表中新增的插件与有更新的插件。这只是对 §3、§5 的界面包装,不引入新的协议概念。

5. 覆盖与更新

5.1 同 ID 覆盖

导入一个 id 已存在的插件时:

新文件的版本 宿主行为
更高 直接更新
相同 覆盖(方便作者调试)
更低 提示这是降级,由用户确认

覆盖保留该插件的存储、设置与片库记录。新版本的 settings 里不再存在的 key,对应的值被清除; 保留键的值类型或选项已不合法时回退为新默认值。插件更新原子替换文件、使能力缓存失效并重新初始化; 初始化失败时提供恢复上一份可用文件的操作,不回滚插件已经执行的上游操作或存储写入。 使用该插件的活跃播放会话在替换前停止并提示重新播放,避免旧资源混用新代码;检查更新不影响播放。

5.2 检查更新

宿主按以下顺序确定一个插件的更新地址:meta.updateUrl → 导入时的来源 URL → 无(本地导入且未声明,不检查)。

版本比较按数字段逐段进行(1.10.0 高于 1.9.0);不合法的版本号在导入或检查更新时明确报错,不猜测为 0。

5.3 移除

移除插件时清除它的文件、存储、Cookie、缓存与设置。 宿主本地片库中引用该插件的收藏与历史应当保留并标记为"来源不可用",以便重新导入后恢复。