释放小七猫的分享欲

媒体服务器一站式搭建-MoviePilot 媒体自动化及 iyuu 辅种

tags: NAS
@ 27/11/2025

媒体服务器一站式搭建-MoviePilot 媒体自动化及 iyuu 辅种

注意:这部分内容不应出现在公开互联网

MoviePilot V2 安装

version: '3.3'
services:
  moviepilot:
    stdin_open: true
    tty: true
    container_name: moviepilot-v2
    hostname: moviepilot-v2
    network_mode: host
    volumes:
      # 下载目录,容器内外要一致
      - '/../视频文件:/../视频文件'
      - './config:/config'
      - './core:/moviepilot/.cache/ms-playwright'
      # - '/var/run/docker.sock:/var/run/docker.sock:ro'

    environment:
      - 'NGINX_PORT=3000'
      - 'PORT=3001'
      - 'PUID=0'
      - 'PGID=0'
      - 'UMASK=000'
      - 'TZ=Asia/Shanghai'
      - 'SUPERUSER=admin' #超级管理员用户名
      - 'SUPERUSER_PASSWORD=!Yan2718281' #超级管理员初始密码
    # 添加自定义 hosts
    extra_hosts:
      - "api.themoviedb.org:65.9.189.27"
      - "api.tmdb.org:65.9.189.48"
      - "www.themoviedb.org:18.67.51.21"
      - "webservice.fanart.tv:51.89.210.79"
      - "api.telegram.org:149.154.167.220"
      - "github.com:20.200.245.247"
      - "api.github.com:20.205.243.168"
      - "raw.githubusercontent.com:185.199.111.133"
      - "api.thetvdb.com:3.170.218.86"

    image: docker.io/jxxghp/moviepilot-v2:latest

extra_host 可能过一段时间就会失效,需要重新找。嫌麻烦的话可以直接上代理。

      - 'PUID=0'
      - 'PGID=0'

使用 docker 的话,这两行代码可能会导致权限问题,因为我用的 podman,因此无法确定实际情况,仅供参考。

配置自动刮削和整理

MP 中正确映射目录后应该能看到这样的结构

PT 目录就是我们从 PT 等途径下载到的源文件,Videos 就是我们整理后的文件目录

再看看这个结构,这回就用一个假设为 pt 的站点来举例:

❯ tree -L 3
.
├── PT
│   ├── pt
│   │   ├── 电视剧
│   │   ├── 电影
│   │   ├── 纪录片
│   │   └── 综艺节目
└── Videos
    ├── pt
    │   ├── 电视剧
    │   ├── 电影
    │   ├── 纪录片 -> ../../PT/pt/纪录片
    └── └── 综艺节目 -> ../../PT/pt/综艺节目

首先配置一下 MP 的 API,需要自行在 TMDB 上注册

然后配置自动刮削整理

  1. 资源目录填写 PT/pt/电影,媒体库目录 Videos/pt/电影,根据你的实际目录填写,需要绝对路径。
  2. 自动整理选择目录监控,因为下载器监控必须要在 qbittorrent 里面添加下载器下载才能监控到变化,实际情况往往没有这么理想——用了不支持的 PT 站、qbittorrent 中批量添加了种子、其他下载器下载等。
  3. 整理方式选择硬链接,硬链接不会占用空间。这一点我说明一下,现在先进一点的文件系统,例如 btrfs、zsh 本身就有“写时复制”功能

Btrfs 支持写时复制(COW)特性,通过引用链接(reflink)实现高效的文件复制。使用 –reflink=always 可以确保快速复制而无需实际数据拷贝。

在这种特性下,你使用复制和硬链接基本没区别(Ext4 不支持写时复制)。

  1. 智能重命名和刮削元数据打开。

MP 还可以自定义重命名媒体文件的格式,如果没有特殊需求,用默认即可。

我用的格式去掉了空格,并采用了年份前置。

配置下载器和媒体服务器联动

“系统”这里可以定义下载器和媒体服务器,可以配合支持的 PT 站实现选片下载,一键入库刮削整理功能并刷新媒体服务器功能。

这部分功能可以自行多多探索。

插件推荐

站点自动签到/站点数据统计

