Emby媒体库302重定向:Openlist+115网盘+go-emby2openlist

最简单的302重定向方法,进一步优化媒体库,让外网也能无须转码观看蓝光原盘。使用Openlist+Emby+Clouddrive+go-emby2openlist+autosymlink的完整解决方案。

原文体验更佳:hiripple.com/zh/blog/emb... Emby媒体库302重定向:Openlist+115网盘+go-emby2openlist

注:本博文基于Strm+Emby=无痛刮削,应对网盘风控新策略的后续内容,强烈建议先阅读前篇博文。

前言

在部署完Emby+strm方案后,外网播放高达几十GB的蓝光原盘仍然是个难题。出门在外想看电影,只能提前下载好,确实有些麻烦。

目前最佳的解决方案是使用302重定向,让客户端直接向115网盘的CDN请求资源,完全绕过家庭/本地服务器的转发开销。这样一来,电影的传输带宽仅受限于网速,而非服务器上传带宽。

当然,这种方案也存在一些权衡:

  • 302重定向的播放启动速度略逊于本地转发

  • 115账号存在被封风险(个人自用概率较低,但需避免多IP多线程下载)

  • 部署流程相对复杂

网上虽然教程不少,但很多是复制粘贴的旧版方案,大部分停留在24年的过时方法,比如老旧的alist+nginx组合。这些方案不仅复杂繁琐,而且缺乏对ISO格式的刮削支持。

因此,本文的目标是提供最简洁的302重定向部署教程,同时保留原有的本地转发能力,实现iOS原盘刮削,并支持电影自动同步与刮削。最终达到在家享受本地转发的快速启动,在公网环境也能302流畅观影的双重体验。

市面上确实有更简单的一站式方案,比如Symmedia: www.symedia.top, 它集成了strm链接与302emby功能。不过这是非开源的付费项目(¥179),是否选择就看个人需求了。

Openlist 部署

Alist被收购后,Openlist成为了绝佳的替代方案:github.com/OpenListTea...

Openlist的作用很明确:提供302重定向能力,满足外网访问需求。这是Clouddrive无法胜任的功能。

使用Docker可以轻松部署(以Unraid为例):

yaml 复制代码
services:

openlist:

image: 'openlistteam/openlist:latest'

container_name: openlist

user: '0:0'

volumes:

# 将容器数据目录映射到Unraid的appdata共享区

- '/mnt/user/appdata/openlist:/opt/openlist/data'

ports:

- '5244:5244'

environment:

- UMASK=022

- TZ=Asia/Shanghai

restart: unless-stopped

容器启动后,访问 http://localhost:5244,按照官方文档完成登录→添加115网盘→获取API Key(后续步骤需要用到)。

go-emby2openlist 配置

官方地址:github.com/AmbitiousJu...

go-emby2openlist是一个Go语言编写的emby反向代理服务,功能强大且使用便捷。它可以反向代理emby页面,智能拦截并重定向电影资源路径(从本地路径转换为webdav 302重定向)。

引用官方说明:

网盘直链反向代理机制

传统模式下,Emby通过磁盘挂载间接读取网盘资源,采用服务器代理模式,数据流向为:

客户端 → Emby源服务器 → 磁盘挂载服务 → OpenList → 网盘
客户端 ← Emby源服务器 ← 磁盘挂载服务(将视频数据缓存到本地,供Emby读取) ← OpenList ← 网盘

这种模式的局限性显而易见:

  1. 视频需经过服务器中转,观看速度受限于服务器上传带宽

  2. 服务器性能不足时,能流畅播放1080p已属不易,4K更是奢望

  3. 服务器流量和资源消耗巨大

使用网盘直链反向代理后,数据流向变为:

客户端 → Emby反代服务器 → Emby源服务器(请求Emby API接口)
客户端 ← Emby反代服务器 ← Emby源服务器(返回数据)

对于普通API接口,反代服务器将请求转发至源服务器,缓存适当结果后返回给客户端。从客户端角度看,这与直连源服务器无异。

客户端 → Emby反代服务器 ⇒ OpenList ⇒ 网盘(请求视频直链)
客户端 ← Emby反代服务器 ← OpenList ← 网盘(返回视频直链,发出重定向响应)
客户端 ⇒ 网盘(客户端获取网盘直链后直接观看,无需再消耗服务器流量)

同样使用Docker安装,Unraid配置示例:

yaml 复制代码
version: '3.8'

services:

go-emby2openlist:

image: ambitiousjun/go-emby2openlist:v2.2.9

container_name: go-emby2openlist

restart: always

environment:

- TZ=Asia/Shanghai

