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 带宽的效果。

教程开始

准备

  1. 已经部署了 emby/plex media server 两者中的一个,无论是 docker 方式还是 “套件” 方式部署。下文以部署的 emby media server 为例,端口为 8096,并获取其 api 密钥。
  2. 已经部署了 alist,并按照 alist 官方文档添加了 115 网盘、阿里网盘等支持 302 重定向的网盘之一。下文以 115 网盘为例,并在 alist 中的挂载路径为/115,如下图:

    并在后台管理 -> 设置 -> 其他,获取 alist 令牌,备用。
  3. 使用 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 网盘时,用扫码即刻,这样防止两者相互挤掉)。

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
    
    
  • embyApiKeyalistAddralistTokenalistPublicAddr根据自身情况修改

  • 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 可以正常播放,那就是走了直链。

由于直接让 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 播放网盘资源时无法记录播放进度。

问题

  1. 元信息不能直接加载。使用 strm 文件来加快 emby 的刮削,会导致 emby 影视详情里没有视频元信息,但打开播放一次后就会有了。
    刮削后,没播放的影视,不显示元信息:

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

  2. 不支持转码。因为相当于是外网设备直接和网盘的媒体文件之间进行串流,所以不支持转码。如果你的库里全装的是来自网盘里的 4K 原盘、4K Remux,那么外网播放似乎有点奢侈。因为一个原盘可能近 50100GiB,外网看完一部这样的影视,得消耗多少流量?

  3. 能否流畅播放,取决于外网设备的对网盘文件的下载速度,因此开网盘会员 + 高下载带宽可能获得更好体验。我看的片少,不知道最高码率多大。如果你的好基友(or npy?)家是千兆带宽,你为爱发电买了网盘会员,他应该能流畅看大部分电影了。

  4. plex 不支持读取 strm 文件,所以 plex 用户不需要 Auto Symlink 这个工具了,只能接受刮削时从网盘下载整个媒体文件,好处时,刮削后就会直接显示视频元信息(分辨率、码率、音频、内置字幕等),但刮削时下载带宽占用大。

参考:

  1. https://github.com/bpking1/embyExternalUrl
  2. https://github.com/chen3861229/embyExternalUrl
  3. https://github.com/shenxianmq/Auto_Symlink
  4. https://invites.fun/d/23667
  5. 和群友吹水的记录

Comments