媒体库刮削/媒体服务刷新

这两个插件用于自动入库和定期补充刮削 Emby 媒体库缺失的源数据,可以作为 MoviePilot 刮削功能的补充。运行频次不用太高,隔几天一次就行。

Nginx 搭建 Emby 认证服务器 - 以 OpenWRT 为例

以前使用 Emby 一直采用别人的补丁文件,一件替换后就可以实现破解,但……

  1. 使用别人的破解补丁,感觉不太放心(其实是多虑了,存的都是正经电影)
  2. Emby 出新版本之后,必须等到补丁作者更新,我才能更新

我是一个爱用新版本的人,前几天 Emby 更新了 4.9.1.90 版本,我苦等补丁作者更新许久,但其博客一直停留在一个多月前,似乎也没有更新的迹象,所以只能自己动手了。

CA 自签证书

先解决证书问题,

第三方网站签发

最简单的方法就是找个网站:

gmcert.org

  • 证书算法:选 RSA 算法,长度至少 2048
  • 主题名称:mb3admin.com
  • 有效天数:3650
  • 证书链选项:勾选自动包含 CA 证书链
  • 输出格式:一般就用 pem 格式或 cer(crt)/key 格式就行

但我使用的 cer/key 证书链,后面用这两个格式做示例,操作方法都是一样的。

生成两个证书:mb3admin.cer,mb3admin.key,下载下来保存好。

linux OpenSSL 签发

mkdir -p <username>/<docker-file-path>/nginx/cert/mb3admin.com && cd <username>/<docker-file-path>/nginx/cert/mb3admin.com

# 生成 CA 密钥
openssl genrsa -out ca.key 2048
# 生成 CA 证书
openssl req -x509 -new -nodes -key ca.key -subj "/C=CN/ST=Beijing/L=Beijing/O=<username>/OU=<username>/CN=<username>/emailAddress=<user-email>" -days 36500 -out ca.crt
# 将 CA 转换成 p12 格式,并指定密码 (<username>)
openssl pkcs12 -export -clcerts -in ./ca.crt -inkey ca.key -out ca.p12 -password pass:<username>
# 将 p12 格式的证书 Base64 编码
base64 ca.p12
# Base64 一行不能超过 76 字符,超过则添加回车换行符。如果因为换行的原因,不能安装证书,可以使用 -w 参数
base64 -w 0 ca.p12
# 将 CA 转换成 pem 格式
openssl x509 -outform pem -in ca.crt -out ca.pem
# 生成服务端私钥 server.key
openssl genrsa -out server.key 2048
# 生成服务端证书请求 server.csr
openssl req -new -sha256 -key server.key -out server.csr -subj "/C=CN/L=Beijing/O=<username>/OU=<username>/CN=mb3admin.com/CN=*.mb3admin.com"
# 生成服务端证书 server.crt
openssl x509 -req -extfile <(printf "subjectAltName=DNS:mb3admin.com,DNS:*.mb3admin.com") -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

上述代码中替换一下自己的相关信息即可(也可以直接去参考资源中获取直接执行的代码):

<username>
<user-email>
<docker-file-path>

Nginx 搭建认证服务器——OpenWRT 为例

OpenWRT 的配置文件路径为 /etc/nginx/conf.d/,假设你已经搭建好了反向代理环境,仅需配置假的 mb3admin.com 认证站点。

假设把证书放置在 /etc/nginx/conf.d/certs/ 下:

root@OpenWRT:/etc/nginx/conf.d/certs# ls
mb3admin.cer      mb3admin.key