- GIN_MODE=release

ports:

# 格式: - '宿主机端口:容器端口'

# HTTP端口(8095端口预留给Autosymlink)

- '8097:8095'

# HTTPS端口(如需启用SSL)

- '8094:8094'

volumes:

# --- 核心配置 ---

# 将宿主机配置文件映射到容器中

- ./config.yml:/app/config.yml

# --- 可选挂载 ---

# SSL证书文件目录

- /mnt/user/appdata/go-emby2openlist/ssl:/app/ssl

  


# 自定义注入JS/CSS文件目录

- /mnt/user/appdata/go-emby2openlist/custom-js:/app/custom-js

- /mnt/user/appdata/go-emby2openlist/custom-css:/app/custom-css

  


# 使用"OpenList本地目录树生成"功能时的必要挂载

# ffmpeg等库文件存放位置

- /mnt/user/appdata/go-emby2openlist/lib:/app/lib

# 生成的本地目录树存放位置

- /mnt/user/appdata/go-emby2openlist/openlist-local-tree:/app/openlist-local-tree

需要说明的是,博主使用了Cloudflare Tunnel反代+autosymlink的组合,因此没有使用项目自带的本地目录树和SSL功能。另外,该项目目前似乎不支持ISO原盘的刮削,且无法在添加电影后立即更新媒体库(需使用cron定时刷新)。综合考虑,保留原有的clouddrive+autosymlink方案是更明智的选择。

方案总结:在博主的架构中,clouddrive+autosymlink负责本地转发和媒体库刮削,而openlist+go-emby2openlist实现外网302重定向。由于go-emby2openlist本质上是反向代理服务,媒体库的刮削和管理依然由前者承担。

接下来是关键步骤:路径映射配置。Unraid环境下的config.yml示例:

yaml 复制代码
# emby访问配置

emby:

# Emby服务访问地址

host: http://192.168.xxx.xxx:8096

# 以下参数保持默认或根据个人喜好调整

episodes-unplay-prior: true

resort-random-items: true

proxy-error-strategy: origin

images-quality: 100

download-strategy: direct

strm:

# strm文件内容为本地路径而非URL,因此留空

path-map:

  


# openlist访问配置

openlist:

# 填写OpenList服务的实际访问地址

host: http://192.168.xxx.xxx:5244

# 填写OpenList的API Token

token: openlist-xxx

  


# 当前使用自建strm工具,暂时禁用此功能

local-tree-gen:

enable: false

ffmpeg-enable: false

virtual-containers:

strm-containers: mkv,mp4,mov,ts,avi,webm,iso

music-containers:

auto-remove-max-count: 10000

refresh-interval: 60

scan-prefixes:

- /115/云下载

- /115/剧集

ignore-containers: jpg,jpeg,png,txt,nfo,md

  


# 视频预览刮削

# 非阿里云盘用户建议禁用以减少不必要的请求

video-preview:

enable: false

containers:

- mp4

- mkv

ignore-template-ids:

- LD

- SD

  


# 路径映射(核心配置)

path:

# emby挂载路径与openlist真实路径的前缀映射

# 程序会提取strm文件中的路径 /mnt/user/embydata/local/movie/云下载/阿凡达.mkv

# 使用下方规则进行替换,将前缀 /mnt/user/embydata/local 替换为 /

# 最终得到OpenList路径:/movie/云下载/阿凡达.mkv

emby2openlist:

- /mnt/user/embydata/local/movie:/115

- /mnt/user/embydata/local/tv:/115

  


# 缓存配置

cache:

enable: true

expired: 1d

  


# SSL配置

ssl:

# 未配置HTTPS,保持禁用状态

enable: false

single-port: false

key: testssl.cn.key

crt: testssl.cn.crt

  


# 日志配置

log:

disable-color: false

重要提醒:确保config.yml的路径与docker-compose.yml中的映射路径完全一致,否则容器将无法正常启动。

最后执行 docker compose up -d,访问 http://localhost:8097 即可看到与emby完全相同的Web界面。此时下载/播放视频的地址会被302重定向至115的CDN服务器。

小技巧 :go-emby2openlist支持注入外部JS/CSS,推荐注入 emby-external-url.7o7o.cc/embyWebAddE... 实现直接跳转到本地播放器的功能。

错误排查

如果出现"没有兼容的流"错误,请按以下步骤排查:

  1. 首先访问emby源地址 http://localhost:8096,如果源服务异常,说明是autosymlink与emby容器的路径配置问题,请参考前篇博文进行排查。

  2. 如果源服务正常,大概率是config.yaml中的路径映射配置错误。您需要检查webdav的实际地址与config.yaml中规则的匹配度。查看go-emby2openlist的容器日志可以获取实际请求路径信息,据此调整为正确的真实路径即可。

