Skip to content

About

把多个数据源聚合为一份 Emby 兼容媒体源:源托管、多站聚合搜索、版本合并。零第三方运行时依赖,前端零构建。

Topics

Resources

Contributing

Security policy

Stars

61 stars

Watchers

2 watching

Forks

Repository files navigation

媒体桥面板

媒体桥

把多个数据源聚合成一份可以直接交给播放客户端的媒体源: 来源与站点由插件提供,面板负责跨来源搜索、合并线路,对外提供 Emby 兼容接口。

  • 来源由插件提供 —— 面板不点名任何插件,也不假设插件内部怎么工作:来源、站点、播放地址 都由插件按约定申报,面板只按动作名取用,不关心插件背后的地址与端口。
  • 聚合搜索 —— 一个关键字并发查询多个来源的多个站点,对片名做规范化清洗后按权重打分匹配, 命中与未命中都可查看(含分数与原因)。
  • 版本合并 —— 同一部作品在多处的线路,在客户端里表现为多个可选的「版本」,点哪条播哪条。
  • Emby 兼容 —— 客户端把面板当作一台 Emby 服务器使用(握手、登录、媒体库、搜索、详情、图片、播放、字幕均已实现)。
  • 零依赖 —— 只使用 Node 内置模块(含内置 node:sqlite),没有第三方包,没有构建步骤。

本项目不内置、不分发任何来源或内容。各项来源由用户自行配置,其可用性与合法性由用户判断。

目录

安装

方式一:Docker(推荐)

镜像发布在 Docker Hub:dlushu/mediabridge,同时提供 linux/amd64 与 linux/arm64。

# 8088            面板本身(Emby 客户端**不**连它,连的是下面那组实例端口)
# 8090-8100       面板要用的端口段:**Emby 实例从这里起依次 +1**(每台各占一个)
#                 装不下就把范围往后加(例如再补一段 -p 8101-8110:8101-8110)
docker run -d --name media-bridge-panel --init --restart unless-stopped \
  -p 8088:8088 -p 8090-8100:8090-8100 \
  -v media_bridge-data:/data \
  -e TZ=Asia/Shanghai \
  dlushu/mediabridge:latest

等价的 compose 文件:

services:
  media-bridge-panel:
    image: dlushu/mediabridge:latest
    container_name: media-bridge-panel
    restart: unless-stopped
    init: true
    ports:
      - "8088:8088"              # 面板本身(Emby 客户端不连它)
      - "8090-8100:8090-8100"    # Emby 实例端口:各自从 8090 起依次 +1
    volumes:
      - media_bridge-data:/data
    environment:
      TZ: Asia/Shanghai
      APP_REPO: dlushu/MediaBridge
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  media_bridge-data:
    name: media_bridge-data

启动后打开 http://<主机地址>:8088。

镜像里没有应用代码:容器首次启动时会从 GitHub Release 取一份装到数据卷的 /data/app/<版本>/ 下再运行。默认先经内置的公共 gh 代理取(APP_MIRRORS,见下),取不到再退到官方直连。 之后升级不需要重建容器:在「面板设置 → 关于 → 版本与更新」里手动更新,应用进程会自己重启到新版本。

运行数据与已安装的应用代码都在具名卷 media_bridge-data 里(来源、站点勾选、Emby 账号、面板密码、 配置、应用代码)。备份该卷即可完整迁移。不要执行 docker compose down -v:-v 会一并删除数据卷。

方式二:运行源码

node --version    # 需要 ≥ 22.13(内置 sqlite 从该版本起无需开启实验开关)
npm start

默认监听 0.0.0.0:8088,运行数据写入项目内的 data/。

环境变量