新建一份配置文件 mb3admin.conf,内容如下,需要注意的地方已经添加了注释

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name mb3admin.com;

    # mb3admin 专用证书(使用你指定的路径)
    ssl_certificate     /etc/nginx/conf.d/certs/mb3admin.cer;
    ssl_certificate_key /etc/nginx/conf.d/certs/mb3admin.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:32k;
    ssl_session_timeout 64m;

    # 跨域和安全头配置(确保 Emby 客户端正常请求)
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers *;
    add_header Access-Control-Allow-Methods *;
    add_header Access-Control-Allow-Credentials true;

    # Emby 认证破解核心接口(仅对 mb3admin.com 生效)
    location /admin/service/registration/validateDevice {
        default_type application/json;
        return 200 '{"cacheExpirationDays": 3650,"message": "Device Valid","resultCode": "GOOD"}';
    }

    location /admin/service/registration/validate {
        default_type application/json;
        return 200 '{"featId":"","registered":true,"expDate":"2099-01-01","key":""}';
    }

    location /admin/service/registration/getStatus {
        default_type application/json;
        return 200 '{"deviceStatus":"","planType":"Lifetime","subscriptions":{}}';
    }

    location /admin/service/appstore/register {
        default_type application/json;
        return 200 '{"featId": "","registered": true,"expDate": "2099-01-01","key": ""}';
    }

    location /emby/Plugins/SecurityInfo {
        default_type application/json;
        return 200 '{"SupporterKey": "", "IsMBSupporter": true}';
    }
}

接下来需要让 Emby 将域名 mb3admin.com 劫持到 OpenWRT 上,这对于 OpenWRT 来说非常简单。

现在 IPv6 已经基本普及,所以,如果你的 Emby 服务器有 IPv6 地址的话,就需要把 IPv6 的解析也加上,否则服务器还是会优先解析到 mb3admin.com 的 IPv6 地址上,因为它是双栈的。

在 Emby 服务器上 ping 一下:

root@testing:~# ping mb3admin.com
PING mb3admin.com(mb3admin.com (fd40:f27e:ca6::1)) 56 data bytes
64 bytes from mb3admin.com (fd40:f27e:ca6::1): icmp_seq=1 ttl=64 time=0.251 ms
64 bytes from mb3admin.com (fd40:f27e:ca6::1): icmp_seq=2 ttl=64 time=0.660 ms
^C
--- mb3admin.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.251/0.455/0.660/0.204 ms

root@testing:~# ping4 mb3admin.com
PING  (10.0.0.1) 56(84) bytes of data.
64 bytes from xunlei.550293.xyz (10.0.0.1): icmp_seq=1 ttl=64 time=0.630 ms
64 bytes from xunlei.550293.xyz (10.0.0.1): icmp_seq=2 ttl=64 time=0.941 ms
^C
---  ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.630/0.785/0.941/0.155 ms

可以看到,的确优先返回了 IPv6 地址,但没关系,双栈都已经被我劫持到路由器上了。

然后我们用浏览器访问,或者通过 curl 工具访问:

  1. https://mb3admin.com/admin/service/registration/validateDevice/
  2. https://mb3admin.com/admin/service/registration/validate/

查看返回信息是否正确:

root@OpenWRT:/etc/nginx/conf.d# curl -kl https://mb3admin.com/admin/service/registration/validateDevice/
{"cacheExpirationDays": 3650,"message": "Device Valid","resultCode": "GOOD"}

root@OpenWRT:/etc/nginx/conf.d# curl -kl https://mb3admin.com/admin/service/registration/validate/
{"featId":"","registered":true,"expDate":"2099-01-01","key":""}

如果和我一样就正确了。

在网页端激活 Emby

如果你是刚安装好的 Emby,那么直接进入后台,Emby Premiere 选项,随便输入一个密钥,保存。注意,这里不会提示已经激活啥的,但其实已经起作用了。

如果你之前已经通过别的方式激活过 Emby,比如替换破解文件,那么直接进入后台可能会激活不了,请按以下步骤操作:

  1. 卸载 Emby:apt remove emby-server,并删除残留文件 rm -rf /opt/emby-server/,这一步只是删除程序,不会清除用户数据。
  2. 删除旧的激活文件:rm -rf /var/lib/emby/data/activitylog*
  3. 重新安装 Emby:apt install ./emby-server-deb_4.9.1.90_amd64.deb

然后再进入后台激活,激活后最好重启一下 Emby 服务:

sudo systemctl restart emby-server

不出意外的话,控制台会出现金牌标识。

但很遗憾,这种方式的激活只能在内网使用,因为 Emby 的客户端也会进行正版验证,在外网当然很难把 mb3admin.com 劫持到我们的路由器上,但幸运的是我们还有一计。

Emby Server 修改认证站点

