Jellyfin 自建影音库:海报墙、多用户与硬件转码

admin 开源软件 2026-09-21 5 0

硬盘里攒了几 T 的电影和剧,接上电脑打开文件夹,文件名乱七八糟,想找去年看过的那部得翻十分钟。想在客厅电视上看,投屏要装一堆 App,或者干脆抱着笔记本接一根 HDMI 线。好不容易播上了,片名、封面、简介全没有,屏幕上一排文件图标。再加上商业媒体服务器这两年把硬件转码、多用户这些功能往付费里挪,界面里还塞广告,不少人就是那时候开始找替代品的。

Jellyfin 是自建这条路里最常被选中的一个。它把「一堆文件」变成「一个片库」,并且不花钱、不埋广告。

它能干什么

项目内容
媒体库指定目录后自动扫描,按电影、剧集、音乐分类整理
刮削自动获取海报、简介、评分、演职员和播出信息
剧集识别按季和集组织,自动排序,支持下一集连续播放
多用户每个账号独立的观看记录,可以给儿童账号限制分级
硬件转码用核显把高码率片源实时转成客户端吃得下的码率
字幕内嵌与外挂都支持,可在线搜索,图形字幕可转文字
直播电视接电视卡或网络电视源,做节目表和定时录制
客户端网页、安卓、iOS、电视盒子、智能电视,也有第三方播放器

核心体验是那张海报墙:打开就是一张张封面,点进去有简介和进度条,手机上看到一半,回客厅打开电视能接着看。这一层是它真正值钱的地方,不是播放器,而是把无序的文件变成有序的片库。

Docker 部署

mkdir -p /opt/jellyfin/config /opt/jellyfin/cache

docker run -d \
  --name jellyfin \
  --restart unless-stopped \
  -p 8096:8096 \
  -v /opt/jellyfin/config:/config \
  -v /opt/jellyfin/cache:/cache \
  -v /srv/media/movies:/media/movies:ro \
  -v /srv/media/tv:/media/tv:ro \
  --device /dev/dri:/dev/dri \
  jellyfin/jellyfin

几个要点:

  • 8096 是网页端口。它还会用 7359 做局域网自动发现、1900 做 DLNA,想让电视自己找到服务器的话,这两个 UDP 端口也要能通
  • 配置目录必须持久化,那里放着数据库、元数据和播放进度
  • 媒体目录挂载时加 :ro,只读。这是个很小的习惯,能挡住你在客户端里一不小心的删除操作
  • /dev/dri 是核显设备节点,没有核显就把这行去掉

compose 写法

services:
  jellyfin:
    image: jellyfin/jellyfin
    container_name: jellyfin
    restart: unless-stopped
    ports:
      - "8096:8096"
      - "7359:7359/udp"
      - "1900:1900/udp"
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /srv/media/movies:/media/movies:ro
      - /srv/media/tv:/media/tv:ro
    devices:
      - /dev/dri:/dev/dri
    environment:
      TZ: Asia/Shanghai
      PUID: 1000
      PGID: 1000
    group_add:
      - "989"

group_add 里那个数字是宿主机上负责显卡设备的组 ID,用 getent group video 或者 getent group render 查一下再换掉。容器内的进程不在这个组里,就没有权限打开核显,硬解会一直失败而你又看不出原因。

首次配置向导

  1. 浏览器打开 8096,选界面语言,中文在列表里
  2. 创建管理员账号。密码别太随意,将来这套东西可能要暴露给外网
  3. 添加媒体库,选对内容类型:电影选「电影」,剧集选「节目」,选错了刮削时根本找不到合适的元数据源
  4. 目录填容器里的路径,比如 /media/movies,不是宿主机的路径,这是最容易填错的一栏
  5. 元数据语言选中文、国家选中国,这两项决定了简介、封面上的文字是什么语言
  6. 把「自动为所有媒体生成缩略图」之类的选项先关掉,除非你硬盘和 CPU 都很闲

向导跑完先别急着灌片子。等你把命名规范那节读完、把目录理顺,再一次性扫描,能省掉后面大量的手工修正。

命名规范:能不能正确刮削就看这个

刮削器是拿文件名和目录结构去匹配的,命名不规范它只能猜。电影目录的标准样子:

