使用Plex & Docker搭建自己的媒体服务器

Plex是Plex,Inc.制造的全球流媒体服务和客户端服务器媒体播放器平台。PlexMedia Server整理用户收藏和在线服务中的视频,音频和照片,并将其流式传输到播放器。尽管提供多种媒体服务, 我这里的需求只是流媒体播放我的本地音乐集还有R音声作品而已,所以关于后面的媒体配置相关都是关于音乐 的, 使用 Docker 和 linuxserver 提供的 镜像 搭建Plex Server非常简单

部分截图:

Music Library

Music Library

image-20210420121417478

Music Album

image-20210420121148416

Playing Music

image-20210420150223086

Music Artist

相比与同类型的开源选择Jellyfin, 界面更加漂亮,依赖于大公司的技术使用体验也更加好,接下来我们将要使用 Docker 搭建自己的服务

你需要准备的东西有

  • NAS设备(树莓派4B即可) + 公网IP/内网穿透 / 土豪直接买云服务器
  • 了解docker 和 docker-compose工具,命令配置的基本使用

搭建Plex Server

新建文件夹plex, 创建docker-compose.yml

BASH

1
2
mkdir plex && cd plex
touch docker-compose.yml

写入下面的配置

YML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: “2.1”
services:
plex:
image: linuxserver/plex
container_name: plex
environment:
– PUID=1000
– PGID=1000
– VERSION=docker
– PLEX_CLAIM=your-claim
volumes:
– ./config:/config
– /path/to/your/music/library:/musics:ro
restart: unless-stopped
mem_limit: 700m
memswap_limit: 2000m
devices:
– /dev/dri:/dev/dri #optional
ports:
– 32400:32400

需要注意的几点:

  • PUIDPGID用于配置容器内进程的UIDGID, 全都设置为0表示以root用户运行,如果你这里不是很明白的话可以无脑设置为0以避免部分权限问题
  • mem_limitmemswap_limit属于可选项, 如果你(我)使用 2GB 内存的树莓派你可能会担心超出内存而出现的问题(一般出现在扫描媒体时, 日常占用并不大, 2GB内存足矣),如果你的内存充足的话,完全可以忽略这两个配置项
  • PLEX_CLAIM环境变量用于认证自己的服务器,也是可选, 你可以从 这里 获取(注意需要可用的plex账号), 另外claim的有效期一般只有 4 分钟 ,如果服务器网络不佳,建议先通过执行docker-compose pull拉取镜像之后再获取,防止过期(虽说过期后再重新claim也行)
  • /path/to/your/music/library:/musics:ro 将自己本地的音乐库映射到plex container的/musics目录, 并且只读(roread only),你可以将自己用nextcloudsyncthing同步过来的曲目映射到这里

执行docker-compose up然后静待服务器启动完成, 启动完成后可以访问ip:32400/web进入web界面

检查你的远程访问有没有正确开启, 成功的示例如下

image-20210421114615816

由于我端口映射并非标准的32400端口, 所以这里手动指定了一下自己的端口

如果已经成功了的话, 你就可以在plex官网看到自己的 server 了, 接下来你可以按照提示设置自己的媒体库, 至于音乐库相关的高级选项可以参考下面的解释

image-20210421114937537

移动端示例截图

Albums
Playing Music

音乐相关高级配置解释

扫描器和代理这两个选项不用考虑, 默认就行, 其中Plex Music是最近几个版本更新的扫描器, 性能更好,扫描速度明显快于旧的Plex Music Scanner

image-20210421113102215

从网易云下载的曲子一般会自带正确的ID3tag, 我们这里可以直接选中Prefer local metadata , 让扫描器优先使用自带的tag.

Artist Bios 歌手信息。推荐保持选中, 我这里没有选中是因为我歌单里面太多冷门优秀歌手/作曲比如 Acyanxi, plex拉取不到这些歌手/作曲的信息,导致后面只有一小部分歌手有封面而多数都没有, 强迫症的我直接把这个选项给关了。

Album Reviews and Critic Ratings , Popular Tracks Concerts 歌曲评价相关,热门曲目和演唱会信息 我个人认为没有必要没有打开, 你可以根据自己的情况选择, 我没有打开, 毕竟热门的并不代表适合自己, 演唱会又不能去(没钱买机票), 我觉得好听的就是最好的, 看xx评价

Genres 注意网易云给的 tag 中的Genres都是空的, 如果你认为音乐风格对你来说有必要可以保持默认的Plex Music选项,虽然并不保证一定能得到

Album Art专辑封面, 网易云提供了, 所以我直接选择了Local Files Only

Scanning

Scanning

自用脚本分享 – 转移本地音乐到Plex

NCM 文件批量解码