变量 默认 说明
WEB_PORT 8088 面板端口(页面与面板接口)。Emby 客户端不连它,连的是各 Emby 实例的端口
WEB_HOST 0.0.0.0 监听地址
DATA_DIR 项目内 data/(镜像内为 /data) 运行数据目录;应用代码装在它下面的 app/
TZ 跟随系统 日志时间(建议 Asia/Shanghai)
APP_REPO dlushu/MediaBridge 从哪个仓库取应用代码(换成分支/私有镜像源时用)
APP_VERSION 未设置 固定运行的版本;留空 = 用已装版本,磁盘上没有则取最新 Release
APP_SOURCE_URL 未设置 版本包地址模板,占位符 {repo} {version} {tag} {name};支持 http(s):// 与本地路径
APP_CHECKSUM_URL 未设置 .sha256 校验文件地址模板(占位符同上);留空 = 在版本包地址后加 .sha256
APP_MIRRORS https://gh-proxy.com,https://ghfast.top 取源镜像前缀(逗号分隔、有序):面板更新与插件库共用,先逐个试这些公共 gh 代理,再退到官方直连。留空 = 用内置默认;置 off / none / - 只走官方直连。显式设了 APP_SOURCE_URL / PLUGIN_INDEX_URL / PLUGIN_SOURCE_URL 时,对应那条不套镜像前缀
PLUGIN_REPO dlushu/media-bridge-plugins 插件库仓库(owner/repo)—— 插件从它取清单与包(面板本身不带插件,见 ADR-0035)
PLUGIN_INDEX_URL 未设置 插件清单地址;留空 = 走 APP_MIRRORS 候选(含镜像),最后兜到上面那个仓库 main 分支根目录的 index.json;设了就是唯一地址、不再套镜像
PLUGIN_SOURCE_URL 未设置 插件包地址模板,占位符 {repo} {path} {type} {id} {version};留空 = 走 APP_MIRRORS 候选(含镜像);设了就是唯一地址、不再套镜像;支持 http(s):// 与本地路径
PANEL_NOTICE_URL 未设置 「关于」页内嵌公告的取回地址(见 ADR-0068);留空 = 取本仓库 main 分支根目录的 notice.html(走 APP_MIRRORS 候选)。设了就是唯一地址、不再套镜像;置 off / none / - 关闭这张卡

例:想自己指定 gh 代理(或换掉内置的),按先后顺序填 APP_MIRRORS;只走官方直连就关掉它:

  -e APP_MIRRORS=https://gh-proxy.com,https://your-mirror.example   # 逐个试,最后自动退到 github.com
  -e APP_MIRRORS=off                                                # 不走任何镜像,只连官方

关于校验:走第三方代理时,包体与其校验值(应用代码的 .sha256、插件的 md5)都经代理之手, 校验只能挡住传输损坏,挡不住代理替换(详见 ADR-0067)。

快速上手

  1. 登录面板 —— 默认密码 123456;进入后先到「面板设置 → 安全」修改密码。
  2. 装插件(必做,面板本身不带插件)—— 在侧栏「插件 → 插件库」装所需的插件;装时可勾 「装完就启用」,网络不通时也能在「插件 → 管理」页上传本地 .tar.gz 手装。 插件分五类,详见插件分类。
  3. 配置插件 —— 侧栏按类型分栏,点开某个插件就是它自带的设置页;它要什么就在那儿填 —— 取数凭据、账号、站点地址等,各插件各不相同,一律存在插件自己那儿。
  4. 配一套模板 —— 在「聚合设置 → 模板」新建(或选中)一套模板,按来源页签勾选参与聚合的站点, 保存后再到「聚合设置 → 域 → 模板」把哪个元数据域用哪套模板指过去;没指的域,其内容搜不到。 匹配策略与线路过滤详见匹配与线路过滤。
  5. 接入客户端 —— 在「Emby → 实例」页新增实例,在「Emby → 账号」页新建账号,然后在 Emby 客户端「添加服务器」里填该实例的连接地址。详见接入客户端。

不接入客户端也可以先在网页上验证效果:「聚合搜索」搜索片名,结果里每条的「这条的版本」 展示的就是客户端点开该条目时会拿到的东西。

界面导览

左侧是一棵树:一栏一个父节点(点一下收起 / 展开这一栏),栏里的页挂在它下面。

