18 KiB
ImageFind
ImageFind 是面向 fnOS/NAS 的私有 AI 媒体库。它提供类似视频网站的浏览、在线播放、上传、 下载和资料管理体验,可索引本地目录、通用 WebDAV、AList 直连库与 AList 加密库,并通过 中英文关键词、番号/演员/标签、OCR/字幕/音频语音、查询图片和已命名人物定位到视频中的具体时间片段。
当前版本为可侧载验证的
0.5.45。应用声明 fnOS Python 3.12 和 PostgreSQL 依赖,核心运行环境离线安装, PyTorch、OpenVINO 和各类 AI 依赖在安装对应模型时按需下载;AI 模型权重可在“设置”中 按组件下载、通过离线脚本准备或上传完整模型包。 上传、移动和回收站操作只会对明确启用写入的资料库生效。
本地开发
要求 Python 3.11–3.13、Node.js 20+、FFmpeg/FFprobe,以及启用 vector、pg_trgm 扩展的
PostgreSQL 17。业务数据、全文索引和语义向量均由 PostgreSQL 保存,不再使用 SQLite 或 Qdrant
作为运行数据库。启动前通过 IMAGEFIND_POSTGRES_CONF 指向 PostgreSQL 客户端配置文件。
python3 -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
npm install --prefix frontend
npm run build --prefix frontend
IMAGEFIND_DATA_DIR="$PWD/.data" imagefind
打开 http://127.0.0.1:8765。本地开发时首次访问需创建不少于 10 个字符的管理员密码;
fnOS 安装包会在安装向导中完成这一步。
UI 回归使用 Playwright。Linux 截图机必须安装 fonts-noto-cjk,缺少中文字体时测试会直接失败,
避免把方框字保存为视觉基线:
cd frontend
npm run test:ui
飞牛真机测试使用独立配置,不在仓库保存 NAS 密码或浏览器会话。先把已登录管理员浏览器的
Playwright storageState 保存到仓库外,并准备一个只放测试文件的可写资料库:
IMAGEFIND_FNOS_BASE_URL="https://NAS地址/app/imagefind/" \
IMAGEFIND_FNOS_STORAGE_STATE="/安全目录/fnos-storage-state.json" \
IMAGEFIND_E2E_SOURCE_NAME="ImageFind E2E" \
npm run test:ui:fnos
写入测试只清理本次创建且以 E2E- 开头的文件,不会操作其他媒体。
常用配置:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
IMAGEFIND_DATA_DIR |
./data |
数据库、缩略图、模型和缓存目录 |
IMAGEFIND_HOST / IMAGEFIND_PORT |
127.0.0.1 / 8765 |
监听地址与端口 |
IMAGEFIND_POSTGRES_CONF |
数据目录上级的 postgres-client.conf |
PostgreSQL 客户端配置文件 |
IMAGEFIND_DB_POOL_MIN / IMAGEFIND_DB_POOL_MAX |
1 / 8 |
PostgreSQL 进程内连接池上下限 |
IMAGEFIND_DB_POOL_TIMEOUT |
5 |
等待可用数据库连接的最长秒数 |
IMAGEFIND_EMBEDDING_BACKEND |
auto |
auto、openvino、torch 或测试用 hash |
IMAGEFIND_MODEL_BUNDLE_URL |
空 | 可选:用自建模型包代替默认官方仓库 |
IMAGEFIND_MODEL_BUNDLE_SHA256 |
空 | 自建模型包的 SHA-256 |
IMAGEFIND_MODEL_HF_ENDPOINT |
https://huggingface.co |
Hugging Face 地址,可改为可信镜像 |
IMAGEFIND_PIP_INDEX_URL |
https://pypi.tuna.tsinghua.edu.cn/simple |
AI 运行依赖使用的 PyPI 主镜像 |
IMAGEFIND_PYTORCH_INDEX_URL |
https://download.pytorch.org/whl/cpu |
PyTorch CPU 专用轮子源,可在设置页留空或修改 |
IMAGEFIND_MODEL_UPLOAD_GB |
10 |
手动上传模型包上限(GiB) |
IMAGEFIND_FFMPEG_PATH |
ffmpeg |
FFmpeg 可执行文件 |
IMAGEFIND_REMOTE_MAX_CONNECTIONS |
3 |
WebDAV 扫描、索引和播放的全局并发上限 |
IMAGEFIND_PREVIEW_CACHE_GB |
5 |
HLS 兼容预览缓存上限(GiB) |
IMAGEFIND_UPLOAD_CHUNK_MB |
16 |
浏览器上传分块大小(MiB) |
IMAGEFIND_UPLOAD_STAGING_GB |
100 |
未完成上传的暂存配额(GiB) |
IMAGEFIND_UPLOAD_RESERVE_GB |
5 |
创建上传任务后仍需保留的磁盘空间(GiB) |
IMAGEFIND_TRASH_RETENTION_DAYS |
30 |
回收站记录的默认保留天数 |
远程媒体库与加密
通用 WebDAV 和 AList 均在“资料库 → 添加资料库”中配置。扫描器使用递归 Depth: 1 PROPFIND,以 ETag、大小和修改时间识别变更。服务端不支持 Range 时,索引或播放可能退化为
完整文件传输,建议先在小目录验证带宽占用。
AList 有两种互斥模式:
- AList 直连:文件和文件名以明文保存在远端。播放接口向浏览器返回 AList 提供的 302 临时直链,视频流量通常不经过 NAS;直链解析失败时自动回退到认证代理。
- AList 加密:使用
rclone crypt加密文件内容、文件名和目录名。应用优先使用 fnOS/系统 已安装的兼容 rclone,缺失时再下载经过版本与 SHA-256 固定的私有副本。上传、 播放、下载、抽帧和 AI 索引均由 NAS 即时解密,因此不能再使用 302 直链,带宽会经过 NAS。
ImageFind 每 60 秒安全核验上次异常退出遗留的 rclone 实例。只有进程身份和应用目录匹配、连续 3 次没有活动连接或 I/O 且观察满 2 分钟时才会自动回收;身份不一致的进程只标记为“待处理”, 不会强制终止。也可以在“设置 → 任务与偏好 → 资源保护”中执行一次立即安全核验。
创建加密库时浏览器会自动下载一次 imagefind-vault-recovery-*.json。必须把它存放在密码管理器
或离线介质中;它含有解密所需密钥,但不包含 AList 登录密码。重装后选择“AList 加密 → 从恢复
文件导入”,再输入当前 AList 密码,即可重新挂载原有密文。丢失恢复文件和应用内部数据后,
远端密文无法恢复。
AI 对加密库仍完整可用:NAS 读取并解密所需片段后执行抽帧、OCR、人物与向量分析,远端不会 得到明文索引。代价是首次扫描和播放都需要 NAS 与网盘之间的传输。
也可以先在 fnOS 中挂载 WebDAV,再作为本地目录添加。这种模式通常拥有更好的断线重连和 系统级缓存能力。
上传、下载与文件管理
浏览器上传采用 16 MiB 分块,每块带 SHA-256 校验,单文件 API 上限为 200 GiB,前端按当前 产品约束提示 100 GiB。文件会先完整暂存在应用私有数据目录,再由独立后台通道传输到目标库; 上传过程中断后,服务端会保留已接收分块用于续传;上传中心分别显示“上传至 ImageFind”、 “转存 WebDAV/AList”和“校验加入媒体库”三个阶段,失败的目标传输可直接重试。创建任务 时若无法满足暂存配额或 5 GiB 安全余量,接口会拒绝任务而不是写满系统盘。
开启飞牛“直接 Web/API 访问”后,可在“设置 → 账户与 API”启用 WebDAV 后台上传。标准
WebDAV 客户端必须连接 http://NAS_IP:8765/webdav/(端口以应用配置为准),用户名固定为
imagefind,密码使用页面创建且只显示一次的专用 REST API Token。飞牛 5666 统一网页网关
不转发标准 DAV 认证和方法,不能作为 WebDAV 服务器地址。上传路径的第一层目录会自动映射为
同名合集,后续目录映射为可任意嵌套的章节或小节;已入库视频可浏览和读取。服务端兼容普通
PUT、临时文件加 MOVE、Content-Range 与 Upload-Offset 续传。完整上传会在接收时增量
校验且不再二次扫描暂存文件;客户端因响应丢失重传相同路径和内容时会幂等返回,不会再生成
(2)、(3) 副本。文件接收完成到媒体入库之间,HEAD/PROPFIND 仍会返回已接收状态,
避免客户端因短暂 404 重新上传。
本地目录默认只读,必须在资料库卡片上主动启用写入;AList 资料库默认可写。文件面板支持浏览、 新建目录、移动/重命名和移入回收站。回收站内可恢复或永久删除;卸载应用不会删除共享目录、 已授权目录或远端库中的源视频。播放接口支持 HTTP Range;AList 直连下载/播放可使用 302, 其余来源经 ImageFind 认证代理读取,下载会保留原文件名。
后台任务按 AI 识别、上传转存、后台下载和来源扫描分为四条独立通道,各自保持单并发。这样 大文件上云不会阻塞索引,同时避免低功耗 NAS 因多个 AI 或磁盘任务并发而耗尽内存。
自定义分类与 AI 标签
“分类与标签”支持创建任意分类组,例如类型、场景、服装、片商或自定义收藏维度。每个组可设置为 单选或多选;影片资料编辑和批量赋值都会遵守该约束。标签可以移动、合并和删除,旧版字符串标签 在升级时会自动迁移到“未分组”。
每个标签都可以独立启用一种 AI 建议方式:
- 画面语义:使用已生成的 CLIP 画面向量与自定义描述做零样本匹配,适合能从画面判断的场景、 服装和视觉类型。
- 文本规则:匹配文件名、路径、影片资料、OCR 和文本字幕,适合番号、片商、系列或明确关键词。
AI 结果只会进入“待确认建议”,不会直接覆盖人工标签。索引新视频完成后会自动排队分析已启用 AI 的标签,也可从影片资料或分类页手动重跑。服务启动、状态检查和仅浏览页面都不会加载模型; 模型仍然只在实际索引、图片/语义检索或手动分析需要时延迟初始化。自定义标签的准确度取决于描述、 阈值和素材,不能可靠由画面判断的抽象标签应使用文本规则或保持手动。
系统备份与恢复
“设置 → 系统备份与恢复”可下载单一 .ifbackup 加密文件。每个备份都包含本地、WebDAV 与
AList 来源配置、登录凭据和 rclone crypt 密钥;完整范围还包含影片身份、手工资料、分类与标签、
演员、收藏、喜欢、播放进度、偏好和模型/运行依赖镜像配置。备份密码独立于管理员密码,长度为 10–256 个
字符,不会持久化;忘记密码后无法解密。
恢复前需在新系统创建管理员并登录。只有没有来源、影片、AI 人物、演员或用户标签的空系统可以 恢复。当前管理员、会话和 API Token 不会被导入或覆盖;媒体文件、模型、缩略图、OCR、人物聚类、 向量与其他可重建索引也不进入备份。恢复后影片先处于不可播放的待扫描状态,启用的来源会自动排队 扫描,并按来源 ID 与源文件键重新关联原影片 ID。
fnOS 视频目录
安装或升级后,fnOS 会创建共享目录 imagefind/videos,应用运行用户会自动获得访问权限。
可以把待索引视频放入该目录,再在 ImageFind 中将它添加为本地资料库。
如果视频已经位于其他 NAS 目录,无需搬动文件:在 fnOS 的 ImageFind 应用设置中授权这些
目录,再在 ImageFind 中添加对应路径。imagefind/videos 是便于直接导入文件的应用共享目录,
授权目录可用于只读索引已有媒体库;只有在 ImageFind 内明确启用写入后,文件管理和上传操作
才允许修改该目录。AI 索引过程本身不会修改源视频。
fnOS 全新安装时必须输入两次 ImageFind 管理员密码。升级向导中的密码可以留空以保留
现有密码,也可以填写两次来初始化或重置密码。卸载向导默认保留应用数据;勾选清除后会
删除数据库、索引、缓存、模型、凭据和日志,但不会删除 imagefind/videos、用户授权目录
或 WebDAV 上的任何源视频。
播放与 HLS 兼容预览
搜索结果优先通过认证后的 Range 接口直接播放,并跳转到命中时间。浏览器不支持源视频的 封装格式或编码时,前端会自动请求命中点附近的 HLS 兼容预览。预览默认最长 180 秒,优先 使用 Intel VAAPI,随后尝试 OpenH264 或 libx264;缓存达到上限后按最久未使用顺序清理。
生成兼容预览会消耗额外 CPU/GPU 和临时空间。远程源还会读取对应时间段;WebDAV 服务端若 忽略 Range,可能退化为完整文件传输。
模型包约定
fnOS 安装包包含 Web 服务与 PostgreSQL 客户端运行依赖,数据库和 pgvector 由声明的
nxsir.postgresql fnOS 依赖应用提供;OpenVINO、PyTorch 等推理运行时
与体积更大的模型权重不随包发布,而是在首次安装对应 AI 组件时按需下载。设置页的在线安装
会从 Hugging Face 下载画面/多语言模型及 Whisper small,从 Open Model Zoo 下载人物模型。Whisper
会导出为 OpenVINO FP16;安装后以单任务串行方式自动补齐旧影片的带时间轴语音索引。应用启动
和状态检查都不会加载模型到内存,只有搜索或索引实际需要时才延迟初始化。
语音识别默认采用“中文优先 + 准确率优先”:先读取音轨语言,再从最多 3 个高语音占比片段检测, 无法判断时使用中文,并以 5-beam 解码。每个时间片段会经过字符损坏、异常文字脚本、重复输出、 无语音幻觉和文本密度校验,低质量片段不会进入搜索。设置页可切换智能检测、固定中文和三档质量, 也可扫描存量旧转写;明显低质量的视频会自动排队重新识别。
“设置 → AI 与网络”可分别配置 Hugging Face、PyPI 和 PyTorch CPU 下载源。PyPI 默认使用已直连 验证的清华镜像;HTTP/HTTPS 代理有独立开关,关闭后保留加密凭据但所有 AI 下载直接连接,启用后 才用于模型与运行依赖下载。pip 安装期间每隔约 5 秒更新阶段和等待时间,任务重启排队时会重置为 0%,避免把等待中的组件误显示为卡住。
无法直接访问官方仓库时,可以在其他电脑准备下述 ImageFind 模型包,再通过设置页“上传模型包”
手动安装。服务端以流式方式写入应用数据目录,不会先占用 fnOS 的 /tmp;安装前会检查压缩包
路径、解压体积和必需目录,并以原子方式替换现有模型。
模型包是 .tar.gz,根目录必须包含 manifest.json 以及:
visual/image/ # clip-ViT-B-32 SentenceTransformer 模型
visual/text/ # clip-ViT-B-32-multilingual-v1 文本模型
ocr/ # 可选:det.onnx、rec.onnx、cls.onnx
faces/ # 可选:detector.xml/.bin、reidentification.xml/.bin
audio/ # 可选:Whisper small OpenVINO FP16 模型和处理器配置
视觉模型变化后需要重建画面向量;应用不会静默切换向量空间。
生成模型包不会修改源模型目录:
python3 scripts/build-model-bundle.py /path/to/models dist/imagefind-models.tar.gz --version 1
构建 fnOS 安装包
发布构建只面向 x86_64 fnOS,需要官方 fnpack、Node.js、带 Hatchling/Pillow 的构建环境,
以及 .fnos-wheel-cache/python312 中完整的 Python 3.12 核心 wheelhouse。fnOS 端声明依赖
python312;AI 推理依赖不会进入 FPK,而是在安装对应模型时按锁文件下载。发布包只内置:
vendor/libOpenCL.so.1
安装依赖并构建:
python3 -m venv .release-venv
.release-venv/bin/pip install -e '.[dev]'
./scripts/build-fnos.sh
默认输出为 dist/imagefind-0.5.45-x86_64.fpk。FFmpeg/FFprobe 与 rclone 在运行时优先使用
兼容的系统版本,缺失时按固定版本和 SHA-256 动态下载。0.5.45 不读取或迁移旧 SQLite 数据库;
安装时直接初始化 PostgreSQL schema,升级脚本不会擅自删除用户数据或旧 runtime 目录。
当前仓库中的 manifest、权限和资源声明是
侧载模板;正式发布前必须用目标 fnOS 版本配套的官方 fnpack 校验,并在真实 N100 设备上
验证安装/升级向导、启停、GPU 权限、端口跳转和两种卸载数据行为。
解出安装包内的 app.tgz 后,可以在 x86_64 Linux 构建机上运行制品级冒烟:
./scripts/smoke-fnos-package.sh /path/to/extracted/app /tmp/imagefind-smoke 18765
API
登录后在“设置”创建独立 API Token。请求使用 Authorization: Bearer <token>。
OpenAPI 文档位于 /api/docs,主要入口是:
POST /api/v1/query-imagesPOST /api/v1/searchPOST /api/v1/uploads与/api/v1/uploads/{id}/chunks/{index}POST /api/v1/models/install、POST /api/v1/models/uploadPATCH /api/v1/models/config、POST /api/v1/models/proxy/test、DELETE /api/v1/models/{component}/api/v1/sources、/api/v1/files、/api/v1/trashPOST /api/v1/sources/alist/restoreGET/POST /api/v1/backups、GET /api/v1/backups/{id}/download、POST /api/v1/backups/restore/api/v1/tag-groups、/api/v1/tags、POST /api/v1/videos/tags/bulk/api/v1/tag-suggestions、POST /api/v1/tag-suggestions/analyze、POST /api/v1/tag-suggestions/decidePATCH /api/v1/videos/{video_id}/stateGET/PATCH /api/v1/speech/config、POST /api/v1/speech/reconcileGET /api/v1/videos/{video_id}/transcript、POST /api/v1/videos/{video_id}/transcript/reindex/api/v1/profile、/api/v1/series、POST /api/v1/videos/series/bulkGET /api/v1/storage/usage/api/v1/preferences、/api/v1/activity、GET /api/v1/events/api/v1/jobs、/api/v1/people、/api/v1/actorsGET /api/v1/system/diagnosticsPOST /api/v1/system/resources/rclone/reconcile
隐私与范围
- 视频可位于本机或用户配置的远端;关键帧、人脸特征、文字、向量和密钥只保存在本机。
- WebDAV 凭据通过应用主密钥加密;主密钥文件权限为
0600。 - 首版只支持管理员;fnOS 提供稳定的用户身份 API 后再接入系统多用户 ACL。
- 支持文本字幕、烧录在画面内的文字和带时间轴的 Whisper 语音转写;不包含 PGS/VobSub 图片字幕。