要使用这个方法,首先你要满足以下几个条件

  1. 确保自己已经有能力搭建一个私有域名的假认证站点,公网无法劫持 mb3admin.com,只能每个设备都去劫持,很麻烦
  2. 假认证站点必须可以公网访问,考虑到家庭宽带一般封禁了 443 端口,因此可以考虑采用加端口号和内网穿透的方案
  3. 关于 SSL,经过我的测试,证书只要有就行(必须 https 访问),匹不匹配域名不重要

在前文,我们已经在 OpenWRT 上搭建好了一个假的 mb3admin.com 服务器,但由于这次我们要上公网,因此得改改域名。

假设我们的域名是 emby-crack.com,证书已经匹配好(这是你自己的域名,要搞证书就很容易了,不用再去搞自签名证书),说到底也就是反向代理里面这几行的事:

    server_name emby-crack.com;

    # mb3admin 专用证书(使用你指定的路径)
    ssl_certificate     /etc/nginx/conf.d/certs/emby-crack.com.cer;
    ssl_certificate_key /etc/nginx/conf.d/certs/emby-crack.com.key;

还有一个我非常推荐的方案,只需要有一个域名即可,那就是使用大善人 Clouflare 的 Worker 功能。

然后编辑这个项目的 worker.js,修改为以下内容,其实和反向代理配置差不多,只能换成了 js 语言来写。

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const path = url.pathname;
    
    // 定义路由对应的响应内容
    const routes = {
      '/admin/service/registration/validateDevice': {
        status: 200,
        body: JSON.stringify({
          cacheExpirationDays: 3650,
          message: "Device Valid",
          resultCode: "GOOD"
        })
      },
      '/admin/service/registration/validate': {
        status: 200,
        body: JSON.stringify({
          featId: "",
          registered: true,
          expDate: "2099-01-01",
          key: ""
        })
      },
      '/admin/service/registration/getStatus': {
        status: 200,
        body: JSON.stringify({
          deviceStatus: "",
          planType: "Lifetime",
          subscriptions: {}
        })
      },
      '/admin/service/appstore/register': {
        status: 200,
        body: JSON.stringify({
          featId: "",
          registered: true,
          expDate: "2099-01-01",
          key: ""
        })
      },
      '/emby/Plugins/SecurityInfo': {
        status: 200,
        body: JSON.stringify({
          SupporterKey: "",
          IsMBSupporter: true
        })
      }
    };

    // 检查请求路径是否匹配已定义的路由
    if (routes[path]) {
      const { status, body } = routes[path];
      return new Response(body, {
        status,
        headers: {
          'Content-Type': 'application/json'
        }
      });
    }

    // 对于未匹配的路由,返回 404
    return new Response(JSON.stringify({ error: 'Not found' }), {
      status: 404,
      headers: {
        'Content-Type': 'application/json'
      }
    });
  }
};

编辑好之后一定要保存,然后退出编辑器。

在部署页面部署好修改后的代码

然后访问 https://emby-cert.xxxx.workers.dev/admin/service/registration/validate,测试能否返回指定的json字符串即可。

Clouflare 的 workers.dev 域名在墙内无法访问,这也是我说需要有一个域名的原因,在以下位置绑定好自己的域名,用自己的子域名访问就可以了。

copy 待拷贝文件

以下内容参考 用于 Emby Server 的修改认证站点&搭建认证站点

原作者已经写得非常详细,在这里我梳理一下大概的步骤。

需要修改的文件目录如下:

├─Emby.Server.Implementations.dll
├─Emby.Web.dll
├─MediaBrowser.Model.dll
└─dashboard-ui
    ├─embypremiere
    │  └─embypremiere.js
    └─modules
        └─emby-apiclient
            └─connectionmanager.js

一个个拷贝出来有点烦,可以一键拷出:

# 先创建目标目录(如果不存在)
mkdir -p target_dir

# 复制文件并保留相对目录结构
cd /opt/emby-server/system/
cp --parents Emby.Server.Implementations.dll Emby.Web.dll MediaBrowser.Model.dll dashboard-ui/embypremiere/embypremiere.js dashboard-ui/modules/emby-apiclient/connectionmanager.js -t target_dir