ISO刮削

这部分内容与之前的博文基本一致,在Unraid系统中调用ffprobe进行ISO刮削。现在Ripp已将JSON格式化接口开放为公共API,大家可以自由使用。

脚本示例:

bash 复制代码
#!/bin/bash

  


# 设置脚本在遇到错误时退出

set -euo pipefail

  


# 定义目录路径

FFPROBE_DIR="/mnt/user/embydata/ffmpeg-master-latest-linux64-gpl/bin"

LINKS_DIR="/mnt/user/embydata/links"

TEMP_DIR="/mnt/user/embydata/temp"

MOVIES_DIR="/mnt/user/embydata/local/movie/云下载"

API_URL="http://probe.hiripple.com/format"

  


# 定义锁文件路径,使用/tmp目录避免权限问题

LOCK_FILE="/tmp/process_strm.lock"

  


# 函数:释放锁文件

cleanup() {

rm -f "$LOCK_FILE"

exit

}

  


# 检查是否已有实例在运行

if [ -e "$LOCK_FILE" ]; then

echo "锁文件已存在,脚本可能正在运行。退出。"

exit 1

fi

  


# 创建锁文件

touch "$LOCK_FILE"

  


# 确保在脚本退出时删除锁文件

trap cleanup EXIT

  


# 进入ffprobe所在目录

echo "进入目录: $FFPROBE_DIR"

cd "$FFPROBE_DIR" || { echo "无法进入目录 $FFPROBE_DIR"; exit 1; }

  


if [ ! -d "$TEMP_DIR" ]; then

echo "创建temp目录: $TEMP_DIR"

mkdir -p "$TEMP_DIR"

fi

  


# 遍历所有.strm文件

echo "扫描目录: $LINKS_DIR 以查找.strm文件"

find "$LINKS_DIR" -maxdepth 1 -type f -name "*.strm" | while read -r strm_file; do

# 提取电影名(不带.strm扩展名)

filename=$(basename "$strm_file" .strm)

echo "处理电影: $filename"

  


# 定义路径

mediainfo_json_link="${LINKS_DIR}/${filename}-mediainfo.json"

mediainfo_json_temp="${TEMP_DIR}/${filename}-mediainfo.json"

iso_file="${MOVIES_DIR}/${filename}.iso"

  


# 检查是否已存在mediainfo.json

if [ -f "$mediainfo_json_link" ]; then

echo "已存在mediainfo.json文件,跳过: $mediainfo_json_link"

continue

fi

  


# 检查ISO文件是否存在

if [ ! -f "$iso_file" ]; then

echo "ISO文件不存在,跳过: $iso_file"

continue

fi

  


# 执行ffprobe命令,生成mediainfo.json

echo "运行ffprobe生成mediainfo.json文件"

set +e # 临时禁用错误退出,以处理可能的错误

./ffprobe -v error \

-print_format json \

-show_format \

-show_streams \

-show_chapters \

-show_programs \

bluray:"$iso_file" > "$mediainfo_json_temp"

ffprobe_status=$?

set -e # 重新启用错误退出

  


# 检查ffprobe是否成功以及文件是否创建

if [ $ffprobe_status -ne 0 ] || [ ! -s "$mediainfo_json_temp" ]; then

echo "ffprobe执行失败或文件创建失败,跳过电影: $filename"

continue

fi

  


# 调用API格式化JSON

echo "调用API进行格式化"

response=$(curl -s -X POST "$API_URL" \

-H "Content-Type: application/json" \

-d @"$mediainfo_json_temp")

  


# 检查API调用是否成功

if [ $? -ne 0 ] || [ -z "$response" ]; then

echo "API调用失败或无响应,跳过电影: $filename"

continue

fi

  


# 保存API返回的格式化JSON到LINKS_DIR

echo "保存格式化后的JSON到 $mediainfo_json_link"

echo "$response" > "$mediainfo_json_link"

  


# 等待5秒

echo "等待5秒后处理下一个文件..."

sleep 5

  


echo "完成处理电影: $filename"

echo "----------------------------------------"

  


done

  


echo "所有.strm文件处理完成。"

在Emby中,如果电影缺少时长信息,将无法保存播放进度。因此,对ISO文件进行刮削显得尤为重要。

小结

最后的内网穿透可以直接使用Cloudflare Tunnel,这样通过公网访问自己的域名就能流畅播放影片了。

如果在部署过程中遇到任何问题,欢迎在下方留言交流~

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax