返回资讯中心
外部精选
软件工程
#开发者实时流

SeharaCloud 开源:可自托管音乐、视频、文档和图片的媒体云系统

来源标题:Show HN: SeharaCloud – Self-Hosted Multimedia System

开发者发布自托管媒体云 SeharaCloud,支持音乐、视频、文档和图片的自动索引与统一管理。系统由 C++ 守护进程索引文件,元数据存入 PostgreSQL,并通过 ASP.NET Core 提供的 REST API 服务 Web 前端和 Android 应用。

Hacker News 最新znj292026/11/14 · 今天30 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

面向音乐、视频、文档和图片的自托管媒体云。文件会被自动索引(C++ 守护进程),元数据存储在 PostgreSQL 中,并由 REST API(ASP.NET Core)提供给客户端(移动应用、Web 前端等)。

本 README 涵盖后端部分(索引器 + API + 数据库 + 部署)以及 Android 移动应用。前端基于此处描述的 API 契约构建。

架构 技术栈 项目结构 快速开始 数据定制与工作流 环境变量(.env) appsettings.Production.json 索引器——预期行为与内部机制 数据库 API 移动应用——概览 移动应用——功能 移动应用——截图 移动应用——技术栈 移动应用——项目结构 移动应用——快速开始 移动应用——配置 API Base URL 移动应用——构建与运行 架构 flowchart LR A["scp / rsync / yt-dlp"] -->|write| B[("staging/")] B -->|"IN_CLOSE_WRITE / IN_MOVED_TO"| C["Watcher (inotify)"] C --> D["FileProcessor\nSHA-256 · TagLib · ffprobe · Poppler · Magick++"] D -->|INSERT metadata| E[("PostgreSQL")] D -->|move file| F[("media/ — physical")] G["ASP.NET Core API"] -->|SELECT| E G -->|"PhysicalFile + Range"| F H["Frontend / Mobile App"] -->|"REST"| G Loading 典型的文件生命周期:

文件到达 staging/(scp、rsync,或 yt-dlp 直接将 mp3 下载到此处)。 Watcher 捕获 IN_CLOSE_WRITE / IN_MOVED_TO(也就是说,仅在写操作完成之后——参见下文的原子写入说明)。 FileProcessor 计算 SHA-256、检查重复(fn_find_duplicate)、按文件类型提取元数据,并在需要时生成 .webp 缩略图。 文件从 staging/ 移动到最终的物理目录;写入数据库的是逻辑路径(/mnt/cloud/...),而非物理路径。 API 从数据库读取,并从其挂载点提供文件(宿主机上是同一个文件夹,容器内路径不同——见下文)。 前端调用 REST 端点;响应中的 ThumbnailUrl 已经是完整 URL,可直接用于 <img> / <Image>。

技术栈 层级 技术 索引器 C++17、libpqxx、TagLib、Magick++、poppler-cpp、OpenSSL、inotify API ASP.NET Core(.NET 9)、Dapper、Npgsql 数据库 PostgreSQL 16(pgcrypto、pg_trgm) 部署 Docker Compose,3 个服务:seharacloud-db、seharacloud-api、seharacloud-indexer

项目结构 /data/configs/seharacloud/api/ ├── client/SeharaCloud.MobileApp/ # Android 移动应用 ├── database/schema.sql # 完整 DDL、种子数据、函数 ├── docker-compose.yml # 模板(不含真实凭据) ├── docs/ApiContract.md # 完整 API 契约(端点的权威依据) ├── env.example # .env 模板 ├── server/ │ ├── api/SeharaCloud.api/ # ASP.NET Core API │ └── indexer/ # C++ inotify 守护进程

仓库(本文件夹)包含模板文件(docker-compose.yml、env.example),不含真实凭据。带有生产值的实际 .env 和 appsettings.Production.json 文件单独存放在服务器的 /data/docker/seharacloud/,绝不提交到仓库。

前置要求:Docker、Docker Compose、git。

git clone https://github.com/SamerKolasevic29/SeharaCloud.git seharacloud cd seharacloud

1. 环境与配置

cp env.example .env cp appsettings.Production.json.example appsettings.Production.json

用你的实际凭据编辑 .env 和 appsettings.Production.json

2. 构建并启动容器

docker compose up -d --build

3. 初始化数据库(关键步骤)

docker exec -i seharacloud-db psql -U postgres -d seharacloud-db < database/schema.sql

4. 设置默认缩略图

确保宿主机上的媒体文件夹(videos、images、music、documents、thumbnails、staging)已存在。

将仓库中的默认缩略图复制到你的 media/thumbnails/ 文件夹:

cp -r docs/DefaultThumbnails/* /path/to/your/media/thumbnails/

数据定制与工作流 默认情况下,索引器处理的每首新歌都会被归入“Unknown Artist”和“Unknown Genre”。如果你希望媒体得到妥善整理,请在将文件放入 staging 文件夹之前按以下步骤操作。

你可以在 docs/GenreThumbnails 中找到常见流派的预制缩略图。要向数据库添加流派:

INSERT INTO genres (name, thumbnail_id2) VALUES ('Rock', 'your-thumbnail-uuid-here');

列出你的流派以获取其 ID,供后续使用:

SELECT id, name FROM genres;

  1. 设置艺术家与缩略图 为你的艺术家找最多两张图片(例如 Artist.jpg、Artist2.png),将它们放入一个文件夹,并使用以下脚本转换为所需的 .webp 格式:

在你的图片文件夹内运行,将 jpg/jpeg/png/webp 转换为标准 webp

for file in .{jpg,jpeg,png,webp}; do if [ -f "$file" ]; then filename=$(basename "$file") name="${filename%.}" ffmpeg -i "$file" -vf scale=512:512 "${name}Thumbnail.webp" fi done

将生成的 ArtistThumbnail.webp 和 Artist2Thumbnail.webp 移动到你的 media/thumbnails/ 文件夹。

将艺术家插入数据库,并将其关联到之前创建的流派 ID:

INSERT INTO artists (name, genre_id, thumbnail_id2, thumbnail_id3) VALUES ('Smoke Mardeljano', 'genre-uuid-here', 'artist-thumb-uuid', 'artist2-thumb-uuid');

  1. 触发索引器 索引器高度依赖文件名解析。

变量 描述 POSTGRES_USER 数据库用户(API 和索引器共用) POSTGRES_PASSWORD 数据库密码 POSTGRES_DB 数据库名称(seharacloud-db) DB_HOST / DB_PORT Docker 网络内的数据库主机名/端口 ASPNETCORE_ENVIRONMENT Production API_PORT API 在容器内监听的端口 API_BIND_ADDRESS 主机接口(127.0.0.1 = 仅本地,置于反向代理之后) API_BASE_URL 公开的 API URL(例如 https://sehara.cloud.com)——用于 ThumbnailUrl 及类似的绝对链接 INDEXER_PHYSICAL_BASE_PATH 索引器容器看到的路径 INDEXER_LOGICAL_BASE_PATH API 容器看到的路径(/mnt/cloud)——该路径作为 path 写入数据库 HOST_MEDIA_PATH 服务器上文件所在的实际路径 HOST_DB_DATA_PATH 服务器上 PostgreSQL 数据目录的实际路径

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →