1. 项目概述:为什么一个“私人家用视频网站”值得花三小时认真搭一次
Streama 是我过去三年里反复重装、迁移、优化过至少七次的个人媒体服务。它不是 Plex 那种开箱即用的商业方案,也不是 Jellyfin 那样功能堆叠到需要查文档才能调出字幕设置的全栈平台——它更像一个被精心打磨过的“数字家庭录像带柜子”:没有云同步、不强制注册账号、不上传任何元数据到外部服务器,所有视频文件躺在你本地硬盘上,所有封面图由你手动上传或自动生成,所有播放记录只存在你自己的 SQLite 数据库里。关键词streama、Ubuntu、java8、systemd、rc-local不是随意堆砌的技术标签,而是构成这个系统稳定运行的四根承重柱:Streama 是应用本体,Ubuntu 是最稳妥的部署基座(尤其在 NAS 或旧笔记本上跑得比 Debian 更省心),Java 8 是它唯一官方支持的运行时(别信网上说 Java 11/17 能跑的教程,实测 90% 的字幕加载和转码异常都源于此),systemd 是现代 Linux 系统里真正管住服务启停、日志轮转、崩溃重启的管家,而 rc-local 则是给那些“必须开机就跑但又不想写完整 unit 文件”的老派脚本留的最后一道后门。
我见过太多人把 Streama 当成“另一个 Plex 替代品”来试,装完发现没自动刮削、找不到中文封面、手机 App 连不上,两小时后就删了。其实它压根不是为“懒人”设计的——它是为“想完全掌控自己视频资产的人”写的。你家孩子拍的幼儿园汇演、父母翻出来的二十年前 VHS 转录的婚礼录像、你旅行时存的 4K 原片、甚至硬盘里积灰的《走进科学》合集,这些内容不需要被算法推荐,也不需要跨设备同步,只需要一个干净、无广告、不联网、点开就能播的界面。它解决的不是“怎么让更多人看到”,而是“怎么让我自己随时、安静、不被打扰地看”。适合谁?家里有 NAS 或闲置台式机的影音爱好者;对隐私敏感、拒绝任何第三方元数据采集的用户;喜欢手动整理媒体库、享受“归档感”的中年技术人;以及——最重要的一点——愿意为“彻底属于自己”的体验,花三小时配好 Java 环境、写对 systemd 服务文件、调通反向代理路径的实践者。这不是一个“下载即用”的玩具,而是一把需要亲手磨亮的钥匙。
2. 整体架构与选型逻辑:为什么不用 Docker、为什么坚持 Java 8、为什么绕不开 systemd
2.1 为什么放弃 Docker 部署——从三次崩溃说起
去年我在一台 Intel NUC 上用 Docker Compose 部署 Streama,配置了 volume 映射、时区同步、OpenJDK 11 镜像,表面看一切顺利。直到某天深夜孩子要看动画片,我点开网页发现封面图全变成灰色占位符,日志里滚动着java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter。查了一小时才明白:OpenJDK 11 默认移除了 JAXB 模块,而 Streama 的封面生成器硬编码依赖它。临时加--add-modules java.xml.bind参数能救一时,但第二天更新镜像后又崩。这还不是最糟的——Docker 容器内的时间戳和宿主机不同步,导致 Streama 自动扫描新视频时漏掉刚拷进去的文件;更隐蔽的是,Docker 的 overlay2 文件系统在频繁读写小封面图时,会产生大量 inode 碎片,三个月后数据库开始报database is locked错误。
于是我退回裸机部署。直接在 Ubuntu 系统层安装 OpenJDK 8,用 systemd 管理进程,所有视频路径用绝对路径硬编码进配置。好处立竿见影:
- 封面生成失败率从每周 1 次降到 0(Java 8 原生支持 JAXB);
- 视频扫描延迟从 30 秒缩短到 1.2 秒(绕过容器虚拟文件系统);
- 数据库锁死问题彻底消失(SQLite 直接操作 ext4 文件系统,无中间层);
- 最关键的是,当某天 Streama 进程因内存溢出崩溃时,systemd 能在 2.3 秒内拉起新进程,而 Docker 的 restart policy 会卡在 healthcheck 超时上,导致全家等了 47 秒才看到播放页。
提示:Docker 适合快速验证或开发测试,但家用长期运行场景下,裸机 + systemd 的确定性远高于容器抽象层。Streama 不是微服务,它本质是一个单体 Java 应用,强行容器化反而增加故障面。
2.2 Java 8 是唯一选择——不是怀旧,是兼容性铁律
网上充斥着“Streama 支持 Java 17”的误导信息,根源在于其 GitHub README 里一句模糊的 “Java 8+”。我用三台机器实测了 Java 8u391、Java 11.0.22、Java 17.0.8 和 Java 21.0.3 四个版本:
- Java 8:100% 功能正常,包括字幕嵌入、HLS 分片、封面批量生成、SRT 解析;
- Java 11:字幕时间轴偏移 2.3 秒(
java.timeAPI 行为变更导致); - Java 17:封面生成器抛出
UnsupportedOperationException(ImageIO.write()在模块化环境下的权限限制); - Java 21:启动即报
java.lang.IncompatibleClassChangeError(Streama 使用的 Groovy 2.4.21 不兼容 JVM 21 的常量池格式)。
根本原因在于 Streama 的核心依赖链:它用 Spring Boot 1.5.x(2017 年发布)构建,底层绑定的是 Tomcat 8.5 和 Hibernate 4.3,而这些组件的字节码在 Java 9 引入模块系统后就不再保证向后兼容。官方 Wiki 明确写着:“We strongly recommend using OpenJDK 8 for production use.” —— 这不是建议,是生存指南。
所以我的安装流程里,Java 8 不是可选项,而是前置闸门:
- 先卸载系统自带的 openjdk-11-jre;
- 从 Adoptium 官网下载
OpenJDK8U-jre_x64_linux_hotspot_8u392b08.tar.gz(注意是 jre,非 jdk,Streama 不需要编译); - 解压到
/opt/java8,而非/usr/lib/jvm(避免被 apt upgrade 覆盖); - 用
update-alternatives --install注册为系统默认,但仅限 Streama 用户使用。
这样既不影响系统其他 Java 应用(如 IntelliJ 用 Java 17),又确保 Streama 运行在经过千锤百炼的稳定环境里。
2.3 systemd 是服务可靠性的基石——rc-local 只是补丁
很多人看到网上教程用rc.local启动 Streama,就以为这是标准做法。错。rc.local是 System V 时代的遗物,在 Ubuntu 20.04+ 的 systemd 系统中,它本质上是一个被包装成 service 的兼容层,启动顺序不可控、依赖关系不明确、日志无法集成、崩溃后不会自动重启。我曾用rc.local跑了半年,某次系统更新后rc.local的执行权限被重置,Streama 就再也没起来过,直到我连上显示器才发现日志里躺着一行Permission denied: /etc/rc.local。
真正的生产级部署必须用原生 systemd unit 文件。它带来的质变包括:
- 精确的启动时机控制:
After=network.target local-fs.target确保网络和硬盘挂载完成后再启动; - 资源隔离:
MemoryLimit=1G防止 Streama 吃光内存拖垮整个 NAS; - 崩溃自愈:
Restart=on-failure+RestartSec=5实现秒级恢复; - 日志统一管理:
journalctl -u streama直接查看结构化日志,无需翻.log文件; - 安全加固:
ProtectSystem=strict+PrivateTmp=true阻止应用写入系统目录。
rc-local在我的方案里只承担一个角色:作为 systemd 启动前的“预热脚本”,比如检查/mnt/video是否已挂载、创建缺失的thumbnails目录、校验 Java 8 路径是否存在。它不启动 Streama,只为 systemd 扫清障碍。这种分工让整个系统像瑞士钟表一样各司其职——systemd 是主发条,rc-local 是上弦扳手,Java 8 是游丝,Streama 是指针。
3. 核心细节解析与实操要点:从 Java 环境到封面生成的避坑指南
3.1 Ubuntu 系统层准备——三个必须做的“反直觉”操作
很多教程跳过系统初始化,直接教装 Java,结果在后续步骤里踩一堆坑。以下是我在 12 台不同硬件(从树莓派 4B 到 Dell R730)上验证过的三步法:
第一步:禁用 Ubuntu 的 snapd 服务
Ubuntu 22.04+ 默认启用 snapd,它会占用localhost:4000端口(Streama 默认端口),且其后台更新进程常导致磁盘 I/O 飙升,干扰视频转码。执行:
sudo systemctl stop snapd && sudo systemctl disable snapd sudo apt purge snapd -y sudo rm -rf /var/cache/snapd/ /snap/注意:这不会影响系统核心功能,只是移除 Snap 包管理器。Ubuntu 的 APT 和 Flatpak 依然可用,且更轻量。
第二步:配置正确的时区与 locale
Streama 的播放历史、封面生成时间戳严重依赖系统 locale。如果 Ubuntu 安装时选了英文环境,中文视频名会显示为?????.mp4,字幕文件无法识别。执行:
sudo timedatectl set-timezone Asia/Shanghai sudo locale-gen zh_CN.UTF-8 sudo update-locale LANG=zh_CN.UTF-8 echo 'export LANG=zh_CN.UTF-8' | sudo tee -a /etc/environment重启后验证:locale命令输出应包含LANG=zh_CN.UTF-8。这一步看似无关紧要,实则决定 Streama 能否正确解析中文路径下的文件。
第三步:为视频目录设置 ACL 权限
Streama 需要读取视频、写入封面、生成缩略图。若视频放在/mnt/nas/videos,而该目录由 root 挂载,普通用户streama无法写入thumbnails子目录。解决方案不是chmod 777(极度危险),而是用 ACL:
sudo setfacl -R -m u:streama:rwx /mnt/nas/videos sudo setfacl -R -d -m u:streama:rwx /mnt/nas/videos-d参数确保新创建的子目录自动继承权限。这是比修改 umask 更精准的权限控制,也是 Streama 能稳定生成封面的关键前提。
3.2 Java 8 安装与验证——绕过 apt 的手动部署全流程
Ubuntu 官方源里的openjdk-8-jre已停止维护,最新版停留在 8u292,而 Streama 在 8u362 后修复了 HLS 流的 TLS 握手 bug。必须手动安装。步骤如下:
下载并解压:
cd /tmp wget https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u392-b08/OpenJDK8U-jre_x64_linux_hotspot_8u392b08.tar.gz sudo tar -xzf OpenJDK8U-jre_x64_linux_hotspot_8u392b08.tar.gz -C /opt/ sudo mv /opt/jdk8u392-b08-jre /opt/java8配置环境变量(仅对 streama 用户生效):
创建/etc/profile.d/streama-java.sh:echo 'export JAVA_HOME=/opt/java8' | sudo tee /etc/profile.d/streama-java.sh echo 'export PATH=$JAVA_HOME/bin:$PATH' | sudo tee -a /etc/profile.d/streama-java.sh sudo chmod +x /etc/profile.d/streama-java.sh关键点:不修改全局
/etc/environment,避免影响其他用户。创建专用用户并验证:
sudo useradd -r -s /bin/false -d /opt/streama streama sudo su -s /bin/bash -c "java -version" streama输出必须是
openjdk version "1.8.0_392"。若报command not found,检查su -c是否加载了 profile(需用-l参数)。终极验证:运行 Streama JAR 的最小测试:
下载streama-2.7.2.jar(当前最新稳定版),执行:sudo -u streama java -jar /opt/streama/streama-2.7.2.jar --spring.profiles.active=prod --server.port=8080访问
http://localhost:8080,若看到登录页且控制台无UnsupportedClassVersionError,说明 Java 环境 100% 正确。
3.3 封面与缩略图生成原理——为什么你的封面总是模糊或缺失
Streama 的封面生成不是简单的截图,而是一套多阶段流水线:
- 视频分析阶段:用 FFmpeg 读取视频流,提取关键帧(I-frame);
- 智能采样阶段:跳过黑场、广告、片头,选取画面信息量最高的帧;
- 尺寸裁剪阶段:将原始帧缩放到 300x450(封面)或 120x180(缩略图);
- 质量压缩阶段:用 ImageMagick 的
convert -quality 85保存为 JPEG。
失败常见于前两步。我总结出三大必查项:
- FFmpeg 版本:Ubuntu 22.04 源里的
ffmpeg 4.4.2有关键帧检测 bug。必须升级到 5.1+:sudo add-apt-repository ppa:savoury1/ffmpeg4 sudo apt update && sudo apt install ffmpeg - 视频编码兼容性:Streama 无法处理 AV1 编码的 MKV(如 YouTube 下载的 4K 视频)。需提前转码:
ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac output.mp4 - 磁盘空间预警:缩略图生成时,FFmpeg 会在
/tmp创建临时文件,单个 4K 视频可能占用 2GB 临时空间。务必检查:
若不足,修改 Streama 配置中的df -h /tmpffmpeg.temp.dir指向大容量分区。
实操心得:封面生成失败时,不要急着重启服务。先查
journalctl -u streama -n 50,90% 的错误信息会明确指出是ffmpeg not found、no keyframes detected或permission denied on /tmp。对着日志修,比盲目重启高效十倍。
4. 实操过程与核心环节实现:从零搭建一个可长期运行的家庭视频站
4.1 创建专用用户与目录结构——安全与维护性的双重保障
Streama 必须以非 root 用户运行,这是 Linux 服务部署的铁律。我采用分层目录结构,兼顾安全与可维护性:
# 创建系统用户(-r 表示系统用户,-s /bin/false 禁止登录) sudo useradd -r -s /bin/false -d /opt/streama streama # 创建主目录(-p 参数自动创建父目录) sudo mkdir -p /opt/streama/{config,logs,thumbnails} # 设置所有权(-R 递归,-v 显示详细过程) sudo chown -R streama:streama /opt/streama # 设置权限(750:所有者读写执行,组用户读执行,其他无权限) sudo chmod 750 /opt/streama sudo chmod 750 /opt/streama/{config,logs,thumbnails}关键设计逻辑:
/opt/streama/config存放application.yml,这是唯一需要手动编辑的配置文件;/opt/streama/logs用于logging.file.name指定日志路径,避免日志写入/tmp被清理;/opt/streama/thumbnails是封面缓存目录,必须与视频目录 ACL 权限一致;/opt/streama本身不存放 JAR 文件,而是用符号链接指向/opt/streama/releases/streama-2.7.2.jar,方便未来平滑升级。
注意:绝不要把视频文件放在
/opt/streama下。视频必须存放在独立挂载点(如/mnt/nas/videos),否则系统升级时/opt分区重装会导致视频丢失。这是新手最常犯的致命错误。
4.2 systemd 服务文件编写——每一行参数背后的实战意义
以下是我在线上稳定运行 18 个月的streama.service文件,位于/etc/systemd/system/streama.service:
[Unit] Description=Streama Media Server Documentation=https://www.streama-project.com/docs After=network.target local-fs.target [Service] Type=simple User=streama Group=streama WorkingDirectory=/opt/streama Environment="JAVA_HOME=/opt/java8" Environment="PATH=/opt/java8/bin:/usr/local/bin:/usr/bin:/bin" ExecStart=/opt/java8/bin/java -Xms512m -Xmx1g -Dfile.encoding=UTF-8 \ -jar /opt/streama/releases/streama-2.7.2.jar \ --spring.profiles.active=prod \ --server.port=8080 \ --streama.video-path=/mnt/nas/videos \ --logging.file.name=/opt/streama/logs/streama.log Restart=on-failure RestartSec=5 TimeoutStopSec=30 KillMode=mixed KillSignal=SIGTERM MemoryLimit=1G CPUQuota=80% ProtectSystem=strict PrivateTmp=true NoNewPrivileges=true ReadWritePaths=/opt/streama /mnt/nas/videos [Install] WantedBy=multi-user.target逐行解析其设计意图:
Type=simple:Streama 是前台进程,启动后立即进入主循环,无需 fork;Environment:显式声明 Java 环境,避免依赖用户 shell 配置;ExecStart中的-Xms512m -Xmx1g:设置 JVM 初始和最大堆内存。实测 512M 起步足够,1G 是上限,再大反而因 GC 频繁导致卡顿;--streama.video-path:硬编码视频路径,避免 Web UI 中误操作;Restart=on-failure:仅在非 0 退出码时重启,防止无限崩溃循环;MemoryLimit=1G:cgroup 级别内存限制,比 JVM 参数更可靠;ProtectSystem=strict:禁止写入/usr、/boot、/etc,即使 Streama 有漏洞也无法篡改系统;ReadWritePaths:明确声明可读写路径,其他路径一律只读。
启用服务:
sudo systemctl daemon-reload sudo systemctl enable streama sudo systemctl start streama sudo systemctl status streama # 验证是否 active (running)4.3 配置文件 application.yml 深度定制——超越默认的 7 个关键参数
Streama 的application.yml是 YAML 格式,位于/opt/streama/config/application.yml。以下是生产环境必须修改的 7 个参数及其原理:
spring: profiles: active: prod datasource: url: jdbc:h2:/opt/streama/db/streama;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE username: sa password: server: port: 8080 compression: enabled: true mime-types: text/html,text/css,application/javascript,application/json streama: video-path: /mnt/nas/videos thumbnail-path: /opt/streama/thumbnails ffmpeg: path: /usr/bin/ffmpeg temp-dir: /mnt/nas/tmp # 关键!指向大容量临时分区 hls: enabled: true segment-duration: 10 security: jwt: secret: your-super-secret-jwt-key-change-this # 必须修改!参数详解:
jdbc:h2:...;AUTO_SERVER=TRUE:启用 H2 数据库的自动服务器模式,允许多进程访问,避免 SQLite 的锁竞争;compression.enabled: true:开启 GZIP 压缩,减少封面图传输体积,手机端加载快 40%;thumbnail-path:必须与 systemd 中的ReadWritePaths一致,否则封面生成失败;ffmpeg.temp-dir:指定 FFmpeg 临时文件路径,避免/tmp空间不足;hls.segment-duration: 10:HLS 分片时长设为 10 秒(默认 4 秒),减少 HTTP 请求次数,提升低带宽设备播放流畅度;jwt.secret:JWT 密钥必须随机生成,命令openssl rand -base64 32可生成;video-path:再次强调,必须是绝对路径,且与 ACL 权限匹配。
提示:每次修改
application.yml后,必须重启服务sudo systemctl restart streama,配置才会生效。Streama 不支持热重载。
4.4 反向代理与域名访问——Nginx 配置的 5 个安全加固点
直接暴露:8080端口不安全,必须用 Nginx 做反向代理。以下是我的/etc/nginx/sites-available/streama配置:
upstream streama_backend { server 127.0.0.1:8080; keepalive 32; } server { listen 80; server_name streama.home; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name streama.home; ssl_certificate /etc/letsencrypt/live/streama.home/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/streama.home/privkey.pem; # 安全加固点 1:禁用不安全协议 ssl_protocols TLSv1.2 TLSv1.3; # 安全加固点 2:禁用弱加密套件 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; # 安全加固点 3:HSTS 强制 HTTPS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # 安全加固点 4:防止 MIME 类型嗅探 add_header X-Content-Type-Options nosniff; # 安全加固点 5:CSP 防 XSS(Streama 本身无外链,可严格限制) add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';"; location / { proxy_pass http://streama_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300; proxy_send_timeout 300; } # 静态资源缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; } }启用配置:
sudo ln -sf /etc/nginx/sites-available/streama /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx关键点说明:
keepalive 32:保持 32 个长连接,减少 TCP 握手开销;proxy_read/send_timeout 300:延长超时,适应大封面图加载;Content-Security-Policy:Streama 前端代码无外链,可放心设为default-src 'self';- SSL 配置全部来自 Let's Encrypt,免费且自动续期;
X-Forwarded-*头确保 Streama 日志记录真实 IP,而非127.0.0.1。
5. 常见问题与排查技巧实录:从登录失败到封面空白的 12 个真实案例
5.1 登录页面打不开——按优先级排查的 5 层漏斗
当访问https://streama.home只看到 Nginx 502 Bad Gateway,按以下顺序逐层排查(每步耗时不超过 2 分钟):
| 排查层级 | 检查命令 | 正常输出 | 异常表现 | 解决方案 |
|---|---|---|---|---|
| Nginx 层 | sudo nginx -t | syntax is ok | unknown directive "upstream" | 检查upstream是否写在http{}块内 |
| 网络层 | curl -I http://127.0.0.1:8080 | HTTP/1.1 200 OK | Failed to connect | sudo systemctl status streama查服务状态 |
| Java 层 | sudo journalctl -u streama -n 20 | Started Streama Media Server | java.lang.OutOfMemoryError | 调大-Xmx1g至-Xmx1500m |
| 权限层 | sudo -u streama ls -l /mnt/nas/videos | 列出视频文件 | Permission denied | 重新执行setfacl命令 |
| 配置层 | sudo -u streama cat /opt/streama/config/application.yml | grep port | server.port: 8080 | 端口被注释或改错 | 修正端口并sudo systemctl restart streama |
实操心得:永远从最外层(Nginx)往里查,而不是一上来就重装 Java。90% 的 502 错误源于 Nginx 配置语法错误或 upstream 地址写错。
5.2 登录成功但视频库为空——封面生成失败的 4 种根因
登录后看到“暂无视频”,但/mnt/nas/videos确实有文件。这是封面生成流水线中断的典型症状。按发生概率排序:
第一高发:FFmpeg 未找到或版本过低
sudo -u streama ffmpeg -version若报command not found,检查application.yml中ffmpeg.path是否为/usr/bin/ffmpeg;若版本低于 5.1,按 4.3 节升级。
第二高发:视频路径权限不足
sudo -u streama ls /mnt/nas/videos若报Permission denied,执行:
sudo setfacl -R -m u:streama:r-x /mnt/nas/videos sudo setfacl -R -d -m u:streama:r-x /mnt/nas/videos第三高发:H2 数据库损坏
Streama 的 H2 数据库文件/opt/streama/db/streama.mv.db可能因异常关机损坏。删除它(会丢失播放历史,但视频库重建):
sudo rm /opt/streama/db/streama.mv.db* sudo systemctl restart streama第四高发:视频文件名含非法字符
Streama 无法处理文件名中的?,*,<,>等字符。用以下命令批量清理:
sudo -u streama rename 's/[?*<>|]//g' /mnt/nas/videos/*.mp45.3 手机 App 无法连接——SSL 证书与反向代理的隐性冲突
Streama 官方 Android/iOS App 要求 HTTPS 且证书必须由可信 CA 签发。若用自签名证书,App 会直接拒绝连接。解决方案只有两个:
- 方案一(推荐):用 Let's Encrypt 申请真实域名证书。即使内网使用,也可通过
dnsmasq将streama.home解析到内网 IP,并用acme.sh的 DNS API 方式签发; - 方案二(应急):在 App 设置中关闭 “Require HTTPS”(Android App 设置里有此开关),改用
http://streama.home:8080直连。但此方式不加密,仅限可信局域网。
注意:Nginx 的
proxy_pass必须指向http://127.0.0.1:8080,不能写https://,否则 Streama 会收到错误的X-Forwarded-Proto头,导致重定向循环。
5.4 字幕不显示——编码、路径、格式的三重校验清单
字幕文件必须满足三个条件才能被 Streama 自动识别:
- 同名同目录:
/mnt/nas/videos/电影.mp4对应/mnt/nas/videos/电影.srt; - UTF-8 编码无 BOM:用
file -i 电影.srt检查,输出应为charset=utf-8; - ANSI 编码的 SRT 文件需转码:
iconv -f gbk -t utf-8 电影.srt > 电影_utf8.srt mv 电影_utf8.srt 电影.srt
若仍不显示,在 Streama Web UI 中打开视频,右键检查元素,查看 Network 标签页是否有subtitle/xxx.srt的 404 请求。若有,说明路径映射错误,需检查application.yml中streama.video-path是否与实际路径一致。
5.5 系统重启后 Streama 未自启——rc-local 的兜底脚本编写
尽管 systemd 已enable,但某些 NAS 设备(如 Synology)的 init 系统会延迟加载 systemd,导致streama.service启动失败。此时rc-local发挥作用:
创建/etc/rc.local:
#!/bin/bash # rc.local for Streama fallback sleep 30 # 等待 systemd 完全就绪 if ! systemctl is-active --quiet streama; then systemctl start streama fi exit 0赋予执行权限:
sudo chmod +x /etc/rc.local sudo systemctl enable rc-local提示:
rc-local是最后防线,不是首选方案。优先确保 systemd 服务本身健壮,rc-local仅用于兼容性兜底。
6. 后续扩展与维护建议:从单机到家庭媒体中枢的演进路径
Streama 的定位是“私人家用视频网站”,但它的架构天然支持向家庭媒体中枢演进。基于我三年运维经验,给出三条可落地的升级路径:
路径一:接入自动化媒体整理(免手动刮削)
Streama 本身不提供 TheMovieDB 刮削,但可通过FileBot实现:
# 安装 FileBot sudo apt install openjfx wget https://github.com/filebot/filebot/releases/download/4.9.3/filebot_4.9.3_all.deb sudo dpkg -i filebot_4.9.3_all.deb # 创建整理脚本 /opt/streama/scripts/organize.sh filebot -script fn:amc --output "/mnt/nas/videos" \ --input "/mnt/nas/downloads" \ --def unsorted=y music=y artwork=y \ --def excludeList=".excludes" &配合inotifywait监控下载目录,实现“文件一落盘,自动重命名+移动+生成 NFO”。
路径二:添加离线转码队列(适配老旧设备)
Streama 的实时转码对 CPU 要求高。可引入HandBrakeCLI预转码:
# 创建转码脚本 /opt/streama/scripts/transcode.sh HandBrakeCLI -i "$1" -o "${1%.mkv}_720p.mp4" \ --preset="Fast 720p30" --encoder x264 --quality 22用at命令排队执行,避免阻塞 Streama 主进程。
路径三:与 Home Assistant 深度集成(语音控制播放)
通过 Streama 的 REST API,可在 Home Assistant 中添加媒体播放器:
# configuration