/media/movies/
  让子弹飞 (2010)/
    让子弹飞 (2010).mkv

剧集更严格,需要「剧名 / 季 / 集」三层,集号用 S01E01 的格式:

/media/tv/
  黑镜 (2011)/
    Season 01/
      黑镜 S01E01.mkv
      黑镜 S01E02.mkv
    Season 02/
      黑镜 S02E01.mkv

几个细节:年份放在括号里,用来区分重名影片;季目录写 Season 01 这种两位数,简写成 S01 也行,但别写成「第一季」;同一个影片有多个版本(比如 1080p 和一个 4K 版本),文件名后面加个短横线加版本名,它会把它们认成同一部片的不同版本,而不是两部电影。

做不到这些的结果很典型:整部剧被识别成一集,或者每一集都变成刮不到任何信息的孤儿条目,海报墙上全是灰色方块。

硬件转码:开还是不开

结论先说:有核显就开,没有就别硬撑。

转码的意义在于:片源是 4K 高码率,而你的电视或手机只吃得下 1080p、或者上行带宽不够,服务器得实时把画面缩小、重新编码再推过去。这件事落在 CPU 上是灾难,落在核显上是小活。

有核显的机器把 /dev/dri 挂进容器,在控制台的「播放 - 转码」里启用硬件加速,选对编码器,再把支持的格式逐项勾上。开对了之后,一部 4K 转 1080p 的片子可能只占百分之十几的 CPU,风扇都不怎么转;开错了或者权限没给到,表现是播放一直转圈,日志里一片错误。

没有核显的纯软解,1080p 单路勉强,4K 基本没戏。这种情况下更实际的做法不是升级 CPU,而是让客户端直连:把码率上限放开甚至关掉转码,让播放器自己解。现在的电视盒子解码能力比很多老服务器强得多,别拿服务器的短处去补客户端的长处。

远程访问的三种方式

第一种,局域网直连。什么都不用配,同一网段内电视和手机能自己发现服务器,速度最快,日常绝大多数时间用这一种。

第二种,反向代理加域名。Nginx 把域名转到 8096,配上证书,任何地方都能用浏览器打开、用 App 登录。注意转发 websocket 相关的请求头,并且把请求体上限和超时时间放宽,否则加载大封面、同步播放进度都会出问题。

第三种,VPN。在外面先连回家里的网络,再用局域网地址访问。配置最麻烦但最安全,也不需要把服务暴露给公网。家里路由器能跑 VPN 的话,这是最省心的方案。

不建议直接把 8096 端口映射到公网。它没有为公网环境做过加固,暴露出去等于把家里的片库交给扫描器。

几个真会踩到的坑

  1. 中文片名刮不到。元数据语言设成英文了,或者文件名里没带年份。改语言、补年份,然后对那个条目手动刷新元数据,别指望再扫一遍就自己好。
  2. 一集被识别成一堆。命名不规范,或者目录里混着样本文件、说明文件、花絮。清掉无关文件,按规范重命名,删掉旧条目重新扫描。
  3. 4K 播放时 CPU 跑满、风扇狂转。硬解没真正开成,或者客户端在强制转码。控制台的播放信息里会写转码原因,通常写着容器不支持或者码率超限,照着原因改。
  4. 字幕乱码。老字幕是 GBK 编码,按 UTF-8 解就是满屏乱码。在字幕设置里指定编码,或者用工具统一转成 UTF-8。
  5. 手机在外网播放卡。默认码率上限太低或者家庭上行不够。客户端里限制码率,服务端把转码开起来,让它按你的上行带宽输出。
  6. 媒体目录忘了只读。客户端里一个误操作就能删掉原片。挂载时加只读,是最省事也最有效的一道防线。

适合你,不适合你

适合:手里有几百 G 到几十 T 的影视资源;想给家里人一套打开就能看的体验,不用教他们找文件;有 NAS 或闲置机器,愿意花一个晚上折腾。

不适合:只想看几个在线平台的剧;完全不想整理文件名和目录;机器是十年前的笔记本还指望它转 4K。这套东西能跑得舒服的前提,是你愿意先把目录理顺——它不是魔法,只是个把规范目录变漂亮的东西。