Files
UHD_Media_Tool/docs/design/file-preview-research.md
T
rootandClaude Opus 5.5 289e8b297a feat(files): wide file manager layout and basic previews (FM-2)
- Files page uses a wide layout (route handle layout:"wide"): no max width,
  full-height directory tree docked next to the sidebar, resizable
  (200-520px, remembered, double-click resets) and collapsible; mobile keeps
  the tree in a drawer.
- GET /files/preview (admin console session only, same path guards as
  download): text/NFO with encoding detection (BOM/UTF-16/UTF-8/GB18030/Big5),
  subtitles first 200 cues (SRT/VTT/ASS/SSA, PGS timings), .torrent file
  list/trackers (passkey masked)/infohash, image dimensions. Reads at most
  1 MiB of text; .torrent capped at 4 MiB.
- Download also allows text files, .torrent and avif/gif.
- Research notes in docs/design/file-preview-research.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 21:44:13 +08:00

3.9 KiB
Raw Blame History

文件管理基础预览调研(FM-2)

2026-09-29。范围:文件管理详情抽屉里除视频播放以外的预览。前提:单容器 4C/8G;前端库只能来自 npm;所有读取走 resolveIn + recheck(realpath 在登记目录内、符号链接目标也须在内),仅管理员控制台会话。

核实:镜像 /usr/local/bin 只有 ffprobe 9.0.2(141 MB,取自 mwader/static-ffmpeg:9.0.2),没有 ffmpeg。同一镜像里的 ffmpeg 静态二进制也是 141 MB,加进来要改 Dockerfile 和编译参数 --allow-run。

MP 对照:MoviePilot 文件管理只有图片预览(/storage/image 取原图转 blob),另有识别和刮削,没有文本、字幕和种子预览。

逐项结论

类别 用户价值 实现 安全 工作量 建议
图片 jpg/png/webp/avif/gif 高:核对海报、背景是否刮对 原图经 /files/download?inline 显示(≤20 MB,loading=lazy);服务端读文件头回宽高 SVG 不内联(可带脚本);nosniff + sandbox CSP S 已做
图片缩略图 中:列表网格、海报墙 需 ffmpeg(+141 MB)或 sharp/libvips(npm 原生模块,deno compile 嵌入风险)或 wasm 解码(内存峰值高) 解码炸弹(超大分辨率):限像素数 M 后做,等有网格视图再定
文本 nfo/txt/log/md/json/xml/yaml 高:看 NFO、发布说明、日志 服务端读前 1 MB,编码探测 BOM → UTF-16 → UTF-8 → GB18030/Big5 择优 → Latin-1;json 美化 一律按纯文本渲染(React 转义),md 不渲染 HTML S 已做
Markdown 渲染 低 markdown-it + DOMPurify(约 60 KB) 必须消毒 S 不做,纯文本够用
字幕 srt/vtt/ass/ssa 高:确认语言、编码、时间轴对不对 服务端解析前 1 MB,按时间排序回前 200 条;ASS 取 Title、去覆写标签 纯文本输出 S 已做
字幕 sup(PGS) 中 解析段头,只列起止时间 只读段头 S 已做;渲染图形不做
音频 flac/mp3 试听 低:库里音频多是音轨附件 浏览器 <audio> + HTTP Range;需给下载接口加 Range 与音频类型放行 大文件流式,不经内存 S 后做
PDF 很低:媒体库几乎没有 <iframe> 内嵌(浏览器自带);pdf.js 约 1 MB 不值 内嵌需同源 + sandbox S 不做
压缩包列表 zip/rar/7z 中:字幕包、原盘分卷 zip 纯 JS 读中央目录即可;rar/7z 需 unrar/7z 子进程或 wasm(libarchive.js 约 1 MB) 只读目录不解压,不会触发压缩炸弹;条目数设上限;文件名当纯文本 zip S / rar·7z M zip 后做,rar/7z 视需求
.torrent 高:核对资源内容、hash、是否私有 复用 @umt/adapters 的 parseTorrent;≤4 MB;回前 500 个文件与 tracker tracker 里的 passkey 服务端打码 S 已做
视频规格 高 已有「探测」(ffprobe 摘要,缓存 24 小时) — — 已有
视频关键帧截图条 中:确认片源、是否黑边/HDR 发灰 需 ffmpeg;每次 4–6 帧、限时、结果缓存到 DATA_DIR 并发与 CPU 上限(4C);超时 SIGKILL M 后做,和缩略图一起决定是否加 ffmpeg
ISO/BDMV 结构识别 中:原盘目录显示主片、时长 BDMV 目录读 index.bdmv/MPLS 找最长播放列表;ISO 需 UDF 解析 只读 M(BDMV)/ L(ISO) 后做,先做 BDMV 目录

已实现(本分支)

  • GET /files/preview?root&path:返回 text / subtitle / torrent / image 四种结构,只回 JSON,不回原始内容;扩展名白名单与前端同表。上限:文本和字幕读前 1 MB,图片读头 512 KB,.torrent ≤4 MB,超过回 413。
  • 下载接口同步放行文本类、.torrent、avif/gif;视频仍不经浏览器。
  • 预览不写审计(只读、量大),下载仍写。
  • 前端:详情抽屉「预览」节;格式、编码、hash、分块等收进「技术信息」。

需要决定

  1. 是否在镜像里加 ffmpeg(+141 MB):决定缩略图、截图条两项。
  2. 音频试听要给下载接口加 Range,是否放开音频类型。