Emby添加网盘挂载路径并使用302直链播放
本文由 简悦 SimpRead 转码, 原文地址 invites.fun
由于 bpking1/embyExternalUrl 仓库一直在更新,本教程可能过时,如果你在使用过程中遇到问题,欢迎提出来大家一起交流。
前言(过于啰唆,请直接跳过)
传统 NAS 上播放网盘媒体文件的模式,可能有:
- alist 里添加 115 / 阿里网盘,rclone 将 alist 以 webdav 方式挂到 NAS 的某个路径上,当作本地盘。然后 emby/plex 的媒体库路径填写网盘挂载路径。
- clouddrive2(简称 cd2)里添加 115 / 阿里网盘,然后 cd2 挂载到 NAS 某个路径上,同样当作本地盘,然后添加到 emby/plex 的媒体库路径。
这种方式的缺陷:
当你在外网播放网盘文件时(假如你的媒体服务搭好后,向一些朋友分发了账号),NAS 向通过 cd2/alist 的链接来将网盘资源(流式)下载到 NAS 上,然后通过 NAS 上传到你的外网设备中。假设你的宽带上传只有 30Mbps,那么基本上是没法外网流畅看较高码率的 4k 影视的。
说人话就是:外网播放 NAS 上挂载的网盘资源,会占你上传带宽(以及下载带宽),可能导致播放不流畅。
考虑到 alist 对一些网盘支持 302 重定向(可以通过访问https://alist公网域名/网盘路径/xxx/网盘媒体文件.mkv,来重定向到阿里 / 115 网盘对应文件的直接链节),可以实现流式访问网盘文件时,不占用 NAS 上的带宽(宏观上是不吃 NAS 的下载和上传带宽的),只消耗访问该 alist 链接的外网设备的下载带宽。
有大佬受此启发,想到,如果外网设备使用 emby/plex 播放/cd2挂载路径/115/xxx/网盘媒体文件.mkv时,可不可以劫持媒体文件资源请求,并进行修改。如去除多余的前缀(即/cd2挂载路径字符串)并拼接 alist 的公网地址,变成https://alist公网域名/网盘路径/xxx/网盘媒体文件.mkv。这样,当播放 emby/plex 上所有路径以/cd2挂载路径开头的媒体文件时,发送的资源请求被劫持,转到 alist 的 302 直链上去了,从而达到了不占用 NAS 带宽的效果。
在类似的思路下,bpking1、chen3861229 等大佬开发了 embyExternalUrl 工具,其作为一种 emby/plex 的外置脚本(或者说工具?插件?),基于nginx服务器配合JavaScript脚本,来有条件地劫持并修改播放器客户端对 emby/plex media server 的请求,从而实现外网设备播放媒体文件时,去访问网盘的直链地址来进行流式传输,达到不额外占用 NAS 带宽的效果。
教程开始
准备
- 已经部署了 emby/plex media server 两者中的一个,无论是 docker 方式还是 “套件” 方式部署。下文以部署的 emby media server 为例,端口为 8096,并获取其 api 密钥。
- 已经部署了 alist,并按照 alist 官方文档添加了 115 网盘、阿里网盘等支持 302 重定向的网盘之一。下文以 115 网盘为例,并在 alist 中的挂载路径为
/115,如下图:

并在后台管理 -> 设置 -> 其他,获取 alist 令牌,备用。 - 使用 clouddrive2 或者 rclone 来挂载网盘到 NAS 某路径下。
- 可以使用 rclone 以 webdav 方式挂载 alist 到本地 NAS 路径
上,如/mnt/alist_webdav。那么 115 网盘中的媒体文件路径可能是/mnt/alist_webdav/115/xxx/网盘媒体文件.mkv。 - 这里有条件的可以使用 cd2,再重新添加一边 115 网盘,进行两次挂载。(alist 里添加 115 网盘时, Qrcode 源选不常用的设备,如 Tv;cd2 里添加 115 网盘时,用扫码即刻,这样防止两者相互挤掉)。
- 可以使用 rclone 以 webdav 方式挂载 alist 到本地 NAS 路径
emby2alist 的使用
去仓库 bpking1/embyExternalUrl 下载源码,关注emby2Alist文件夹结构:
~/emby2Alist
├── docker // 创建容器脚本文件夹
| ├── docker-compose.yml // docker-compose 脚本,根据自身情况修改
| ├── nginx-emby.syno.json // 群晖 docker 脚本,根据自身情况修改
| └── nginx-jellyfin.syno.json // 群晖 docker 脚本,根据自身情况修改
└── nginx // nginx 配置文件夹
├── conf.d // nginx 配置文件夹
| ├── api // JS 脚本文件夹,完全不用改
| ├── cert // SSL 证书文件夹,根据自身情况修改
| ├── common // 通用工具类文件夹,完全不用改
| ├── exampleConfig // 示例 constant 配置文件夹
| ├── includes // 拆分的 conf 文件夹,http 和 https 端口在这改
| ├── constant.js // 常量主配置文件,根据自身情况修改
│ ├── emby-live.js // 直播相关脚本,完全不用改
│ ├── emby-transcode.js // 转码相关脚本,完全不用改
│ ├── emby.conf // emby 配置文件,根据自身情况修改,注意 https 默认被注释掉了
│ └── emby.js // 主脚本,完全不用改
└── nginx.conf // nginx 配置文件,一般不用改
由于我曾是 Ubuntu 用户(保留了一些特别癖好),喜欢 compose 文件与对应的配置在同一级目录,因此,拷贝xxx/emby2Alist/docker/docker-compose.yml到xxx/emby2Alist/compose.yaml,删掉 docker 文件夹,变成这样的结构:
emby2Alist
├── compose.yaml
├── nginx
│ ├── conf.d
│ │ ├── api
│ │ ├── cert
│ │ ├── common
│ │ ├── constant.js # 待修改
│ │ ├── emby.conf # 需要https才修改
│ │ ├── emby.js
│ │ ├── emby-live.js
│ │ ├── emby-transcode.js
│ │ ├── externalUrl.js # 修改emby外网地址即可
│ │ ├── exampleConfig
│ │ └── includes
│ ├── log # 该目录仅在容器建立后生成
│ │ ├── access.log
│ │ └── error.log # 可查看劫持日志
│ └── nginx.conf
└── README.md
我打包了一份 commit 为 0ca1943 的修改后的文件,方便朋友们直接下载使用,链接为:https://zmgg.lanzout.com/iTNrJ1yv72zg。下载该压缩包后,解压后按照如下步骤修改:
1. 修改nginx/conf.d/constant.js

-
embyHost,你的 emby media server 部署地址,如果 compose.yaml 里的 network_mode 不是 host,这里要改成 docker 网络的网关,ifconfig docker0获取,如桥接模式下填http://172.17.0.1:8096。 -
embyMountPath,图里写的/mnt,表示/mnt开头的媒体资源被访问时发送的请求会被劫持并修改。由于我的 emby server(docker 方式部署)中,进行了如下映射,所以填/mnt:volumes: - xxx:xxx - /mnt/alist_webdav/115:/mnt/115:rslave - /mnt/alist_webdav/aliyun:/mnt/aliyun:rslave -
embyApiKey、alistAddr、alistToken、alistPublicAddr根据自身情况修改 -
alistSignEnable是填 true 还是 false,根据 alist 添加网盘时是否启用签名来定:

2. 修改nginx/conf.d/externalUrl.js
修改其中的serverAddr = 'https://emby.xxx.com';即可。如果没有搞反代,这里似乎可以留空serverAddr = ''。
这样就整合了embyAddExternalUrl的功能:在电影 / 电视的海报页底部,添加了一排调用第三方播放器的入口,如:

3. [可选] 修改nginx/conf.d/emby.conf
如果你想配置反代,用emby.xxx.com域名绑定到该服务上,反代 http 端口 8091 就足够,这一步可以跳过。
该 docker 服务部署后,默认是暴露 http 协议下的 8091 端口的。也就是说你的 emby 服务器地址通过http://192.xxx.xxx.xxx:8091访问即是需要使用 emby2Alist 这一外置工具来处理 emby media server 接收到的请求。如果你的播放器客户端继续填http://192.xxx.xxx.xxx:8096,那就相当于使用原来的 emby 服务,不使用 emby2Alist 来处理请求。
如果你想通过https://192.xxx.xxx.xxx:8095或者https://ip.yourdomain.com:8095,即不配置反代的条件下通过 https 来访问,你需要把一份证书放到cert文件夹下,并按照nginx/conf.d/includes/https.conf里的代码提示,你需要改名为:

并取消nginx/conf.d/emby.conf中的如下注释:

4. 创建并启动容器
完成上述修改后,创建容器就行了。如果你是威联通 / 群晖等 NAS,如果不支持 compose.yaml 里填写相对路径,请把 compose.yaml 挂载目录里的相对路径改为绝对路径。
启动容器后,有强迫症的可以在终端下输入netstat -lntp |grep 809,查看是否有 8091 或 8095 端口服务(必有 emby media server 的 8096 端口):

测试
容器正常启动后,使用 emby 播放器客户端,通过主机http[s]://ip或域名,端口8091(如果你配了反代,那就是主机https://域名,端口443)来连接 emby media server。
进入后台设置,创建一个媒体库,文件夹添加 cd2 挂载到本地的网盘里的路径,如/mnt/alist_webdav/115/电影。这里最好找一个影视数量少的网盘路径做个测试,防止 emby2alist 配置的有问题,而影视又过多,进行大量的刮削,导致 NAS 非常卡。
等慢慢刮削完后,点击播放视频,查看日志tail -f /emby2Aist容器路径/nginx/log/error.log,若出现如下信息,则表示直链播放成功:

该图表明,在播放/mnt/115/电视/欧美剧/纸牌屋 (2013)/Season 01/House.of.Cards.S01E01.2013.1080p.Blu-ray.x265.10bitxxxx.mkv媒体文件时,emby2alist 将改资源路径,移除掉了首部的/mnt(即上述填写的embyMountPath),得到/115/电视/欧美剧/纸牌屋 (2013)/Season 01/House.of.Cards.S01E01.2013.1080p.Blu-ray.x265.10bitxxxx.mkv,然后拼上 alist 的公网地址,变成了https://alist.xxx.com/d/115/%E7%94%B5%E8%A7%86/%E6%AC%A7%E7%BE%8E%E5%89%A7/%E7%BA%B8%E7%89%8C%E5%B1%8B%20(2013)/Season%2001/House.of.Cards.S01E01.2013.1080p.Blu-ray.x265.10bit.xxxx.mkv(没有仔细研究源码,姑且这么粗暴解释吧)。
有的朋友不想看日志,通过观察 cd2 的下载列表来判断是否走了直链,如果 cd2 里没有属于对应资源的下载,且 emby 可以正常播放,那就是走了直链。
配合 Auto Symlink 使用
由于直接让 emby 刮削网盘挂载的媒体文件,实在是太慢了,因为 emby 刮削网盘文件需要将媒体文件的一部分内容下载到本地,然后再读取视频元数据(获得该视频的内封字幕、码率信息、音频信息等)。对于视频库大的朋友,第一次入库刮削,下载带宽压力可能会有点大。幸运的是,emby 支持 strm 文件的读取,因此一些大佬提出使用 strm 文件来替代大文件来让 emby 刮削。
本节所介绍的 Auto Symlink 工具便是一个自动为网盘挂载后的路径自动生成对应 strm 文件的工具。
安装
docker compose 方式部署:
version: "3.3"
services:
auto_symlink:
container_name: auto_symlink
environment:
- TZ=Asia/Shanghai
volumes:
- /mnt/alist_webdav/115:/mnt/115:rslave
- /mnt/alist_webdav/aliyun:/mnt/aliyun:rslave
- /data/disk0/02strm:/strm
- ./config:/app/config # 有的系统左边可能需要填绝对路径
ports:
- 8095:8095
user: 0:0
logging:
options:
max-size: 10m
max-file: 3
restart: unless-stopped
image: shenxianmq/auto_symlink:latest
networks: {}
对挂载路径的说明:
- /mnt/alist_webdav/115:/mnt/115:rslave
- /mnt/alist_webdav/aliyun:/mnt/aliyun:rslave
# 上面两行与我的emby media server是同样的挂载,也就是说,最好让auto symlink看到的网盘路径和emby server是一致的。
# 由于我的固态硬盘比较小,担心后期库很大,所有strm文件加起来会越来越大,因此我把strm文件放在一块4T机械盘里的。
- /data/disk0/02strm:/strm
因为我有多个网盘,我手动建立了 115 和 aliyun 两个子文件夹,让他们放不同网盘的 strm 文件(非强迫症用户,或者只打算使用一个网盘的用户可跳过):
02strm
├── 115
└── aliyun
配置
打开 auto symlink 的 webui,添加同步:



其他默认就行,保存。然后去全局设置里,把这些开关打开:

保存后。点击右上角的用户图标—> 重启,来手动触发 strm 文件生成(因为打开了重启全同步开关)。然后点击查看日志 -> 刷新,出现下面这种信息,则表示在生成 strm 文件了:

现在,可以在 emby media server 里的媒体库的文件夹里,添加 strm 文件所在的路径,如:

这样 emby 刮削的是 strm 文件。并且 auto symlink 会把对应的非媒体文件(如字幕文件,nfo 文件也拷贝过来),刮削会快很多。点进一个刮削好的海报,你会发现媒体信息如下:

上面的路径显示的就是 strm 文件中记录的路径。
这样添加后,播放可能会出问题(路径没替换正确),需要让 emby2alist 针对 strm 文件中记录的路径进行规则替换。
因此继续修改 nginx/conf.d/constant.js,找到embyPathMapping变量,添加[0, 1, "/mnt", ""],如下:

0表示做字符串替换,1表示处理 strm 文件中的路径,[0, 1, "/mnt", ""]表示将 strm 文件中记录的路径中的/mnt移除掉。
改好后,重启 emby2alist 容器。
播放时,查看日志,可以看到有两个路径替换规则,第一个规则是由embyMountPath生成的(处理非 strm 文件中的路径),第二个规则是我们自己添加的,由于是基于 strm 文件播放的影视,因此只有第二个规则生效了,从而对路径进行了正确的替换。

对于 emby 的 docker 容器中,不能因为 emby 的媒体库似乎只需要添加文件夹
/data/xxx/strm/xxx/,就只挂载 strm 文件的根目录xxx:/data/xxx/strm/,而不挂载网盘媒体文件的根目录xxx:/mnt/115,若不挂载后者,可能会导致 emby 播放网盘资源时无法记录播放进度。
问题
-
元信息不能直接加载。使用 strm 文件来加快 emby 的刮削,会导致 emby 影视详情里没有视频元信息,但打开播放一次后就会有了。
刮削后,没播放的影视,不显示元信息:

播放过一次后(比如播放几秒),正常显示的元信息:

-
不支持转码。因为相当于是外网设备直接和网盘的媒体文件之间进行串流,所以不支持转码。如果你的库里全装的是来自网盘里的 4K 原盘、4K Remux,那么外网播放似乎有点奢侈。因为一个原盘可能近 50100GiB,外网看完一部这样的影视,得消耗多少流量?
-
能否流畅播放,取决于外网设备的对网盘文件的下载速度,因此开网盘会员 + 高下载带宽可能获得更好体验。我看的片少,不知道最高码率多大。如果你的好基友(or npy?)家是千兆带宽,你为爱发电买了网盘会员,他应该能流畅看大部分电影了。
-
plex 不支持读取 strm 文件,所以 plex 用户不需要 Auto Symlink 这个工具了,只能接受刮削时从网盘下载整个媒体文件,好处时,刮削后就会直接显示视频元信息(分辨率、码率、音频、内置字幕等),但刮削时下载带宽占用大。
参考:
对于 emby 的 docker 容器中,不能因为 emby 的媒体库似乎只需要添加文件夹
Comments