
115 + alist + cd2 实现 emby 直链播放
流程 & 原理介绍
此方案需使用到四个容器,Emby、CloudDriver2、Alist、Nginx。
- Emby 读取、刮削、入库 「2」 挂载好的资源
- 通过 CloudDriver2 挂载 webdav 协议的资源(115网盘)挂载到本地硬盘,使用起来比 Alist 的 webdav + rclone 挂载方便。
- 通过 Alist 将 115 网盘资源转成可以通过网络编辑和管理 webdav 协议。
- 安装 Nginx 实现对访问 Emby 的请求地址,并从 Alist 获取 115 直链转发给客户端。将: 静态资源转发到 Emby 服务上,视频资源的访问直接转发到 Alist,从而利用 Alist 的 302 转发实现直接访问网盘资源。
302 是什么
GPT 如是说:
HTTP 302 是 HTTP 协议中的一种状态码(Status Code),全称是 HTTP 302 Found,表示请求的资源临时移动到了一个新的 URL,即临时重定向。
当浏览器或其他客户端向服务器发送请求时,如果服务器返回一个 302 状态码,它会同时在响应头中提供一个 Location 字段,告知客户端资源现在可以在新的 URL 找到。客户端随后应该使用这个新的 URL 来重新发起请求。
这种重定向通常是临时的,意味着资源只是暂时可以在新的地址找到,未来还可能会返回到原来的地址。
在此教程中,利用 Alist 的获取 115 网盘直链的功能,也就是302跳转直链,来实现 Emby 播放时直连网盘地址,不走 Emby 所在网络上下行,减少了一次中转,达到外网高带宽看片的需求。
目前已测试以下客户端播放可以实现 302 跳转
- Emby 客户端
- Infuse
- Fileball
- Vidhub
- Yamby
欢迎补充…
准备条件:
- 有空间及会员的115账号
- CD2(CloudDriver2),可以不需要会员。
- Alist
- Emby,可以选择自己喜欢的镜像版本,如 emby/embyserver、linuxserver/emby、amilys/emby
阅读此篇教程,默认你已经学会
- Docker/Docker-Compose 的相关配置使用
- 上述相关软件的基础配置使用
容器配置
Emby
version: '3' # 指定版本
services: # 定义服务的部分
embyserver: # 服务的名称
image: 'amilys/embyserver:latest' # 使用的镜像
container_name: embyserver # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '2' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 2048M # 内存限制
ports:
- '8096:8096' # 端口映射
volumes:
- ./emby:/config
- /Movies:/movies:rslave
据群友实测,Emby 需要 4.8 及以上版本,低于 4.8 版本有可能不成功。
emby 配置两个路径,一个是 /config
,映射到你喜欢的路径即可。一个是 /movies
,映射到宿主机的 /Movies
,这个路径可以自己自定义,所有的影视文件都会在此路径内,没有什么特殊的,记住这个 /movies
,一会要考。
CD2
version: "3" # 指定版本
services: # 定义服务的部分
cloudnas: # 服务的名称
image: cloudnas/clouddrive2 # 使用的镜像
container_name: clouddrive2 # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置 bridge / host / none / container / user-defined bridge
user: 0:0 # 以 root 用户身份运行
privileged: true # 特权模式
pid: "host"
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: "1" # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
environment:
- TZ=Asia/Shanghai
- CLOUDDRIVE_HOME=/Config
devices:
- /dev/fuse:/dev/fuse
ports:
- "19797:19798" # 端口映射
volumes:
- /Movies:/CloudNAS:shared
- ./cd2:/Config
cd2 映射两个路径,/CloudNAS
为挂载路径,用于将云盘文件挂载到本地,同样映射到宿主机的 /Movies
路径下,这个宿主机路径与 Emby 的必须一致,自行决定。
Alist
version: '3' # 指定版本
services: # 定义服务的部分
alist: # 服务的名称
image: xhofe/alist:latest # 使用的镜像
container_name: alist # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置 bridge / host / none / container / user-defined bridge
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '1' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
environment:
- PUID=0
- PGID=0
- UMASK=022
ports:
- '5244:5244' # 端口映射
volumes:
- ./alist:/opt/alist/data
Alist 只需要映射配置文件的路径即可。
Nginx
version: '3' # 指定版本
services: # 定义服务的部分
nginx: # 服务的名称
image: nginx:latest # 使用的镜像
container_name: nginx # 容器名称
restart: unless-stopped # 重启策略
network_mode: host # 网络配置
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '1' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # 需要手动上传
- ./nginx/nginx.conf:/etc/nginx/nginx.conf # 需要手动上传
- ./nginx/embyCache:/var/cache/nginx/emby
- ./nginx/logs:/var/log/nginx
nginx 配置需要完全自定义,使用官方镜像即可,需要注意的是,容器的网络模式必须使用 host。相关配置文件后文提供,nginx 容器先不启动
。
详细配置
CD2
启动 CD2 容器后,添加自己的 115 账号。使用 CD2 的本地挂载功能,选择 115根目录
(要挂载哪个目录,就进入到哪个目录的根层级就行),点击 挂载到本地
,名称
填写 115
,挂载点选择 /CloudNAS
,保存即可挂载到 /CloudNAS
路径下,也就是宿主机的 /Movies
路径。
选择挂载路径(这里十分关键跟后面的 constant.js
中的路径直接相关,如果不一致会导致直链播放失败,建议按照我的配置来)
选择好 alist 文件夹,点击确定后,会显示如下路径
点击挂载后,查看挂载是否成功,若「失败原因」处显示空白,则证明一切正常。
此时,在宿主机查看 /Movies
目录,就可以查看到115上的文件了。
Alist
启动 Alist 容器后,设置密码
./alist admin set NEW_PASSWORD
访问 http://nasip:5244,登录管理后台,添加 115 网盘,按需配置,对配置项不太理解的朋友建议直接抄我的
记录下 alist token 值,示例:alist-56aed914-dc75-4exxxxx
挂载 115 云盘提示如下信息,是因为 115已经下架了
Windows、Mac、Linux
这三个客户端的应用{ "state": 0, "error": "登录失败,系统已下架!如果你有电脑端的使用需求,我们诚挚邀请你下载体验115产品专属客户端“115浏览器”或在线使用“115网页端(115.com)”,畅享智能高效云生活。", "errno": 0, "message": "登录失败,系统已下架!如果你有电脑端的使用需求,我们诚挚邀请你下载体验115产品专属客户端“115浏览器”或在线使用“115网页端(115.com)”,畅享智能高效云生活。", "code": 0 }
请通过二维码令牌进行登录 QRCode 扫码方式登录
如果你的 CD2 是挂载的根目录的话,最下方的 根文件夹ID
为 0 不要修改,反之请自行修改,务必保持一致。
Emby
配置完以上挂载后,需要重启一次 Emby 容器,如果你的 Emby 已经提前启动了的话。
重启完成后,在 Emby 中添加你的媒体库,此时可以看到,Emby 的 /movie
目录下有你的 115 的影视文件了。如果你的文件部包含 nfo 文件的话,建议不要开启 ⬇️ ⬇️ ⬇️ 此开关,防止小文件上传过多被风控。以及关闭 将媒体图片保存到文件夹中
开关。
Nginx
操作到这里,你需要明确一下 Emby 和 Alist 的对应文件路径。
两边对比一下同一个视频文件,可以看到,Emby 中的路径应为 /movies/alist/115/影视/动漫/动画电影/铃芽之旅 (2022)/铃芽之旅 (2022) - 1080p H.264.mkv
,Alist中的同一个文件路径为 /115/影视/动漫/动画电影/铃芽之旅 (2022)/铃芽之旅 (2022) - 1080p H.264.mkv
具体的网盘内路径以自己为准,但如果完全照抄以上配置的话,路径的开头
/movies/alist
及/115
肯定是和我一致的。
此时 Alist 内的路径为 Emby 的路径的子集,即多出一个 /movie/alist
开头。
接下来,下载此压缩包,解压后得到一个 nginx 文件夹,其中有 conf.d
文件夹及 nginx.conf
文件,此为 nginx 相关配置文件。在此感谢 bpking1/embyExternalUrl 作者大大提供的配置及脚本。
需要自定义配置的有两个文件。
-
conf.d/constant.js
- embyHost:Emby 的内网地址及端口
- embyMountPath:填写上述的
/movies/alist
,即 Alist 路径为 Emby 的子集剩余的部分。注意填写到此列表变量的元素中,即["/movies/alist"]
。如果你的 Emby 文件路径与 Alist 完全一致,即剩余部分为空,那么此处填写[]
。 - embyApiKey: Emby 的 ApiKey,从 Emby 的 web 中获取。
- alistAddr: Alist 的地址及端口。这里我使用的是 Alist 的外网地址,内网地址是否可用可自行探索。
- alistToken: Alist 的 Token 令牌,在 Alist → 管理 → 设置 → 其他 → 令牌 获取,格式为
alist-
开头
-
conf.d/emby.conf
- 第 26 行:
listen 8091;
- 此为 nginx 监听的端口,修改为你想要的端口即可,用于替代原 Emby 的 8096 端口访问。访问此端口才能实现 302 转发。
修改完配置之后,将 conf.d
及 nginx.conf
映射到 nginx 容器,在上述的 nginx 的 docker-ccompose 配置中已添加,注意存放的宿主机路径。启动 nginx 容器。
测试
此时启动 Nginx 容器后,访问 8091
端口,或是你在 emby.conf
文件中修改的端口,可以访问到 Emby Web。即完成了第一步,nginx 代理 Emby Web 成功。
使用各类客户端,如 Emby 官方客户端、Infuse、Fileball、Vidhub 等登录 8091 端口,找一个刮削好的片子播放,或者 web 跳转第三方播放器 potplayer、iina 等,查看 CD2 的下载任务。如果没有大流量的对应文件下载,进程为 /system/EmbyServer
,即 302 转发成功。
目前 Emby Web 直接播放还无法实现302转发,也或许是我姿势不对。如果有成功使用 Emby Web 播放 302 直链的欢迎分享成果。
合并容器配置
使用 Docker Compose 可以方便地把多个有关联的容器进行合并配置,并且可以设置依赖的启动顺序,一键拉起所有容器。
version: '3' # 指定版本
services: # 定义服务的部分
embyserver: # 服务的名称
image: 'amilys/embyserver:latest' # 使用的镜像
container_name: embyserver # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '2' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 2048M # 内存限制
depends_on:
- cloudnas
- alist
- nginx
ports:
- '8096:8096' # 端口映射
volumes:
- ./emby:/config
- /Movies:/movies:rslave
cloudnas: # 服务的名称
image: cloudnas/clouddrive2 # 使用的镜像
container_name: clouddrive2 # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置
user: 0:0 # 以 root 用户身份运行
privileged: true # 特权模式
pid: "host"
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: "1" # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
environment:
- TZ=Asia/Shanghai
- CLOUDDRIVE_HOME=/Config
devices:
- /dev/fuse:/dev/fuse
ports:
- "19797:19798" # 端口映射
volumes:
- /Movies:/CloudNAS:shared
- ./cd2:/Config
alist: # 服务的名称
image: xhofe/alist:latest # 使用的镜像
container_name: alist # 容器名称
restart: unless-stopped # 重启策略
network_mode: bridge # 网络配置
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '1' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
environment:
- PUID=0
- PGID=0
- UMASK=022
ports:
- '5244:5244' # 端口映射
volumes:
- ./alist:/opt/alist/data
nginx: # 服务的名称
image: nginx:latest # 使用的镜像
container_name: nginx # 容器名称
restart: unless-stopped # 重启策略
network_mode: host # 网络配置
user: '0:0' # 以 root 用户身份运行
privileged: true # 特权模式
deploy: # 部署配置
resources: # 资源限制
limits:
cpus: '1' # CPU 限制(1 表示 100% 的一个 CPU,2 表示 200% 的一个 CPU)
memory: 1024M # 内存限制
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # 需要手动上传
- ./nginx/nginx.conf:/etc/nginx/nginx.conf # 需要手动上传
- ./nginx/embyCache:/var/cache/nginx/emby
- ./nginx/logs:/var/log/nginx