步骤/目录： 1.背景介绍 （1）MDC （2）Plex 2.MDC的使用 3.EverAver的使用 4.Plex的使用 （1）XBMCnfoMoviesImporter插件下载 （2）安装与设置 5.linux + docker安装plex （1）docker-compose的编写 （2）插件与设置 （3）头像 a.失败方法一 b.失败方法二 c.总结 d.方法三 e.方法四 f.修改nfo标签 （4）内网穿透 （5）显卡加速（未实操） a.卸载之前的CUDA、驱动 b.查看显卡是否可用CUDA c.安装NCT d.安装CRI-O e.配置 f.安装显卡驱动 g.安装驱动后检查 h.plex-docker开启硬件加速本文首发于个人博客https://lisper517.top/index.php/archives/92/，转载请注明出处。本文的目的是对本地电影文件进行整理，并搭建个人影音库。本文写作日期为2023年11月30日。用到的系统有win10、Ubuntu 22.04 LTS。1.背景介绍在 Python，爬虫与深度学习（17）——电影的信息爬取、下载与处理（二） 一文中，笔者曾经试图对本地电影文件进行压缩，并通过mysql库管理。压缩视频没有什么问题，但是根据视频文件名进行查询、归类时，由于文件名参差不齐，涉及的爬虫知识又比较复杂，笔者还想对视频内容进行比对，却一直没有好的解决办法。好在互联网上总是有人在做相似的项目，今天介绍的MDC就比较好地满足了这类需求。在文件管理上，笔者选择用废旧笔记本装linux连硬盘，Samba共享，详情参考 树莓派+Samba+frp搭建NAS（网络云存储） 。当然，树莓派的孱弱性能不太适合装plex，这里用笔记本代替。（1）MDCMovie_Data_Capture 刮削软件，项目地址 。可以识别本地视频文件名，到Java网站上查询，下载海报，生成nfo文件（这些工作称为刮削），根据主演名创建文件夹。其它类似的软件有AVDC，MDCx（原作者似乎在23-10-4删库），tinyMediaManager（正常情况下用的最多。这里不用tMM是因为本文主要讨论不正常的情况），EverAver（只能对单部电影刮削）等。另外，对于英语电影，可以使用tMM + 插件，具体可参考 提供插件的网站 （该网站目前转移到了 另一个地址 ）。在该插件网站注册一个账号，右上角点击头像可获得API token，MDCx可填入该API，或者tMM安装插件后也需填入该API。tMM插件的github项目地址 在此 ，把插件放到tMM安装路径的Addons文件夹里（新建一个）。（2）Plexplex官网 ，一个功能比较齐全的本地影音库解决方案。在存放电影文件的本地电脑上安装plex media server，只要该本地电脑能联网，就能在外网通过plex的客户端（安卓，苹果，Windows，Mac）或者网页端访问、管理电影文件。当然，在外网看是要花钱充会员的（在局域网内不用钱，所以也可以内网穿透）；且plex只能用自带的播放器。其实plex和流媒体有很多相似之处，也能看一些电视、美剧。需要注意的是，plex也可对电影进行识别（文件名，还会对视频内容进行比对），获得海报、生成nfo，但在一些细分领域的识别正确率不高。plex需要使用XBMCnfoMoviesImporter插件才能识别本地的nfo文件，这将在之后讲解。其它类似的有Jellyfin、Emby（Jellyfin是Emby的开源版本，Jellyfin疑似在文件较多时无法运行），Jvedio（可以用本地播放器，缺点是电影名的.必须改成-）等。plex是目前最成熟的影音管理软件，但是也有其它小问题。2.MDC的使用由于涉及爬虫，运行时请确认能够访问外网，最好是日服。可参考 Docker实践——如何查阅wiki百科及V2Ray 或者 Google云的免费使用。在 MDC发行版 中选择合适的版本进行下载。需要注意MDC最新的版本（7.0.1以后）开始内测，需要付费，有实力的读者可以支持一波。本文使用免费的6.6.7版本（最后一个免费版本）进行演示。对压缩文件解压，得到config.ini（配置文件）和exe文件。配置文件修改以下几处：stop_counter = 10 #默认为stop_counter = 0 rerun_delay = 1m #默认为rerun_delay = 0 [watermark] switch = 0 #默认为switch = 1 [storyline] switch = 0 #默认为switch = 1更多配置选项参考 配置说明 （该6.6.7版本配置说明网页在本文写作的这几天已失效）。接下来，将ini文件和exe文件放到存放电影的文件夹中（建议先用少量几部电影试验），把V2Ray改为全局模式，运行exe文件，等待一段时间。如果无法访问日服，MDC可能有些差错，可尝试上文提到的其它软件，推荐MDCx。第一次试刮削后，可自行更改配置，换其它刮削软件尝试，找到适于自己的软件及设置。3.EverAver的使用非常简单，把文件拖拽到软件框中即可。对于少量刮削出错的，使用EverAver单独刮削，或者使用其它软件的单独刮削功能。由于该软件19年后就没有更新过，现在也能用，但不推荐。4.Plex的使用（1）XBMCnfoMoviesImporter插件下载在github项目地址中按照最下面的指示操作即可，看不懂英文就看本文接下来的操作。首先下载XBMCnfoMoviesImporter的zip包，解压并将文件夹改名为 XBMCnfoMoviesImporter.bundle （此时该文件夹下应该有Contents文件夹，不要多套了一层），放到plex的插件目录下（Windows在安装目录的 Plex Media Server\Resources\Plug-ins-xxxxxxxxx 下，参考plex官网帮助）。如果除了电影，还有看电视剧的需求，可以装 XBMCnfoTVImporter插件 ，作者是同一个人。（2）安装与设置没什么特别的，安装即可。安装好后，右下角的任务栏会有plex图标，左键双击可点开网页，注册一个账号登录。在右上角 设置 - 管理 - 媒体库 -添加资料库 可新增电影库，在 高级 - 代理 中注意选择 XBMCnfoMoviesImporter ，plex才能识别本地的nfo文件。5.linux + docker安装plex在前文提到过，笔者使用的是 旧笔记本（Ubuntu 22.04）连硬盘+SMB分享 ，所以最好能在Ubuntu上装plex。步骤如下：（1）docker-compose的编写在Ubuntu命令行中如下操作：su root mkdir -p /docker/plex/conf/plex ls -l NAS硬盘挂载目录 chown -R 用户名:用户组 /docker/plex/conf id 用户名查看NAS硬盘目录所属的用户、用户组，修改目录到该用户及组下，记下uid、gid。vim /docker/plex/docker-compose.yml在docker-compose文件中写入如下内容：version: "3.9" services: plex: image: lscr.io/linuxserver/plex:latest container_name: plex network_mode: host environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - VERSION=docker - PLEX_CLAIM= #optional volumes: - /docker/plex/conf/plex:/config - /path/to/tvseries:/tv - /path/to/movies:/movies restart: unless-stopped修改 PUID 和 PGID ；修改 /path/to/tvseries 和 /path/to/movies 分别为存放电视剧、电影的地方，或者随便怎么挂载，这个不是死的。需要注意的是 /config 是存放影音库等配置的地方，影像较多时留50GB的空间比较稳妥（等下也会将XBMCnfoMoviesImporter插件放到这里）。最后需要注意的是， /config 如果挂载到宿主机的机械硬盘上，plex会自动对视频截图作为封面，而不使用MDC刮削的封面，这可能与硬盘读取速度有关，所以 /config 一定要放在固态硬盘上。最后docker run：cd /docker/plex docker-compose config docker-compose up等待pull并成功run后，退出并后台运行：docker-compose up -d如果设置了防火墙，记得打开32400端口：ufw allow 32400（2）插件与设置插件方面，linux与windows下的插件是通用的。按前文的步骤，把XBMCnfoMoviesImporter.bundle放到 /docker/plex/conf/plex/Library/Application Support/Plex Media Server/Plug-ins 下即可，然后 docker-compose restart 一下。浏览器访问 笔记本本地ip:32400/web 即可进入plex media server网页。登录账号，跟随引导即可，添加电影库的操作也是一样的（如果在其它电脑上也装过plex，此时注意选择笔记本。此前实验时创建的其它电脑，在设置里可以删除），同样先用一个test文件夹、少量几部电影测试一下。笔者还进行了如下设置：允许我在家庭外访问我的媒体 取消勾选 启用电影预告片 取消勾选 启用视频预览缩略图 取消勾选 包含相关的额外内容 取消勾选对XBMCnfoMoviesImporter：Enable debug logging 勾选上（3）头像使用刮削软件生成的nfo文件，其中演员头像也是可以在plex中显示的（比如MDCx生成的nfo，演员头像在 <actor> 标签的 <thumb> 里，是 .actors/演员名.jpg ），但是需要一些操作。先到 gfriends项目 下载别人整理好的演员头像，然后进行一些设置。a.失败方法一根据这个提问下提问者的说法，在XBMC插件的设置中，把 actor thumb location 设置为link， path to movie library or global actor folder 不用管，在nfo里把thumb标签改成头像图片的绝对路径。失败，演员头像显示为黑，上面没有演员名的首字。b.失败方法二该提问者在后面的回答中提出，把 actor thumb location 设置为global， path to movie library or global actor folder 填存放演员头像的目录（如 /movies/actor_photo ，该目录下存放所有的头像jpg图片）。同样失败，同样显示黑图。以上两种方法，提问者都是在windows下运行，笔者在linux，可能有影响。c.总结在另一个问题中提到，存放头像的整个路径上都不能有空格，要用 _ 替代空格。源文件的 __init__.py 负责该设置，从750行的 if athumbloc in ['local','global']: 开始，这里其实有把空格替换成下划线。plex获得演员头像困难的根源在于它虽然管理本地电影，但核心是围绕线上刮削+本地缓存的，也就是说电影的海报、演员头像都需要从plex提供的数据库获取，缓存到自己的server上，完全没有考虑过server本地提供nfo、海报（不装XBMC插件，根本识别不了本地nfo），也不想让你碰缓存的数据。另一个问题是它会优先用本地缓存的图片，如果你更新了一些图片则它还是会显示以前的图片，解决方法可能是 扫描资料库文件 ，或者删除影音库再重建。在第一个提问中，提问者说头像显示为黑图说明plex已经缓存了图片（显示名字首字母说明没有缓存）。笔者在 /docker/plex/conf/plex 下查找了所有jpg图片，并没有缓存的头像。使用 grep -iR "actor photo" /docker/plex/conf/plex 也没发现有用的log信息（但是在最终的方法中还是找到了有用的log）。有人还提到，nfo里的thumb标签会覆盖掉 actor thumb location 和 path to movie library or global actor folder 设置，所以设置成local或者global时要删掉（这个不完全对，笔者设置link+ http://localhost 、thumb标签是 actor/演员名.jpg ，log里发现XBMC把它们拼接成了 http://localhostactor/演员名.jpg ）。d.方法三有人对XBMC插件进行了修改，名为 JAVnfoMoviesImporter.bundle ，安装方式和原来相同，不同在于它会在线从前面提到的gfriends项目获得演员头像。由于从github上刮削，可能需要翻越。而且gfriends项目作者已经停止更新，一些新人可能没有头像（这个可能性不大，因为还是有人在零散提交）。笔者没有使用这种方法，主要是想在本地存头像，一些演员的头像拍丑了、想用自己的图。e.方法四在第二个问题的最后，有人提出了另一种解决方案，稍微修改一下 __init__.py ，然后在docker-compose里另建一个nginx容器来提供头像链接；或者也可以不改 __init__.py ，只建nginx容器，笔者尝试也可以。不过改不改py文件，nfo文件都是要修改的。操作如下：cd /docker/plex docker-compose stop mkdir -p /docker/plex/conf/nginx chown -R 用户名:用户组 /docker/plex/conf vim /docker/plex/conf/nginx/default.conf写入nginx配置：server { listen 80; server_name localhost; location / { root /var/www/html; index index.php index.html index.htm; } }然后修改docker-compose.yml：vim /docker/plex/docker-compose.yml修改如下：version: "3.9" services: plex: image: lscr.io/linuxserver/plex:latest container_name: plex network_mode: host environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - VERSION=docker - PLEX_CLAIM= #optional volumes: - /docker/plex/conf/plex:/config - /path/to/tvseries:/tv - /path/to/movies:/movies restart: unless-stopped nginx: image: nginx:1.23.1 ports: - "80:80" volumes: - /docker/plex/conf/nginx:/etc/nginx/conf.d - 存放头像的目录:/var/www/html logging: driver: syslog restart: always如果你已经用了笔记本的80端口，也可以改成其它端口（比如改成9090端口： 9090:80 ）。ufw allow 80 cd /docker/plex docker-compose config docker-compose up -d现在测试一下nginx图片服务器能否正常工作。在浏览器打开 笔记本内网ip/图片名.jpg （或者 笔记本内网ip:9090/图片名.jpg ），应该能看到头像图片。最后设置一下plex（其实就是保持默认设置）， actor thumb location 设置为link， path to movie library or global actor folder 保持为 http://localhost （可以直接删掉并保存，XBMC会自动填充这个值）。重点是nfo文件里，thumb标签的值，改成 http://localhost/演员名.jpg 即可（如果nginx用的不是80端口，这里应该填 http://localhost:端口号/演员名.jpg ）（有些刮削软件填的是 .actors/演员名.jpg ，适用于EMBY等其它影音管理软件）。这时nfo里的thumb标签确实会覆盖掉头像的链接。测试一下，把之前测试的几部电影剪切走，换成其它新的电影，能正常显示演员头像。最后修改一下nginx的设置，不要把nginx容器的端口暴露到宿主机上。如下操作：ufw delete allow 80 cd /docker/plex docker-compose stop vim /docker/plex/docker-compose.yml把端口映射删掉，如下：version: "3.9" services: plex: image: lscr.io/linuxserver/plex:latest container_name: plex network_mode: host environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - VERSION=docker - PLEX_CLAIM= #optional volumes: - /docker/plex/conf/plex:/config - /path/to/tvseries:/tv - /path/to/movies:/movies restart: unless-stopped nginx: image: nginx:1.23.1 volumes: - /docker/plex/conf/nginx:/etc/nginx/conf.d - 存放头像的目录:/var/www/html logging: driver: syslog restart: always然后删除并重新构建：docker-compose stop nginx docker-compose rm nginx #按y确认 docker-compose config docker-compose up -d需要注意的是thumb标签的值稍微有所不同。docker container ls其中会有一个 plex-nginx-1 容器（老版本的docker-compose可能是plex_nginx_1或者其它名称）。查看它在容器组合里的ip：docker inspect plex-nginx-1 | grep IPAddress比如说是172.22.0.2，那么thumb标签的值就改成 http://172.22.0.2/演员名.jpg 。如果对docker有经验的读者，可能会想改成 http://nginx/演员名.jpg 或者 http://plex-nginx-1/演员名.jpg ，可以进入plex容器来验证：docker exec -it plex bash cd /tmp wget http://nginx/演员名.jpg wget http://plex-nginx-1/演员名.jpg wget http://172.22.0.2/演员名.jpgplex容器自带了wget命令，但最终只有改成ip值才行。f.修改nfo标签把所有thumb标签的值从 .actors/演员名.jpg 改成 http://172.22.0.2/演员名.jpg 。使用如下python脚本：#!/usr/bin/python3 # -*- coding: UTF-8 -*- import os dir = r'电影存放目录' content = '' def main(): global content for dirpath, dirnames, filenames in os.walk(dir): for filename in filenames: suffix = os.path.splitext(filename)[-1].upper() if suffix != '.NFO': continue abs_path = os.path.join(dir, dirpath, filename) with open(abs_path, 'r+', encoding='utf-8') as f: content = f.read() if content.find(r'<thumb>.actors/') == -1 and content.find( r'<thumb>http://172.22.0.2/') == -1: print(f'没有头像{abs_path}') content = content.replace(r'<thumb>.actors/', r'<thumb>http://172.22.0.2/') f.close() with open(abs_path, 'w', encoding='utf-8') as f: f.write(content) f.close() if __name__ == "__main__": main() 每次有新文件，刮削后运行一次即可。（4）内网穿透plex在外网访问需要开会员，2023年，费用大约是包月$5、包月$40、永久$120，有需要的可以购买。从学术研究的角度，也可以尝试用内网穿透（前提是有公网ip，像前文提到的Google云服务器），比如用frp，映射笔记本的32400端口即可。可参考 Docker树莓派实践——frp（附dashboard开启https、frp双向验证） ；或者能访问ipv6的，笔者更建议 IPv6 + DDNS （能跑满家里的上传带宽），见 IPv6与DDNS ，这里不再赘述。（5）显卡加速（未实操）如果在自己的电脑上观看该电脑上的视频，会使用该电脑的显卡解码；如果用自己的电脑观看云视频，就涉及到在服务器端还是在客户端解码的问题。plex解码笔者不太清楚，按常理来说用手机看最好在服务器端解码（本文为例就是笔记本上解码），用PC就在客户端解码。如果笔记本用的是Nvidia某些型号的显卡，可以用显卡解码，毕竟CPU硬解码还是比较占CPU。笔者测试时，观看720p电影，CPU占用不大（ top 命令，或者 watch -d -n 1 cat /usr/local/watchdog/cpu_temperature 看CPU温度），没有开硬件加速的必要。在 docker-plex 的 Nvidia 小节，提到了开启显卡加速的方法，即先安装 nvidia-docker ，然后运行一个nvidia容器（加 --runtime=nvidia ），plex容器则在yml里写 -e NVIDIA_VISIBLE_DEVICES=all （或者把 all 换成UUID来指定特定显卡。 nvidia-smi --query-gpu=gpu_name,gpu_uuid --format=csv 可查看GPU的UUID）。可惜的是，截止23年12月，nvidia-docker这个项目已经废弃了，转而被NVIDIA Container Toolkit取代。接下来就演示用NCT为plex开启显卡加速（笔者没有实操）。a.卸载之前的CUDA、驱动如果之前装过CUDA，或者在本次流程装CUDA时出现了意外，可以卸载后重装。根据 Nvidia官方文档 ，执行以下命令：sudo apt-get --purge remove "*cuda*" "*cublas*" "*cufft*" "*cufile*" "*curand*" \ "*cusolver*" "*cusparse*" "*gds-tools*" "*npp*" "*nvjpeg*" "nsight*" "*nvvm*" sudo apt-get --purge remove "*nvidia*" "libxnvctrl*" sudo apt-get autoremoveb.查看显卡是否可用CUDAupdate-pciids lspci | grep -i nvidia获取当前的显卡型号，到 NVIDIA官网 比对，是否能开启CUDA。如果不能，就不需要进行接下来的步骤了（没有对应的显卡驱动）。根据官方的 这个回答 ，2008年以后制造的英伟达显卡都支持CUDA（包括笔记本），所以N卡其实可以无脑装。c.安装NCT参考 NCT安装官方指南 。为笔记本开启翻越，进行如下操作（Ubuntu下。其它发行版参考原文）：curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list可以更新一些实验性功能包，一般情况下没必要。sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list安装即可。apt-get update apt-get install -y nvidia-container-toolkitd.安装CRI-O接下来需要用到CRI-O，不太清楚是什么东西，好像是docker的某种替代或者补充，笔者还没装过。安装CRI-O（参考 这篇文章 ）：apt update apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common -y export OS=xUbuntu_22.04 export CRIO_VERSION=1.24 echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /"| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$CRIO_VERSION/$OS/ /"|sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION.list curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION/$OS/Release.key | sudo apt-key add - curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key add - apt update apt install cri-o cri-o-runc -y systemctl start crio systemctl enable crio systemctl status crio参考文章后面还有一些附加的内容，这里没有继续。e.配置第一个配置会调整宿主机的 /etc/docker/daemon.json 文件，使得docker可以使用NVIDIA Container Runtime。nvidia-ctk runtime configure --runtime=docker systemctl restart docker第二个配置会调整 /etc/containerd/config.toml 文件，使得containerd可以使用NVIDIA Container Runtime。nvidia-ctk runtime configure --runtime=containerd systemctl restart containerd第三个配置调整 /etc/crio/crio.conf 文件，使得CRI-O可以使用NVIDIA Container Runtime。nvidia-ctk runtime configure --runtime=crio systemctl restart criof.安装显卡驱动参考 官网文章 。apt-get install linux-headers-$(uname -r) distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed -e 's/\.//g') wget https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-keyring_1.0-1_all.deb dpkg -i cuda-keyring_1.0-1_all.deb apt-get update apt-get -y install cuda-drivers这个是通过包管理安装，没有 /usr/local/cuda-版本号/nvcc 。g.安装驱动后检查参考 官方说明 。h.plex-docker开启硬件加速运行一个CUDA容器（这里笔者不是很确定）：docker run --runtime=nvidia --gpus all ubuntu nvidia-smi在plex-docker的docker-compose.yml中增加环境参数： -e NVIDIA_VISIBLE_DEVICES=all ，重新build即可。