
1. 项目概述为什么需要一个真正可用的 ARM Web 界面配置指南Automatic Ripping MachineARM不是某个商业软件而是一个在 Linux 环境下运行的开源光盘自动抓取系统——它能识别插入的 DVD 或 Blu-ray 光盘自动调用 HandBrake、MakeMKV、FFmpeg 等工具完成解密、转码、元数据获取与归档最终把一张物理光盘变成结构清晰、命名规范、可入库管理的数字文件。但它的原始设计逻辑非常“极客”所有配置靠编辑 YAML 文件日志靠journalctl查状态靠systemctl status arm看任务进度靠翻/home/arm/logs/下一堆时间戳命名的日志文件。对刚接触 ARM 的用户来说这就像拿到一辆没有仪表盘、没有中控屏、连油量都要扒引擎盖看浮标的老式越野车——功能全有但每一步操作都得查手册、敲命令、猜状态。Web 界面UI Settings正是为解决这个断层而生的模块。它不改变 ARM 的核心工作流而是给底层服务套上一层实时可视化的操作外壳你能一眼看到当前正在处理哪张光盘、用了哪个配置模板、转码进度到哪一帧、是否触发了元数据匹配、失败原因直接高亮显示。更重要的是它让“配置”这件事从文本编辑器里解放出来——不用再担心 YAML 缩进错一位导致整个服务启动失败也不用每次改个输出路径就重启服务等半分钟。你点几下鼠标保存生效就这么简单。我最早在某高校媒体资源数字化实验室部署 ARM 时团队里三位老师、五位研究生没人愿意天天守着终端看日志。有人误删了arm.yaml里的min_age参数缩进结果所有新插入光盘立刻被处理连测试盘都没放过还有人把handbrake_preset写成Fast 1080p30带空格ARM 启动时报错却只提示preset not found排查了三小时才发现是引号没包住。这些不是技术缺陷而是交互设计缺失带来的真实成本。所以这篇指南不讲“ARM 是什么”也不堆砌 GitHub README 里的基础安装步骤而是聚焦于 UI Settings 这一具体模块——它怎么装、怎么配、哪些参数动不得、哪些字段改了会连锁反应、不同场景下该怎么调优。适合两类人一是已经跑通 ARM 基础流程、正卡在“怎么让非技术人员也能操作”的运维者二是准备批量部署 ARM 到多个工作站、需要统一配置策略的项目负责人。2. UI Settings 模块架构与选型逻辑为什么不是直接用 Flask Admin 或 Django AdminARM 的 Web 界面并非官方原生组件而是由社区开发者基于 Python Flask Bootstrap 构建的独立子服务通过 Unix Socket 与主 ARM 进程通信。它的存在本身就是一个权衡结果既要轻量不能拖慢光盘识别速度又要可靠不能因界面崩溃导致抓取中断还要足够灵活支持自定义字段、权限分组、多模板切换。这就决定了它不能走通用后台框架路线。2.1 为什么不选 Flask-AdminFlask-Admin 是个成熟方案但它的默认行为是“数据库驱动”——所有配置项必须映射到 ORM Model而 ARM 的核心配置是 YAML 文件结构嵌套深比如ripper: {dvd: {method: makemkv, device: /dev/sr0}, bluray: {method: makemkv, decrypt: true}}且允许用户自由扩展任意层级。Flask-Admin 强制要求每个字段声明类型和约束一旦用户在arm.yaml里加了个custom_post_process: [ffmpeg -i {input} -c:v libx265 {output}]就得同步改 Model 定义、迁移数据库、重写表单渲染逻辑。实测过一次光为支持一个自定义 hook 字段前后改了 7 个 Python 文件还导致 ARM 主进程读取配置时因字段类型不匹配抛出KeyError。2.2 为什么不用 Django AdminDjango Admin 更重依赖完整 Django 项目结构。ARM 是个专注单一任务的工具链引入 Django 意味着要维护settings.py、urls.py、migrations/目录还要处理静态文件收集collectstatic、CSRF token 管理、中间件冲突等问题。我们在某公司音像资料室试过 Django 方案部署后首次加载 Web 界面耗时 4.2 秒主要卡在django.contrib.staticfiles初始化而此时光盘已插入 3 秒ARM 主进程可能已完成设备检测并开始读取 TOC 表——界面还没打开任务已经跑了。这不是性能问题是架构错配。2.3 当前 UI Settings 的三层通信模型最终采用的方案是“松耦合三明治”结构底层ARM 主进程持续监听/tmp/arm.sockUnix Domain Socket接收来自 Web 界面的 JSON-RPC 请求如{method: get_status, params: {}}返回结构化响应如{status: idle, current_job: null}中层Web 界面服务arm-webui作为独立 Python 进程运行用socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)连接该 Socket封装请求/响应逻辑并缓存最近 5 分钟的状态快照避免高频轮询拖垮主进程上层前端用纯 HTML JavaScript无框架通过 AJAX 轮询/api/v1/status获取缓存数据所有表单提交走 POST/api/v1/config/update后端校验通过后再写入 YAML 并触发arm reload信号。这种设计的好处是Web 界面挂了ARM 照常抓盘ARM 主进程重启Web 界面最多显示“连接中断”刷新即可恢复新增配置项只需改 YAML Schema 定义schema.json前端自动渲染对应表单字段无需动一行 Python 后端代码。我们在线上环境压测过同时打开 12 个浏览器标签页访问 UICPU 占用率仅上升 1.3%而 ARM 主进程负载无变化。3. 核心配置项逐项解析哪些字段必须设哪些可以留空哪些改了会触发连锁反应UI Settings 的配置页面分为六大区块全局设置、光盘识别策略、转码规则、元数据获取、存储路径、通知与日志。每个字段背后都有明确的业务意图和约束条件不是填了就能用。下面按实际使用频率和风险等级排序详解。3.1 全局设置Global Settings决定整个系统的“呼吸节奏”web_port默认 8080Web 界面监听端口。看似简单但要注意两点一是不能与 ARM 主进程的http_port默认 5000冲突否则systemctl restart arm-webui会失败二是若服务器启用了防火墙如ufw必须显式放行该端口sudo ufw allow 8080。我们曾遇到某图书馆服务器因ufw默认 deny all管理员填了 8080 却打不开界面折腾两小时才发现是防火墙挡的。auto_reload_config布尔值默认 true是否在 YAML 配置变更后自动重载。设为true时UI 提交后立即生效设为false则需手动执行sudo systemctl restart arm。生产环境建议设为false因为某些配置变更如修改ripper.dvd.method需要重新初始化设备句柄强制 reload 可能导致正在抓取的光盘中断。我们在线上环境的 SOP 是日常调参用true重大配置升级如切换解密引擎则切回false人工确认无误后再重启。max_concurrent_jobs整数默认 1最大并发任务数。这里有个关键陷阱ARM 本身不支持真正的多光盘并行同一时刻只能处理一张光盘此参数实际控制的是“排队队列长度”。设为 3 意味着插入三张光盘后第三张会进入等待队列前两张按顺序处理。但如果ripper.dvd.device指向/dev/sr0而服务器实际有/dev/sr0和/dev/sr1两个光驱此参数无效——ARM 不会自动分配设备。要实现双光驱并行必须在arm.yaml中显式定义devices: [/dev/sr0, /dev/sr1]并在 UI 中启用multi_device_mode该选项在“光盘识别策略”区块。3.2 光盘识别策略Disc Detection让 ARM “认出”你的光盘disc_id_method枚举值md5,volume_label,makemkv_id光盘唯一标识生成方式。md5对光盘首 1MB 数据做哈希速度快但无法区分同内容不同压制版本如导演剪辑版 vs. 剧院版volume_label读取光盘卷标如DVD_VIDEO,BLURAY_DISC稳定但易被伪造makemkv_id调用 MakeMKV 的--scan命令提取内部 ID最准但耗时平均 8~12 秒。实测数据在 Intel i5-8400 SATA DVD-ROM 上makemkv_id识别准确率 99.7%1000 张测试盘仅 3 张失败而md5误识别率 12.4%主要因压制时填充数据差异。所以除非你处理的是自制 DVD无标准卷标否则必选makemkv_id。min_age秒默认 30光盘插入后等待多少秒再开始识别。这是防误触的关键。很多用户抱怨“刚插盘就开抓根本来不及换片”根源就是min_age太小。我们建议DVD 设为 45 秒Blu-ray 设为 90 秒。计算依据是DVD 平均识别耗时 22 秒makemkv_id模式Blu-ray 平均 68 秒留出 20 秒缓冲应对老旧光驱。如果设为 0ARM 会在设备就绪瞬间发起lsblk查询可能读到未完全初始化的设备状态导致device busy错误。ignore_devices字符串数组默认[]忽略特定设备路径。典型场景服务器有 USB 光驱/dev/sr1专供管理员调试不想让它参与自动抓取。填入[/dev/sr1]即可。注意格式必须是 JSON 数组字符串不能写成/dev/sr1单字符串否则 UI 解析失败整个配置页变灰。3.3 转码规则Transcoding Rules决定数字文件的“长相”handbrake_preset字符串默认Fast 1080p30HandBrake 预设名。这里极易踩坑ARM 内部调用的是HandBrakeCLI命令行它只认 HandBrake 自带预设--preset-list输出的列表不支持用户自定义预设名。如果你在 HandBrake GUI 里新建了个叫My_DVD_Archive的预设ARM 无法识别。正确做法是先在终端执行HandBrakeCLI --preset-list | grep -i dvd找到官方预设名如HQ DVD再填入此处。我们整理过常用预设对照表光盘类型推荐预设码率范围典型体积90分钟DVDHQ DVD1800~2200 kbps2.1~2.6 GBBlu-rayHQ 1080p306500~7500 kbps7.8~8.9 GB动画片Animation3200 kbps3.8 GB提示预设名区分大小写且必须与HandBrakeCLI --preset-list输出完全一致多一个空格都会报错。ffmpeg_custom_args字符串默认FFmpeg 自定义参数。这是高级用户的“逃生舱口”。例如某纪录片需要保留 5.1 声道但降采样到 48kHz原盘是 96kHz可填入-ac 6 -ar 48000。但要注意ARM 会将此字符串直接拼接到 FFmpeg 命令末尾所以不能包含-i或-c:v等已有参数否则冲突。我们曾有用户填了-c:v libx265 -crf 22结果 ARM 自动生成的命令变成ffmpeg -i input.mkv ... -c:v libx264 -c:v libx265 -crf 22 output.mp4编码器冲突直接失败。3.4 存储路径Storage Paths文件落地的“户籍所在地”media_dir字符串默认/home/arm/media主媒体库根目录。所有转码完成的文件都存于此。关键约束此路径必须对arm用户运行 ARM 的系统用户有读写权限且不能是 NFS 或 CIFS 挂载点ARM 不支持网络文件系统上的原子性重命名操作。我们在线上环境强制要求media_dir必须是本地 ext4/XFS 分区且chown arm:arm /home/arm/media。intermediate_dir字符串默认/home/arm/tmp临时文件目录。ARM 在转码前会把光盘内容先解包到此处再喂给 HandBrake。此处 I/O 压力极大必须用 SSD。实测HDD 上intermediate_dir会导致 DVD 抓取速度从 1.8x 降到 0.9x瓶颈在解包阶段。我们给客户的配置规范里明确写“若intermediate_dir在 HDD性能下降视为预期行为不受理相关工单”。naming_scheme字符串默认{{ title }} ({{ year }})文件命名模板。支持 Jinja2 语法变量包括title,year,resolution,source等。常见错误是用中文括号或全角符号如《{{ title }}》{{ year }}会导致 Linux 文件系统创建失败Invalid argument。必须用英文半角符号。我们推荐的安全模板{title} ({year}) [{resolution} {source}]生成效果如Inception (2010) [1080p DVD]。4. 实操全流程从零部署 UI Settings 到生产环境稳定运行部署不是复制粘贴几条命令而是一套需验证每步结果的闭环流程。以下是我们给客户交付的标准 SOP已在 37 个不同硬件环境从 NUC 到 Dell R740上验证通过。4.1 环境准备确认 ARM 已稳定运行UI Settings 依赖 ARM 主服务正常工作所以第一步永远是验证基础。执行# 检查 ARM 服务状态 sudo systemctl status arm # 应显示 active (running)且 Latest logs 中有 ARM service started # 检查 Socket 文件是否存在 ls -l /tmp/arm.sock # 应显示 srw-rw-rw- 1 root root ...注意开头的 s表示 socket # 手动触发一次识别插入空白 DVD sudo -u arm python3 /opt/arm/arm/main.py --debug # 观察日志末尾是否出现 Disc identified as DVD注意如果systemctl status arm显示failed不要继续部署 UI。常见原因是arm.yaml语法错误YAML 对缩进极其敏感或handbrake-cli未安装。先运行yamllint /opt/arm/arm/arm.yaml检查语法再执行which HandBrakeCLI确认路径。4.2 安装 UI Settings 服务ARM 社区提供两种安装方式Git 克隆源码 or pip 安装。我们强制推荐 Git 方式因为 pip 包版本滞后最新 pip 版本是 2.3.1而 GitHub 主干已是 2.5.0修复了 Blu-ray 元数据匹配 bug。步骤# 创建专用目录 sudo mkdir -p /opt/arm-webui sudo chown arm:arm /opt/arm-webui # 切换到 arm 用户克隆避免权限问题 sudo -u arm git clone https://github.com/automatic-ripping-machine/ARM-WebUI.git /opt/arm-webui # 安装 Python 依赖注意必须用 arm 用户执行否则 pip 安装的包对 arm 进程不可见 sudo -u arm pip3 install -r /opt/arm-webui/requirements.txt # 复制配置模板 sudo -u arm cp /opt/arm-webui/config.example.json /opt/arm-webui/config.json此时/opt/arm-webui/config.json是空配置下一步要填入关键参数。4.3 配置文件config.json手动初始化UI Settings 启动时会读取config.json但它的字段与arm.yaml不同需手动映射。重点填以下 5 个字段其余可保持默认{ web_port: 8080, arm_config_path: /opt/arm/arm/arm.yaml, arm_socket_path: /tmp/arm.sock, log_level: INFO, enable_auth: false }arm_config_path必须指向真实的arm.yaml路径。ARM 默认在/opt/arm/arm/但有些用户自定义到/etc/arm/此处必须严格匹配。arm_socket_path必须与arm.yaml中webui.socket_path值一致默认即/tmp/arm.sock。如果不一致UI 启动后会显示 Connection refused。enable_auth设为false表示无需登录适合内网环境设为true则需额外配置auth_user和auth_pass密码明文存储不推荐。4.4 创建 systemd 服务单元让 UI Settings 作为系统服务常驻运行而非前台进程。创建/etc/systemd/system/arm-webui.service[Unit] DescriptionARM Web UI Service Afterarm.service Wantsarm.service [Service] Typesimple Userarm WorkingDirectory/opt/arm-webui ExecStart/usr/bin/python3 /opt/arm-webui/app.py Restarton-failure RestartSec10 EnvironmentPYTHONUNBUFFERED1 [Install] WantedBymulti-user.target关键点Afterarm.service确保 ARM 主进程先启动Userarm必须与 ARM 主服务一致否则无法访问/tmp/arm.socksocket 文件权限为srw-rw-rw- 1 arm armRestartSec10设置 10 秒后重启避免频繁崩溃UI 本身很稳定此值仅为保险。启用服务sudo systemctl daemon-reload sudo systemctl enable arm-webui sudo systemctl start arm-webui sudo systemctl status arm-webui # 应显示 active (running)且日志末尾有 Web UI listening on port 80804.5 首次访问与配置同步打开浏览器访问http://服务器IP:8080首次加载会较慢约 8~12 秒因为 UI 需扫描arm.yaml结构并生成表单。成功后页面顶部显示绿色横幅Connected to ARM v2.5.0。点击右上角齿轮图标进入配置页此时会发现所有字段都是空的——因为 UI Settings 默认不读取arm.yaml的值需手动点击Sync from arm.yaml按钮位于页面右下角。注意此按钮只做单向同步arm.yaml → UI不会修改arm.yaml。点击后UI 表单自动填入当前arm.yaml的值你才能开始修改。如果按钮灰色不可点说明arm_config_path配置错误或arm.yaml不存在。4.6 生产环境必做的三项验证部署完成不等于可用必须通过以下验证插入测试盘验证流程闭环插入一张已知标题的 DVD观察 UI 界面左上角状态栏应从Idle变为Detecting disc...再变为Ripping DVD...“当前任务”面板显示光盘标题、识别 ID、预计剩余时间转码完成后media_dir下生成对应文件夹且文件名符合naming_scheme。修改配置验证热更新在 UI 中将handbrake_preset改为HQ DVD点击保存。观察日志sudo journalctl -u arm-webui -n 20 --no-pager # 应出现 Config updated successfully 和 Reloading ARM config... # 再插入新 DVD确认转码日志中 HandBrake 命令含 --preset HQ DVD故障注入验证容错性手动停掉 ARM 主服务sudo systemctl stop arm观察 UI状态栏变为红色Disconnected from ARM所有操作按钮禁用防止误操作5 秒后自动重连恢复连接后显示Reconnected。此验证确保网络抖动或 ARM 重启时UI 不会发送无效指令。5. 常见问题与独家排查技巧那些文档里不会写的“血泪经验”5.1 典型问题速查表现象可能原因排查命令解决方案页面打不开ERR_CONNECTION_REFUSEDarm-webui.service未运行或端口被占sudo systemctl status arm-webuisudo ss -tulngrep :8080点击 Sync from arm.yaml 无反应arm_config_path路径错误或arm.yaml权限不足sudo -u arm cat /opt/arm/arm/arm.yaml | head -5确保路径正确且arm.yaml对arm用户可读chmod 644 /opt/arm/arm/arm.yaml转码后文件名含乱码如★★★naming_scheme模板含 UTF-8 BOM 或系统 locale 不支持中文localefile -i /opt/arm-webui/config.json在arm-webui.service的[Service]段添加EnvironmentLANGen_US.UTF-8然后sudo systemctl daemon-reload restart arm-webui插入 Blu-ray 后一直卡在Detecting disc...disc_id_method设为makemkv_id但 MakeMKV 未授权sudo -u arm makemkvcon --version运行sudo -u arm makemkvcon -r --cache/tmp/makemkv cache 1获取试用密钥填入arm.yaml的makemkv.key字段5.2 三个“踩过坑才懂”的硬核技巧技巧一用curl直接调用 API 绕过 UI 故障当 UI 页面卡死或 CSS 加载失败常见于低配设备可直接用命令行操作。例如强制重载配置curl -X POST http://localhost:8080/api/v1/config/reload # 返回 {status: success, message: Config reloaded}查看当前状态curl http://localhost:8080/api/v1/status \| python3 -m json.tool # 返回完整 JSON含 current_job, queue_length 等字段这招在远程服务器无图形界面时救过我们多次。技巧二日志分级定位法UI Settings 日志分散在三处需交叉比对sudo journalctl -u arm-webuiWeb 服务自身日志HTTP 请求、配置加载sudo journalctl -u armARM 主进程日志光盘识别、转码执行/home/arm/logs/arm-date.logARM 详细任务日志含 HandBrake 命令输出。典型案例某客户反馈“UI 显示转码完成但 media_dir 无文件”。我们查arm-webui日志发现{status: completed}查arm日志发现HandBrakeCLI exited with code 1再查arm-date.log找到关键行Error: No video track found。最终定位是源盘损坏UI 因超时机制误判为成功。技巧三配置备份的“黄金三分钟”法则每次通过 UI 修改配置前必须执行sudo cp /opt/arm/arm/arm.yaml /opt/arm/arm/arm.yaml.$(date %Y%m%d_%H%M%S).bak为什么是三分钟因为 ARM 的min_age默认 30 秒UI 提交后 ARM 最多 30 秒内开始执行而人工干预如拔盘、停服务窗口只有这 30 秒。备份文件名含时间戳确保可追溯。我们线上环境规定无备份操作视为违规需提交 RCA根本原因分析报告。6. 进阶配置与场景化扩展让 UI Settings 适配你的独特需求UI Settings 的默认配置面向通用场景但真实世界更复杂。以下是我们在不同客户现场落地的三个扩展方案全部基于现有 UI 框架无需改代码。6.1 多校区分布式部署一套 UI 管理多台 ARM 服务器某高校有 4 个校区每个校区一台 ARM 服务器处理本地音像资料。他们不想为每台服务器单独维护 UI希望统一入口。方案是在中心服务器部署 Nginx 反向代理将不同路径映射到各校区 ARM 的 UI 端口# /etc/nginx/sites-available/arm-central server { listen 80; server_name arm.university.edu; location /campus-a/ { proxy_pass http://192.168.1.10:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /campus-b/ { proxy_pass http://192.168.1.11:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }用户访问http://arm.university.edu/campus-a/即操作 A 校区服务器。关键点UI 的前端 JS 会自动从当前 URL 路径推导 API 基地址所以proxy_pass后的/不能省略否则 API 请求会发到根路径导致 404。6.2 敏感内容过滤自动拦截含特定关键词的光盘某档案馆要求所有含“内部资料”、“机密”字样的光盘禁止自动抓取需人工审核。ARM 本身无此功能但可利用 UI Settings 的pre_rip_hook机制。在arm.yaml中添加pre_rip_hook: /opt/arm/scripts/filter_sensitive.sh {disc_id}再创建/opt/arm/scripts/filter_sensitive.sh#!/bin/bash DISC_ID$1 # 从 MakeMKV 扫描日志中提取标题 TITLE$(grep -A 5 TID:$DISC_ID /home/arm/logs/makemkv-scan.log 2/dev/null | grep Title: | head -1 | cut -d: -f2 | tr -d ) if echo $TITLE | grep -iq 内部资料\|机密; then echo SENSITIVE CONTENT DETECTED: $TITLE exit 1 # ARM 遇到非零退出码中止任务 fiUI Settings 会自动将此脚本显示在“高级设置”区块管理员可一键启用/禁用。6.3 与现有资产管理系统集成自动推送元数据某博物馆已有 PIM产品信息管理系统要求 ARM 抓取完成后自动将影片标题、年份、分辨率等字段 POST 到其 API。利用 UI Settings 的post_process_hookpost_process_hook: /opt/arm/scripts/push_to_pim.sh {output_file} {title} {year}脚本中用curl发送 JSONcurl -X POST https://pim.museum/api/assets \ -H Content-Type: application/json \ -d {\title\:\$2\, \year\:\$3\, \file_size\:\$(stat -c%s $1)\, \path\:\$1\}UI Settings 会将post_process_hook字段暴露在配置页方便管理员维护 API 地址和 Token。我在实际部署中发现最有效的配置不是追求功能全而是抓住核心痛点让非技术人员敢操作、让运维人员少救火、让管理者看得清。ARM Web 界面的价值从来不在炫酷的 UI而在把“不确定”变成“确定”——插入光盘前你知道它会被怎么处理转码中途你知道卡在哪一步归档完成后你知道文件在哪、叫什么、谁经手过。这套配置指南里的每一个参数、每一行命令、每一个技巧都来自真实场景的反复打磨。它不承诺“一键完美”但保证“每一步都有据可依”。