PYTHON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
from ncmdump import dump
from pathlib import Path

source_dir = Path(r”F:\Musics\netease”) # 网易云音乐下载根目录


def output_path(input_path: Path, metadata) -> str:
return (input_path.parent /
(input_path.stem + “.” + metadata[‘format’])).__str__()


if __name__ == ‘__main__’:
for file in source_dir.iterdir():
if file.name.endswith(‘.ncm’):
print(str(file))

dump(file, output_path, skip=True)
os.remove(file)

ncmdump模块来自https://github.com/nondanee/ncmdump, 你可以通过执行下面的命令安装依赖和ncmdump

BASH

1
2
pip install pycryptodome mutagen
pip install git+https://github.com/nondanee/ncmdump.git

删除重复文件

网易云音乐下载的曲目有可能会出现重复下载的情况, 一般情况下重复下载的曲目文件名称有比较明显的特征,例如XX - XXX (1).mp3, 可以通过这个特征删除掉重复的下载的曲目

PYTHON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pathlib import Path
import re
import os

source_dir = Path(r”F:\Musics\netease”) # 网易云音乐下载根目录
target = re.compile(r”^.+\([1-9]\)\.(mp3|ncm)$”)

if __name__ == ‘__main__’:
for file in source_dir.iterdir():
if not file.name.endswith((“.mp3”, “ncm”)):
continue

if target.match(file.name):
print(file)
os.remove(file)

目录转移(Plex推荐格式)

plex推荐了音乐相关的目录格式为

PLAINTEXT

1Music/ArtistName/AlbumName/TrackNumber – TrackName.ext

例如

PLAINTEXT

1
2
3
4
5
6
7
8
9
10
11
/Music
/Pink Floyd
/Wish You Were Here
01 – Shine On You Crazy Diamond (Parts I-V).m4a
02 – Welcome to the Machine.mp3
03 – Have a Cigar.mp3
/Foo Fighters
/One By One
/There is Nothing Left to Lose
/U2
/Joshua Tree

如果一首曲子存在多个artists, plex推荐使用 Various Artists作为ArtistName, 搞不清理由,由于我下载的曲目太多是多艺术家创作的, 都放在这样的文件夹里让我感觉很乱,因此并没有遵守这个推荐规则

为了后面新增曲目时能快速找到哪些是新增的曲目, 我这里随便使用了sqlite保存了源文件目录的位置

PYTHON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from pathlib import Path
from mutagen.id3 import ID3
import shutil
import sqlite3

source_dir = Path(r”F:\Musics\netease”) # 网易云音乐下载根目录
target_dir = Path(r”F:\nextcloud\Musics\NETEASE”) # 想要转移的目的根目录
db_path = ‘music.db’

def safe_name(name: str) -> str:
“””this function is awful and if you got a better one, just tell me
“””
return name.replace(“/”, “/”).replace(“:”, “:”).replace(“>”, “❯”).replace(
“|”, ” “).replace(“<“,
“❮”).replace(“\\”, ” “).replace(“?”, “?”).replace(
‘”‘, “‘”).replace(“*”, “*”).strip().strip(‘.’)


if __name__ == ‘__main__’:
con = sqlite3.connect(db_path)
cur = con.cursor()

# Create table if not exists
cur.execute(”’CREATE TABLE IF NOT EXISTS musics
(path text NOT NULL PRIMARY KEY)”’)

for source_file in source_dir.iterdir():
if source_file.name.endswith(“.ncm”):
continue

source_file = source_file.absolute()
cur.execute(“SELECT * FROM musics WHERE path = ?”, [str(source_file)])
if cur.fetchone(): # 已经出现在数据库中, 直接跳过
continue

metadata = ID3(source_file)
artist = source_file.name.split(‘-‘)[0].strip().split(‘,’)[0]
try:
album = safe_name(metadata.get(“TALB”).text[0])
except AttributeError:
print(source_file, “has no album, just skipped”)
continue

target_file: Path = target_dir / artist / album / source_file.name

if target_file.exists():
# Insert a row of data
cur.execute(“INSERT INTO musics VALUES (?)”, [str(source_file)])
con.commit()
continue

if not target_file.parent.exists():
target_file.parent.mkdir(parents=True, exist_ok=True)

shutil.copy(source_file, target_file)

# Insert a row of data
cur.execute(“INSERT INTO musics VALUES (?)”, [str(source_file)])

con.commit()

con.close()

Claim | Plex

文章作者: Hinata Rin

原创文章,作者:Go,如若转载,请注明出处:https://www.smallogs.com/?p=433

(0)
Go的头像Go
上一篇 2024-04-29 15:13
下一篇 2024-05-06 13:25

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注