然后想办法把这些文件拷贝到 Windows 电脑上。

修改 Emby.Server.Implementations.dll

下载 dnSpy 软件:dnSpy/releases,请自行下载最新版

原文的破解链接有点问题,假设你的破解服务器域名是 emby-crack.com,那么直接将 mb3admi.com 替换为 emby-crack.com 就可以了,替换之后,为避免出错,最好是把修改后的地址贴到浏览器中试一试,以免打错字。

修改 Emby.Web.dll

这份文件中的 Emby.Web.dashboard_ui.modules.emby_apiclient.connectionmanager.js 无法在软件中修改,因此需要下载到本地,改好后再传上去。

修改 MediaBrowser.Model.dll

纯为了好看,改不改都可以,嫌麻烦可以不改

不改的话高级页面不会显示已激活,但功能已经可以正常使用

修改 embypremiere.js 和 connectionmanager.js

文本文件就很简单了,直接记事本打开。替换掉 mb3admin.com,就完事。

将文件还原到原来的位置

关闭服务器,将上述文件全部替换到原文件位置,使用 cp -r * /opt/emby-server/systemc/ 直接覆盖原文件即可,然后重启 Emby 服务 systemctl restart emby-server。

Emby 配置

Emby 可以直接软链接,因此对于综艺、纪录片,直接添加软链接路径就可以了,但要注意文件夹的权限问题。

辅种

辅种:一个站点的某个种子很可能在别的站点也有,因此对于该资源无需进行多次下载来做种,直接把某站点下载好的资源拿去给别的站做种就行。

辅助主要有三种方式:

  1. 仅 qBittorrent:qBittorrent 负责下载、做种,辅种
  2. qBittorrent+transmission:qBittorrent 负责下载、做种;transmission 辅种
  3. qBittorrent+transmission:qBittorrent 负责下载;transmission 负责做种和辅种

种子量没超过 1000,或者 qBittorrent 没有明显卡顿的时候,用 1、2 就可以,种子数量过大可以选择 3。3 相比 2 就是多了一个 qb 转种 tr 的过程。

方案一推荐:MoviePilot 插件——青蛙辅种助手

配置比较简单,直接把种子路径映射到容器,然后填进去就行了,要先配置好 MP 的下载器。

这种方案无法实现 qBittorrent 做种、transmission 辅种,所有种子都在 qBittorrent 里面。

方案二、三推荐:IYUU Plus

IYUU Plus 可以看成是专业的辅种助手,不再是 MP 的一个插件,核心功能是可以实现多个下载器的联动。

先安装 IYUU,网络模式必须使用 host:

version: "3.8"  # 统一使用最高兼容版本(兼容所有服务配置)

services:
  # 1. IYUUPlus 服务
  iyuuplus-dev:
    image: docker.io/iyuucn/iyuuplus-dev:latest
    container_name: IYUUPlus
    stdin_open: true
    tty: true
    network_mode: host
    volumes:
      - ./iyuu/iyuu:/iyuu
      - ./iyuu/data:/data  # 区分数据目录,避免冲突
      - /home/admin/.local/share/qBittorrent/BT_backup:/qb_torrents
      - /var/lib/transmission/.config/transmission-daemon/torrents:/tr_torrents
    restart: always  # 服务级重启策略(可继承 Pod 策略)

需要映射配置文件目录和种子目录,注意,根据 IYUU 官方说明,IYUU 任何时候都不需要映射资源目录。因为 IYUU 只是辅助 qBittorrent 和 transmission 而已,真正操作磁盘文件的是两个下载器。

IYUU 辅种

首先确保 transmission 与 qBittorrent 的下载路径一致

下载器

站点

绑定一个通过认证的站点,否则无法使用 IYUU 的功能

然后添加需要辅种的站点即可

辅种任务

在任务管理中添加辅种任务

  • 辅种下载器:种子来源,选择在 下载器 中设置的哪些下载器需要进行辅种。
  • 主辅分离:专门用一个下载器来辅种

我的种子量不大,懒得做转种,因此我把所有辅种全部放到了 transmission,这样整体结构比较简单。

配置完成之后,跑一下看看: