周末在家收拾储藏室翻出一台积灰三年的旧笔记本屏幕裂了但接上显示器还能跑。我盯着它看了十分钟突然觉得这玩意儿不该就这么躺在这儿。当天晚上“LunaTV”这个项目就诞生了——一台用旧笔记本改造成的家庭媒体中心统一管理我这些年攒下的电影、剧集、纪录片还有手机里几千张照片和几十段家庭录像。LunaTV这个名字很直白Luna是月亮因为我发现全家基本都是在晚上用它窝在沙发上或躺在床上看电影月光氛围刚好对味。它本质上是一个自托管的媒体服务器把分散在移动硬盘、旧电脑、网盘里的视频资源全部集中到一个地方然后客厅电视、卧室投影仪、手机、平板都能直接访问看到哪停在哪下次打开无缝续播。这篇东西不是产品说明书是我从零搭建LunaTV的完整复盘。我会把选型时的纠结、部署中的翻车、以及最后稳定运行的经验全部写出来。适合谁看如果你家里也有闲置电脑、视频文件乱成一锅粥、家人看片需求五花八门那这篇文章应该能帮你省下好几个晚上的折腾时间。1. 为什么家里需要一台LunaTV从一个真实痛点说起1.1 事情起因一台旧电脑和一堆散落的视频文件先交代一下背景。我家以前的观影状态是这样的客厅电视上装着三家视频平台的会员但想看的电影永远需要单独付费卧室投影仪是智能系统同一个平台还要再登录一遍电脑上下载的正版数字电影存在移动硬盘里想看就得把硬盘插到电视上文件格式不对还播不了手机里孩子从小到大的视频每隔半年就要导一次备份导出之后基本就躺在硬盘里吃灰再也没打开看过。问题的核心不是缺设备而是视频内容的管理方式彻底分裂了。平台管着平台的内容硬盘管着硬盘的内容手机相册又是另一套体系。每次想看个东西得先想清楚它在哪然后再想用什么设备放。那天晚上我列了一个清单看看自己到底有多少视频资产四块移动硬盘里的电影和剧集大概三四个TB电脑上的家庭照片和录像接近两百GB网盘里还存着一堆早年拍的素材。这些文件有的按年份建立了文件夹有的是随手堆在桌面然后塞进某个“新建文件夹(3)”。1.2 定位取舍它不是NAS胜似NAS最初的设想很简单能不能做一个东西让所有这些文件都能在任意一台设备上直接播放不用拷贝、不用转格式、不用插拔硬盘。市面上的成品NAS确实能解决一部分问题但三四盘位的主流机箱加上硬盘预算至少两三千。而且我的需求只有一个——管理媒体文件并且播放顺畅NAS上那些同步备份、虚拟机、Docker全家桶其实都用不上。旧笔记本虽然屏幕裂了但CPU是赛扬系列带核显跑一个媒体服务绰绰有余。LunaTV最终定位很清楚不追求当什么全功能家庭服务器就做好一件事——把媒体库管好、播好。当然我后来才发现媒体服务这件事一旦做起来你就回不去了。以前打开电视永远面对同一个首页现在打开电视看到的是自己整理的电影海报墙那种感觉完全不一样。1.3 它到底能替你做哪些事LunaTV成型后家里这几个场景都被改善了客厅的电视能看到完整的电影海报墙每部片子有简介、评分、预告片按类型、年份、地区随便筛。手机拍的视频自动同步到指定文件夹后电视上马上就能看老人想看看孙女的近况不用等周末我们过去自己打开电视就能翻。一家三口的观看进度完全分开我半夜看的科幻片不会出现在女儿的推荐列表里她看动画看到哪儿了系统也会记住。老电视不支持HEVCH.265格式的视频LunaTV会自动转码成它能播的格式不需要我事先转换文件。电视剧一集接着一集自动播放片头片尾还能自动跳过。一句话总结它解决的是家里所有屏幕和所有视频之间的连接问题。这件事听起来不复杂但做的时候坑比想象中多得多。2. 服务端技术选型复盘没有选Plex与Emby最终定了Jellyfin2.1 三款主流媒体服务器对比LunaTV的核心是一个媒体服务器软件。市面主流的开源/半开源方案就三个Jellyfin、Emby、Plex。网上对比文章很多但大部分停留在功能列表层面我直接说自己的使用体验和选型逻辑。对比项JellyfinEmbyPlex开源/免费完全开源免费核心免费高级功能收费免费版限制多高级会员按月/年收费服务端功能无功能锁定全部开放硬件转码等高级功能需付费硬件转码需Plex Pass客户端覆盖面Android/iOS/TV/网页/各类智能设备Android/iOS/TV/网页Android/iOS/TV/网页元数据刮削内置支持TMDB等数据源内置比较成熟内置成熟度最好硬件转码支持Intel QSV、NVIDIA NVENC、AMD AMF免费版受限解锁需订阅Plex Pass才能用中文支持界面中文比较完整中文字幕处理良好支持中文部分细节需调教中文生态不错但字幕处理偶有Bug部署方式Docker/原生包易于容器化Docker/原生包官方更推荐自己的NAS或客户端2.2 为什么“免费开源”会成为关键加分项最初我差点选了Plex因为它的客户端体验确实好尤其是Android TV端界面流畅度和美观度都在线。但仔细看了授权模式之后心凉了一半硬件转码要在服务器端开启这个功能被放进了Plex Pass订阅里一次性买断倒也行可对我来说为一个跑在旧笔记本上的服务再花七八百块性价比实在不高。Emby的情况类似免费版能用但硬件转码、部分高级播放功能被锁住解锁费用同样不低。如果你是零基础小白预算充足Plex的省心程度确实有优势但我的定位是“一个不太花钱的家庭影音中心”软件授权费这笔账就不能不算。Jellyfin是完全开源的所有功能对所有人开放包括硬件转码。功能完整度也许比Plex差一点点但差距没有想象中那么大。它的社区很活跃每月都有新版本玩的人多踩坑文档也齐全。对我这种喜欢动手的人来说这个选择几乎没有悬念。2.3 整体架构与目录规划定下Jellyfin之后接下来是目录规划。吃过亏的人都知道媒体库的目录结构决定了后面刮削的准确率这一步做不好后面全是痛苦。我选择的是这样的布局路径用途/data/media/movies电影按电影名 (年份).ext命名/data/media/series电视剧按剧名/S01E01.ext结构放/data/media/documentary纪录片统一管理/data/media/home家庭录像和照片按日期建子文件夹/srv/lunatv/configJellyfin程序配置和数据库/srv/lunatv/cache转码缓存和临时文件关键点在于媒体文件存放路径和程序配置路径必须分离。我见过有人把所有东西一股脑装在一个目录下系统一崩整个库都没了。我的/srv/lunatv整个目录定期打包备份媒体盘即使坏了重装系统后挂上新盘、恢复配置整个媒体库海报墙瞬间回来播放记录也在。2.4 硬件转码Intel核显与NVIDIA独显怎么选这台旧笔记本的CPU是Intel低功耗赛扬自带核显支持Intel Quick Sync VideoQSV硬件转码。如果你的机器是NVIDIA独显对应的是NVENCAMD平台则是AMF。对绝大多数家庭用户来说Intel核显反而是最省心的选择因为驱动集成度好、功耗低、转码画质够用。硬件转码解决什么问题举个真实场景你下载了一部4K HEVC 10bit的片子但卧室那台老电视最高只支持1080p H.264。没有硬件转码服务器就得靠CPU一帧一帧地软解CPU占用冲上100%播放变成幻灯片开了硬件转码核显几个小时内一动不动就能同时处理两三条转码流。选型阶段我还查了一下各平台对主流编码的支持情况整理如下编码格式Intel QSVNVIDIA NVENCAMD AMFH.264支持支持支持H.265/HEVC 8bit支持支持支持H.265/HEVC 10bit较新核显支持支持部分支持AV1较新核显支持30系以后支持新架构支持旧笔记本的核显具体支持到哪个程度可以在Linux下装个vainfo看一眼。这一步别省等实际跑起来发现不支持再换平台那才是真折腾。3. 从零部署LunaTV容器编排、权限和第一行日志3.1 Docker Compose单文件部署LunaTV的服务端我选择用Docker部署。原因很朴素隔离干净、升级方便、卸载不留垃圾。旧笔记本重装的是Debian系系统装好Docker和Compose插件后写一个docker-compose.yml就能搞定。services: lunatv: image: jellyfin/jellyfin:latest container_name: lunatv user: 1000:1000 network_mode: host volumes: - /srv/lunatv/config:/config - /srv/lunatv/cache:/cache - /data/media:/media:ro devices: - /dev/dri:/dev/dri environment: - TZAsia/Shanghai restart: unless-stopped然后在/srv/lunatv目录下执行docker compose up -d等镜像拉起来LunaTV的主界面就监听在8096端口了。3.2 目录权限与用户映射最容易爆雷的一步这个配置文件里我认为最关键的其实是user: 1000:1000这一行。Jellyfin容器默认以root运行虽然能跑但容器生成的配置文件、缩略图、清洗后的缓存文件全部归属root。一旦后续你想直接在宿主机上手工编辑容器里的文件会发现权限不够还得先sudo chown非常难受。正确的做法是让容器内的进程以宿主机上一个普通用户的身份运行。先确认当前用户的UID和GIDLinux下用id命令查看一般是1000。然后在compose文件里写上user: 1000:1000容器内生成的所有文件在宿主机上就都归这个用户管了。另外媒体目录挂载时我把/data/media设为只读ro这样Jellyfin只能读取影片文件不会误删或改坏原始数据。媒体库的元数据、缩略图、图标这些可写内容全部放在config和cache目录里各司其职权限边界清清楚楚。3.3 首次启动配置添加媒体库、语言、元数据下载第一次启动后用浏览器打开http://服务器IP:8096进入配置向导。这里有几个坑需要提前说第一创建管理员账户时用户名和密码不要包含中文某些客户端对中文用户名支持有问题会导致登录失败排查半天发现是用户名的问题真的很冤。第二语言设置直接选中文然后勾选“首选中文简体”作为元数据语言。不然刮削出来的电影简介大概率是英文的海报倒是正常简介全得靠猜。第三添加媒体库时一定要按照目录分别添加。电影一个库、剧集一个库、纪录片一个库、家庭录像一个库分别指定内容类型。我一开始偷懒把电影和剧集放进同一个库选“电影”结果十几个剧集全被识别成了一堆乱码名字怎么手动匹配都救不回来。媒体库类型选择建议 - /data/media/movies - 电影 - /data/media/series - 剧集 - /data/media/documentary - 纪录片 - /data/media/home - 混搭家庭视频3.4 局域网内的播放测试与转码链路验证库建完、文件扫描完第一步先别急着让全家人都用自己在电脑上打开网页端选一部片源播放。这一步要验证的是“播放链路”是否通网页端默认会走HTTP串流服务器把视频直接发给浏览器不转码。如果片源编码格式刚好是浏览器不支持的比如HEVCJellyfin会自动触发转码此时去后台“控制台 - 活动”看那一条播放记录能看到“转码”标识。如果转码总是很慢或直接失败大概率是硬件转码没启用。先执行下面几条命令确认# 检查容器里是否能看见核显设备 ls -l /dev/dri # 如果 /dev/renderD128 不存在检查宿主机内核模块 sudo modprobe i915看到/dev/dri/renderD128存在后去Jellyfin后台把“硬件加速”选成“Intel QuickSync”保存后重试。CPU占用从之前的90%以上降到15%以下就说明链路没问题了。4. 客户端接入与多端播放体验全家人的遥控器都统一了4.1 Android TV客户端客厅场景的关键设置LunaTV服务端跑起来只是第一步真正决定家人愿不愿意用还得看客厅这台电视上的体验。Android TV上安装Jellyfin官方客户端登录后会直接进入媒体库页面。进入设置有几个选项必须调播放器优先用“外部播放器”或“内置播放器”。我实测下来内置播放器对ASS字幕特效的支持更好。开启“Direct Play”优先让电视在能直接解码时不要请求服务器转码减少服务器负担。“允许在兼容时直通音频”一定要开只有打开这个选项连接功放时才能输出杜比/dts原始比特流。调完之后客厅电视的体验就是开机、打开Jellyfin、看到海报墙、点开一部电影直接播。片源格式电视能解码就直通播放不能解码服务器自动转码整个过程家人不需要知道任何技术细节。4.2 手机/平板/网页端不同场景的差异化体验手机端我装的是官方App最常用的场景是吃饭时往旁边一架把之前没看完的纪录片放完。手机端会记住每个用户的播放进度换设备继续播完全无缝。平板端反而是家里老人用得最多的地方。字体调大、界面列表切换成“海报”大卡片模式手指点起来比遥控器还顺手。网页端适合我自己管理媒体库时用鼠标键盘操作效率最高能直接编辑元数据、手动匹配错误识别的影片。多端的好处是同一套媒体库不用重复扫描、重复下海报所有设备的播放记录实时同步。女儿在客厅看到一半去睡觉回到卧室打开平板接着看进度直接续上不会问“我上次看到哪了”。4.3 进度同步与多用户隔离家人之间互不干扰Jellyfin原生支持多用户这功能我强烈建议用起来。给每个家庭成员建独立账号好处不只是播放记录分开还有孩子的账户可以在管理后台设置为“不展示限制级内容”有些片源标了年龄分级孩子账号下直接不显示。收藏夹、观看记录、续播队列完全独立。我自己追的剧不会因为女儿看了小猪佩奇而挤掉位置。电视端登录界面可以记住多个账号开机后用遥控器选一下就进去了成本很低。我家现在的习惯是晚上八点半之后孩子洗漱睡觉客厅电视切到我的账户打开收藏夹里的电影开始属于成年人的时间。这种体验对于一个影音爱好者来说真的很有仪式感。4.4 不要做的事把8096端口直接暴露到公网这是全文我最想强调的一点。很多人在配置完Jellyfin后会在路由器上做一个端口转发把8096映射到公网这样在外面也能连回家看片。但这类开源服务被全网扫描盯上的概率非常高默认端口、默认账号体系一旦暴露轻则被暴力破解重则服务器被植入挖矿程序这个问题在技术社区里已经出现过很多次了。我的建议很简单不要给Jellyfin做公网端口映射尤其是不要用默认端口直接暴露。关闭路由器上的UPnP功能避免内网设备自己偷偷做端口映射。Jellyfin后台开启“需要登录才能访问”并设置强密码。如果你确实需要远程访问优先考虑带零信任架构的私有组网方案这类方案不需要在公网开放任何端口安全性会好很多。配置方法以官方文档为准别自己凭感觉搞开放端口。安全不是玄学是习惯。这个习惯值得从一开始就养成。5. 字幕、硬解与刮削LunaTV踩坑排查实录LunaTV稳定运行一个月后我把过程中踩过的坑集中梳理了一遍。这里不直接给答案而是复盘完整的排查链路你下次遇到同样问题时能顺着思路走一遍。5.1 字幕不显示/乱码从SRT到ASS的完整处理思路第一个坑在字幕。现象是播放带中文字幕的电影有些字幕显示正常有些干脆不显示还有一些显示成一堆方框乱码。排查思路先确认字幕文件的编码格式。用文本编辑器打开.srt文件看上去内容是正常的但Jellyfin的网页播放器完全识别不了。再用file命令看编码file 电影名.zh.srt # 输出示例ISO-8859 text, with CRLF line terminators问题找到了。很多中文字幕文件虽然扩展名是.srt但实际编码是GBK/GB18030而Jellyfin默认按UTF-8解析编码不对就会直接乱码或无法识别。解决方法是把字幕转为UTF-8批量转换的话可以写个小脚本# 先转换单个文件验证 iconv -f GB18030 -t UTF-8 电影名.zh.srt 电影名.zh.utf8.srt # 确认效果后再批量处理注意先备份 find /data/media -name *.srt -exec sh -c iconv -f GB18030 -t UTF-8 $1 $1.tmp mv $1.tmp $1 _ {} \;注意如果文件本来就是UTF-8再用GB18030强制转换会乱上加乱。批量处理前先抽样确认编码或者用支持编码检测的工具先判断一遍。另一个坑是ASS特效字幕。ass字幕自带定位、颜色、特效样式播放端如果缺字体样式会退化甚至显示方框。处理方法是把中文字体上传到LunaTV容器内或者在播放端设置里加载系统字体。对大多数用户来说直接在内置播放器设置里勾选“使用样式化字幕”并安装一款中文字体包问题就解决了。PGS字幕蓝光原盘里最常见的图形字幕又是另一种情况。它是图片格式没法靠文本编码修复播放时如果显示不出检查Jellyfin转码设置里的“图形字幕”选项开启“图像字幕烧录”才能确保电视端稳定显示。5.2 硬解不生效/dev/dri权限、i915驱动与转码日志判断第二个坑是硬解不生效。现象是用Android TV端播放一部4K HDR电影画面卡顿后台看到转码速度远慢于播放速度CPU占用接近100%。排查分三步。第一步确认硬件设备映射是否有效。进入容器看设备docker exec -it lunatv ls -l /dev/dri如果输出纯净的/dev/dri/renderD128说明设备映射成功如果报错大概率是compose文件里没有devices配置或者宿主机内核没加载驱动。第二步安装vainfo确认VAAPI可用sudo apt install vainfo vainfo | grep -i H264\|HEVC如果输出包含VAProfileH264Main和VAProfileHEVCMain相关行说明核显驱动没问题。如果输出一堆driver not supported就需要检查Intel GPU驱动是否装好。旧内核下有时还需要手动加载i915模块。第三步去Jellyfin后台确认转码配置。“控制台 - 播放 - 转码”里硬件加速选“Video Acceleration API (VAAPI)”或“Intel QuickSync”两者选一个保存。选完后看“活动日志”如果出现hw: true字样说明硬解链路已经打通。这里还有一个容易忽略的细节容器运行用户需要有权限访问/dev/dri。如果compose里user配的是一个普通用户而这个用户不在video或render组里设备文件虽然挂进去了但进程打开失败表现就是“硬解按钮开了但是不生效”。可以在宿主机上验证sudo usermod -aG render,video 你的用户名改完用户组重启容器再看日志正常了。5.3 杜比/DTS音频直通失败电视、功放与HDMI EDID的三角关系第三个坑来的比较隐蔽。起因是朋友来家里观影我挑了一部带DTS-HD Master Audio音轨的片源结果功放面板上显示的是PCM两声道而不是DTS-HD。排查链路是这样的先在手机端用同一个片源播放能被正确识别为DTS在网页端播放也正常唯独Android TV端接功放不行。这说明服务器端识别音频流没问题问题出在电视端的音频输出链路上。逐步排查后发现Android TV客户端播放设置里的“音频直通”选项默认是关闭的系统会自动把DTS转成PCM再通过HDMI传给功放。打开“音频直通”后功放能正确识别DTS了但点击播放后没有声音与此同时网页端正常。进一步查日志发现片源音轨是DTS-HD MA而电视的HDMI-ARC通道不支持DTS-HD MA只支持DTS Core和杜比数字。功放能识别不代表电视传输链路能承载。最终的处理方案是在LunaTV的转码设置里启用“音频转码”把不兼容的DTS-HD MA音轨统一转成AC3 5.1再直通给功放。这样既保留了环绕声又绕过了HDMI-ARC带宽限制。这块的通用经验是音轨能否源码直通取决于最弱的一环——可能是客户端、可能是电视、也可能是功放。逐段排查顺序建议为客户端设置 - HDMI线缆/ARC协议 - 功放输入声道判定。实在绕不过去就果断在服务器端做音频转码普通家庭影音场景下服务器转成AC3 5.1的听感差距远没有想象中大。5.4 标题刮削错误nfo修正与离线处理手段第四个坑是刮削识别错误。现象是电影《月球陨落》被识别成了一部同名的老纪录片海报和简介风马牛不相及。原因在于TMDB等开源元数据源依靠“文件名 年份”来匹配影片。如果文件名写的是Moonfall.2022.BluRay.1080p.x265.mkv刮削器能认出来但如果文件名带着[1080P]随便压制的版本这类花里胡哨的信息匹配精度就会直线下降。我的处理思路是这样的先把文件重命名成标准格式月球陨落 (2022).mkv或者保留英文原名Moonfall (2022).mkv。年份必须加这是匹配的关键锚点。如果自动匹配还是失败在Jellyfin网页端手工搜索片名手动锁定正确的影片条目。锁定成功后Jellyfin会生成一个.nfo文件里面记录了完整的元数据。以后即使重新扫描也不会再匹配错。对于特别冷门的片源可以在网上下载现成的nfo文件放到同目录然后开启“优先使用本地nfo元数据”选项。这一串操作熟练之后一个库几百部电影大概半小时就能整理得干干净净。整理完的海报墙非常治愈。6. 从能用再到好用自动化、备份与长期维护6.1 媒体文件的命名规范一次整理多年受益如果你准备搭LunaTV我建议第一部电影就按标准命名别嫌麻烦。命名规范是媒体库管理的基石做好了能省掉90%后续手工维护的时间。我采用的规范是类型命名规则示例电影中文名 (年份).ext月球陨落 (2022).mkv剧集剧名/剧名.SxxEyy.ext沙丘E01/沙丘.S02E01.mkv纪录片中文名 (年份).ext地球脉动 (2023).mkv家庭视频日期_标题.ext20240210_春节团圆饭.mp4剧集这一块容易搞错不是所有剧集都从S01E01开始有的可能是特别篇、剧场版这类建议单独建一个“特辑”库不然和正剧混在一个目录里刮削时会互相覆盖。6.2 定时任务清理转码缓存、重建媒体库索引转码缓存是隐藏的硬盘杀手。Jellyfin在播放不需要转码的视频时只会生成极小的临时文件但一旦影片要转码系统会把视频切成很多小片段一只只临时存储在/srv/lunatv/cache/transcodes里。一部4K电影转码完这些缓存文件积攒下来很容易吃光几个GB。Jellyfin默认的清理周期是7天周期内如果你一直在看不同片源临时文件就可能膨胀。我加了条crontab每天凌晨把两天前的转码缓存清掉0 4 * * * find /srv/lunatv/cache/transcodes -type f -mtime 2 -delete注意清理前确认没有正在播放的任务凌晨四点的定时任务基本安全。这个脚本跑了几个月了从没出过问题。6.3 备份策略元数据目录每周打包播放记录丢失的代价媒体库本身不丢丢的往往是元数据和配置。Jellyfin的config目录里存着每个用户的播放进度、收藏夹、自定义海报、用户头像、刮削后的元数据缓存。如果你重装系统后发现收藏夹空了、观看记录没了那个感受堪比失业。我的备份策略极其简单每天凌晨用tar把整个/srv/lunatv/config打包保留最近7个备份放到一块独立硬盘上。0 3 * * * tar czf /backup/lunatv-config-$(date \%Y\%m\%d).tar.gz -C /srv lunatv/config find /backup -name lunatv-config-*.tar.gz -mtime 7 -delete媒体文件本身不做备份因为原始文件我有移动硬盘和网盘多份副本。但配置目录必须有备份这东西丢了很难重建。恢复流程也验证过一次新系统装Docker、挂载旧盘恢复config目录启动容器整个库一分钟内恢复原样。6.4 扩展方向海报墙展示、智能家居联动与后续计划LunaTV稳定之后我开始琢磨怎么让它更好用。目前已经做了两个扩展一个是把客厅电视的屏保换成了LunaTV的“正在播放”海报墙不操作电视时自动轮播最近添加的电影海报家里来客人看到都会多问一句这是什么效果很好。另一个是和智能家居的联动观影开始时通过一个简单的自动化脚本把客厅灯光调到10%亮度窗帘自动拉上按下暂停键灯光恢复到30%。这个功能不是必须的但用起来相当有仪式感。实现方案用的是智能家居平台的自动化规则配合LunaTV的Webhook通知技术门槛不高但调起来好玩。一台旧电脑的第二个春天我最后想说的是LunaTV这个项目技术上并不复杂真正的价值在于把家里分散了几年的视频内容重新聚到了一起。现在女儿周末会自己打开电视翻动画片看我妈能随时在平板上看我拍的旅行视频我和老婆的追剧进度也再没丢过。整个过程下来我的体会是搭建这样的系统别一上来就追求功能齐全。先把电影和剧集两个媒体库跑顺让家人用上一个月再慢慢加自动化、加智能联动。一次到位的系统往往维护成本高而且容易半途而废。从最小可行版本开始边用边迭代这才是家庭媒体中心能长期跑下去的正确姿势。如果你家里也有一台落灰的电脑也许它该迎来第二个春天了。