hanphone-blog

admin-file 📂

Node.jsExpressMulterSwaggerJWT

Node.js 实现的轻量级文件管理接口服务,提供完整的文件和目录管理功能,支持 JWT 认证、Swagger API 文档和完善的日志系统。

✨ 功能特性

🚀 快速开始

环境要求

作为 Monorepo 的一部分

本项目已纳入根目录的 pnpm workspace,推荐在根目录统一管理:

# 根目录安装所有依赖
pnpm install

# 启动文件服务(在根目录执行)
pnpm --filter admin-file start

独立安装步骤

cd admin-file

# 安装依赖
pnpm install

# 启动服务
pnpm start

环境配置

创建 .env 文件:

PORT=4000
JWT_SECRET=your-secret-key

访问 API 文档

启动服务后,访问 Swagger 文档:

http://localhost:4000/api-docs

📡 API 接口

公共接口(无需认证)

认证接口(需要 JWT)

静态文件访问

媒体派生资源(视频 HLS / 图片缩略图)

接口 说明
GET /media/meta?path=blog/essay/foo.mp4 视频状态:ready / pending / processing / failed / none,以及 HLS、海报、原片、下载地址
GET /media/poster.jpg?path=... 视频封面 JPEG(未生成时 404)
GET /media/thumb?path=...&w=320\|800\|1600 图片缩略图,302 到带版本号的 WebP;按需生成,失败/原图较小回退原图
POST /media/transcode 手动触发视频转码(需要认证,body: { "path": "...", "force": false })

视频原片永远保留在 uploads 原路径,HLS 只是派生资源:

uploads/blog/essay/foo.mp4                        ← 原片(管理端可下载)
uploads/.video/blog/essay/foo-<版本hash>/         ← 派生目录
  master.m3u8
  v0/playlist.m3u8 + seg_00000.ts ...             ← 720p
  v1/playlist.m3u8 + seg_00000.ts ...             ← 1080p(源片足够大时)
  poster.jpg
  meta.json
# 历史视频回填(原片保留,只补 HLS/海报)
cd ~/server_file
node scripts/transcode-videos.js --env /home/hanphone/server_file/.env --dry-run
node scripts/transcode-videos.js --env /home/hanphone/server_file/.env

缓存与 nginx

生产建议让 nginx 直接读 uploads/ 与 uploads/.video/(sendfile),只把 miss 和 API 回源到 Node; 示例见 nginx/hanphone.top.conf.example。

Cloudflare 默认只按扩展名缓存,.m3u8 / .ts 不在默认列表里。必须给 /hls/* 加一条 Cache Rule (Cache Eligibility: Eligible,Edge TTL 1 年),否则每个 HLS 分片都会回源到 3Mbps 的小机器。 具体步骤见 docs/media-delivery.md。

更多接口详情,请查看 Swagger 文档。

📁 项目结构

admin-file/
├── uploads/                 # 上传文件存储目录
│   ├── temp/               # 临时上传目录
│   ├── .video/             # 视频 HLS/海报派生目录(由转码任务生成)
│   └── blog/avatars/       # 头像存储目录
├── lib/
│   ├── thumbnail.js        # 图片缩略图(sharp)
│   ├── video.js            # 视频 HLS 转码队列 / ffmpeg / meta
│   └── paths.js            # 路径安全与 URL 编码
├── nginx/                  # nginx 示例配置(静态直出 + HLS CORS)
├── scripts/                # 缩略图/视频回填脚本
├── logs/                   # 日志文件目录
├── server.js               # 主服务器文件
├── token.js                # JWT 认证处理
├── logger.js               # 日志系统
├── package.json            # 项目配置
└── .env                    # 环境变量配置

环境变量(视频)

完整列表见 .env.example。关键项:

变量 默认 说明
VIDEO_TRANSCODE_ENABLED true 关闭后原片仍可上传/播放/下载,只是不生成 HLS
VIDEO_HLS_MAX_HEIGHT 1080 最高档位(短边);720 可显著省磁盘/CPU
VIDEO_HLS_SEGMENT_SECONDS 4 HLS 分片长度
VIDEO_TRANSCODE_CONCURRENCY 1 同时转码任务数
VIDEO_FFMPEG_THREADS 2 ffmpeg 线程数
VIDEO_TRANSCODE_NICE 10 ffmpeg 的 nice 优先级
VIDEO_TRANSCODE_TIMEOUT_MS 21600000 单任务超时(6 小时)
PUBLIC_FILE_BASE_URL https://hanphone.top 返回给前端的绝对文件域名

原片下载