聚合设置
  ├ 模板            建 / 删 / 改模板 —— 站点集合 + 打分过滤参数 + 超时与并发;站点按来源分页签勾选
  ├ 聚合搜索          多来源并发搜索(带打分),每条可查看「这条的版本」
  └ 域 → 模板       哪个元数据域用哪套模板

Emby
  ├ 实例            每台服务器一份:名称 / 端口 / 首页插件 / 连接地址(客户端连的就是这里)
  └ 账号            按实例分(先选实例);客户端里显示的服务器名 = 该实例的名称

插件
  ├ 插件库          从插件仓库里挑插件装 / 更新(面板本身不带插件)
  └ 管理            已装的:装 / 卸 / 启停 / 重启 / 动作调用 / 日志;也可上传本地 .tar.gz 手装

元数据              已启用的元数据插件各占一个子项,点开内嵌打开它自己的设置页
片源                已启用的片源插件各占一个子项
首页                已启用的首页插件各占一个子项
输出                已启用的输出插件各占一个子项
字幕                已启用的字幕插件各占一个子项

面板设置
  ├ 概览            运行环境、面板重启、退出登录
  ├ 设置            缓存设置、站点测速
  ├ 备份与还原      导出 / 还原整份数据
  ├ 安全            修改面板密码、登录态有效期
  ├ 关于            版本与更新、关于
  └ 日志            面板进程的实时日志

「元数据 / 片源 / 首页 / 输出 / 字幕」五栏的子项现算:装好并启用的插件才出现在侧栏,栏里一个插件都没有时整栏不显示。一个包可同时具备多个类型,于是会同时出现在对应的每一栏里。

常见问题

插件分类

  • 元数据插件 —— 条目详情从哪来。
  • 片源插件 —— 去哪儿找片。
  • 首页插件 —— 客户端首页那些媒体库行。
  • 输出插件 —— 把面板已有的首页 / 聚合能力再转给外部客户端。
  • 字幕插件 —— 给版本挂字幕轨、供客户端取用。

一个包可同时具备多个类型,每个类型各带自己那份设置页,于是同一插件会同时出现在侧栏对应的多栏里。 装法:「插件 → 插件库」挑装,可勾「装完就启用」;网络不通时在「插件 → 管理」页上传本地 .tar.gz。 插件仓库地址可用 PLUGIN_REPO / PLUGIN_INDEX_URL / PLUGIN_SOURCE_URL 更换(见环境变量表)。

匹配与线路过滤

在「聚合设置 → 模板」的「编辑」卡片里那一排参数:

  • 打分设置:分数线(填 0 表示不按分数线筛选)、「最多留几条命中」(希望得到几条可用的结果, 不足时按分数继续向后尝试)、「匹配到底」(忽略条数上限,直到凑够或名单结束)。
  • 线路过滤:一个正则,只有匹配的线路名才会进入客户端看到的版本列表。

接入客户端

  • 新增实例:「Emby → 实例」页点「新增实例」,端口留空即可,后端从 8090 起依次 +1。
  • 连接地址:在 Emby 客户端「添加服务器」里填该实例的端口(每行给出的就是连接地址)。 填主机就行:客户端自己会补 /emby,实例监听两种前缀都收;哪个客户端连不上,就改成 http://<面板地址>:8090/api/emby 再试。面板端口 8088 不再提供客户端协议端点 (只留 System/Info/Public 垫片),填它会连不上。
  • 账号:需先在「Emby → 账号」页(先选实例)中新建。
  • 服务器名:客户端内显示的服务器名默认为实例名,可在「Emby → 实例」页的编辑弹窗里改。
  • 全新安装不自动建实例:面板装好后「Emby → 实例」是空的,需自行添加一台; 从老版本升级上来的会沿用老的 emby.db 生成一条 default,不受影响。

客户端里点开条目,版本列表为空或缺少部分线路

面板只列出「可用」的线路:有线路,且定位到了请求的那一集。核对方法:「聚合搜索」搜索片名 → 点击某条的「这条的版本」,可以看到每个来源取回几条线路、哪条定位到了该集;这份内容与客户端拿到的相同。 常见原因是来源里确实没有该集(例如来源只更新到第 210 集),或排在候选前列的条目没有可用线路 —— 后者可在「聚合设置 → 模板」的参数里调大「最多留几条命中」,或启用「匹配到底」。

