Docker实践——MDC与plex
步骤/目录:
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)MDC
Movie_Data_Capture 刮削软件,项目地址 。可以识别本地视频文件名,到Java网站上查询,下载海报,生成nfo文件(这些工作称为刮削),根据主演名创建文件夹。
其它类似的软件有AVDC,MDCx(原作者似乎在23-10-4删库),tinyMediaManager(正常情况下用的最多。这里不用tMM是因为本文主要讨论不正常的情况),EverAver(只能对单部电影刮削)等。
另外,对于英语电影,可以使用tMM + 插件,具体可参考 提供插件的网站 (该网站目前转移到了 另一个地址 )。在该插件网站注册一个账号,右上角点击头像可获得API token,MDCx可填入该API,或者tMM安装插件后也需填入该API。tMM插件的github项目地址 在此 ,把插件放到tMM安装路径的Addons文件夹里(新建一个)。
(2)Plex
plex官网 ,一个功能比较齐全的本地影音库解决方案。在存放电影文件的本地电脑上安装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/演员名.jpg
plex容器自带了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 autoremove
b.查看显卡是否可用CUDA
update-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-toolkit
d.安装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 crio
f.安装显卡驱动
参考 官网文章 。
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即可。