客户端搜不到作品

客户端的关键字走面板自身的搜索;面板里搜不到即确实没有。若网页「聚合搜索」能搜到而客户端搜不到, 通常是「聚合设置 → 模板」里这套模板没勾这个站点,或「片源」栏里那个插件的实例没在运行 (启停在该插件自己的设置页)。

点击播放无反应或返回 404

面板对播放一律以 302 跳转到插件提供的直链,不代理流量,因此跳转后的地址必须能被客户端访问 (局域网内通常没有问题)。

客户端报错「无法播放 / Source error」但面板日志正常

面板侧日志若已正常回 200(清单)或 302(直链),说明地址已经交给客户端。 后续失败通常是客户端自身的媒体解析器/嗅探器判不出类型(例如 URL 不带 .m3u8 后缀时 ExoPlayer 系把它当普通文件嗅探)或客户端本身不支持该容器。这类问题取决于具体客户端, 面板只能确保下发的地址与类型标识正确。详情见 ADR-0071。

端口与安全

端口 用途
8088 面板本体(页面与面板接口),有密码保护;只额外提供 System/Info/Public 垫片,不是 Emby 客户端要连的端口
8090 起 Emby 实例端口:新建实例时端口留空,就从 8090 起依次 +1(被占了继续往后找)。Emby 客户端连的是这里,用 Emby 账号鉴权(与面板密码是两套)

Emby 实例端口要发布给需要连接的客户端(建议一次发布 -p 8090-8100,不够再往后加); 某个插件若自己还需要额外端口,按其说明另行发布。需要外网访问时,只发布 8088 与相应实例端口, 并置于反向代理与 HTTPS 之后。更多细节见 SECURITY.md。

数据位置、备份与升级

  • Docker 部署:数据与应用代码都在具名卷 media_bridge-data 内 (docker volume inspect media_bridge-data 可查看实际路径),其中应用代码在 <卷>/app/<版本>/。
  • 备份:面板「面板设置 → 备份与还原 → 导出备份」会打出一个 zip,含整份数据 (设置、模板、插件、Emby 账号与播放进度),不含缓存与应用代码;也可以直接备份上述卷。 ⚠️ 备份里含账号密码哈希与插件凭证,请当作私密文件保管。
  • 升级:「面板设置 → 关于 → 版本与更新」→ 检查更新 → 更新到新版本。 面板会下载、校验并安装新版本,随后自己重启(容器不停,几秒后页面恢复)。 更新采用完整替换:新版本启动成功后,旧版本目录会被自动清掉,磁盘上只留当前这一版 (决策见 ADR-0021)。
  • 回退:本地不留旧版本,所以回退 = 把 APP_VERSION 指向要回到的版本再重启容器 —— 引导脚本发现该版本不在磁盘上会重新下载(前提是那个 Release 还在、且这台机器能访问到)。
  • 镜像只在"引导逻辑"变化时才需要更新:docker pull dlushu/mediabridge:latest 后重建容器。

改名

  • 客户端内显示的服务器名 = 该实例的名称:在面板「Emby → 实例」页里编辑该实例。
  • 面板自身的名称:server/core/branding.js 与 public/core/branding.js(两处成对)。

参与开发

提交前请运行 npm run check(语法检查与文风检查)。

仓库只包含应用源码;容器定义与镜像构建脚本不属于项目源码,由维护者另行维护。 分发有两条路:Docker Hub 上的运行时镜像(见上文),以及 GitHub Release 上的版本包 —— 容器启动与面板更新装的都是后者,由 .github/workflows/release.yml 在推送 v<版本> 标签时产出。

许可

AGPL-3.0

About

把多个数据源聚合为一份 Emby 兼容媒体源:源托管、多站聚合搜索、版本合并。零第三方运行时依赖,前端零构建。

Topics

Resources

Contributing

Security policy

Stars

61 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages