轻课堂项目研究文档
一、项目概述
1.1 基本信息
- 项目名称: 轻课堂 (Lite Class)
- 版本: 1.0.6
- 描述: 专为NAS用户打造的轻量级、多用户私有云学习管理系统
- 开发者: 落地长安
- 默认管理员账号: admin / admin123
- 技术架构: 前后端分离架构
1.2 核心特性
- 多用户管理系统(管理员/普通用户)
- 课程分类与管理
- 视频播放与学习进度追踪
- 笔记与资料管理
- 学习日历与历史记录
- 视频转码服务(支持HLS流式转码)
- 硬件加速(GPU/NVENC/VAAPI/QSV)
- 分片上传支持
- 课程收藏功能
- 深色主题支持
二、技术栈
2.1 前端技术栈
- 框架: React 18.2.0
- 路由: React Router Dom 6.14.2
- 构建工具: Vite 4.3.9
- UI样式: Tailwind CSS 3.3.3
- 视频播放: hls.js 1.5.7
- 图标库: lucide-react 0.263.1
- 开发语言: JavaScript + JSX
2.2 后端技术栈
- 运行环境: Node.js v22
- Web框架: Fastify 4.26.1
- 数据库: SQLite 3 (sqlite3 5.1.7)
- 身份认证: JWT (jsonwebtoken 9.0.2)
- 密码加密: bcryptjs 2.4.3
- 视频转码: fluent-ffmpeg 2.1.3
- 文件上传: @fastify/multipart 7.7.3
- 静态文件: @fastify/static 6.12.0
- 文件系统: fs-extra 11.2.0
- MIME类型: mime-types 2.1.35
2.3 关键依赖
- FFmpeg: 视频转码核心工具(需系统预装)
- fnOS: 飞牛NAS操作系统支持
三、项目结构
3.1 根目录结构
lite.class_1.0.6/
├── app/ # 应用主目录
│ ├── server/ # 后端服务
│ │ ├── index.js # 服务器入口文件 (2264行)
│ │ ├── transcoder.js # 视频转码模块 (905行)
│ │ ├── package.json # 后端依赖配置
│ │ ├── public/ # 静态资源目录
│ │ │ └── uploads/ # 上传文件存储
│ │ └── liteclass.db # SQLite数据库
│ ├── frontend/ # 前端应用
│ │ ├── src/
│ │ │ ├── api/ # API封装
│ │ │ ├── components/ # React组件
│ │ │ ├── hooks/ # 自定义Hook
│ │ │ ├── utils/ # 工具函数
│ │ │ ├── App.jsx # 应用入口
│ │ │ └── main.jsx # 渲染入口
│ │ ├── index.html # HTML模板
│ │ └── package.json # 前端依赖配置
│ ├── ui/ # UI界面资源
│ └── config/ # 应用配置
├── cmd/ # 命令脚本目录
│ ├── main # 主控脚本(启动/停止/状态)
│ ├── install_callback # 安装回调
│ ├── install_init # 安装初始化
│ ├── uninstall_callback # 卸载回调
│ ├── uninstall_init # 卸载初始化
│ ├── upgrade_callback # 升级回调
│ ├── upgrade_init # 升级初始化
│ ├── config_callback # 配置回调
│ └── config_init # 配置初始化
├── wizard/ # 安装向导
│ ├── install # 安装配置(端口/管理员账号)
│ └── uninstall # 卸载配置
├── config/ # 系统配置
│ ├── privilege # 权限配置
│ └── resource # 资源配置
├── manifest # 应用清单文件(元数据)
├── ICON.PNG # 应用图标
└── ICON_256.PNG # 应用大图标
3.2 前端组件结构
components/
├── Login.jsx # 登录页面
├── Layout.jsx # 布局组件(底部导航栏)
├── Home.jsx # 首页(学习日历)
├── Courses.jsx # 课程列表
├── CourseDetail.jsx # 课程详情与播放器 (84KB)
├── CourseChapterManager.jsx # 章节管理
├── HlsPlayer.jsx # HLS播放器组件
├── Profile.jsx # 个人中心 (74KB)
├── ConfirmModal.jsx # 确认对话框
└── PreviewModal.jsx # 文件预览弹窗
四、数据库设计
4.1 数据表结构
4.1.1 users(用户表)
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL, -- 用户名
password_hash TEXT NOT NULL, -- 密码哈希
role TEXT DEFAULT 'user', -- 角色: admin/user
nickname TEXT, -- 昵称
avatar TEXT, -- 头像路径
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
4.1.2 categories(分类表)
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL -- 分类名称
);
-- 默认分类: ID=1, name='未分类'
4.1.3 courses(课程表)
CREATE TABLE courses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL, -- 课程标题
description TEXT, -- 课程描述
cover_image TEXT, -- 封面图片
category_id INTEGER, -- 所属分类
type TEXT DEFAULT 'manual', -- 类型: manual(手动)/uploaded(上传)/mount(挂载)
folder_path TEXT, -- 存储路径
is_shared BOOLEAN DEFAULT 0, -- 是否公开(0=隐藏, 1=公开)
creator_id INTEGER DEFAULT 1, -- 创建者ID
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
4.1.4 course_materials(课程素材表)
CREATE TABLE course_materials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
course_id INTEGER NOT NULL, -- 所属课程
chapter_title TEXT, -- 章节标题(支持树形结构)
title TEXT NOT NULL, -- 素材标题
file_path TEXT NOT NULL, -- 文件路径
media_type TEXT, -- 媒体类型: video/audio/document/attachment
file_size INTEGER, -- 文件大小(字节)
duration INTEGER, -- 时长(秒)
sort_order INTEGER DEFAULT 0, -- 排序序号
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
4.1.5 learning_progress(学习进度表)
CREATE TABLE learning_progress (
user_id INTEGER,
course_id INTEGER,
material_id INTEGER,
played_seconds INTEGER DEFAULT 0, -- 播放时长(秒)
is_finished BOOLEAN DEFAULT 0, -- 是否完成
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, course_id, material_id)
);
4.1.6 learning_notes(学习笔记表)
CREATE TABLE learning_notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
material_id INTEGER,
content TEXT, -- 笔记内容
video_timestamp INTEGER DEFAULT 0, -- 视频时间戳
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
4.1.7 system_settings(系统设置表)
CREATE TABLE system_settings (
key TEXT PRIMARY KEY,
value TEXT
);
-- 默认设置:
-- allow_registration: false
-- allow_course_creation: true
-- enable_transcoding: false
-- max_material_size: 100 (MB)
4.1.8 favorites(收藏表)
CREATE TABLE favorites (
user_id INTEGER,
course_id INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, course_id)
);
4.1.9 user_materials(用户私有资料表)
CREATE TABLE user_materials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
course_id INTEGER NOT NULL,
title TEXT NOT NULL,
file_path TEXT NOT NULL,
file_size INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
4.2 数据库初始化流程
- 创建所有数据表
- 插入默认系统设置
- 插入默认分类(未分类)
- 自动创建管理员账号(如果数据库为空且环境变量提供了凭据)
- 执行数据库迁移(自动添加新字段)
- 初始化转码服务设置
五、后端API设计
5.1 认证相关 API
POST /api/auth/register - 用户注册
权限: 根据系统设置决定
请求体:
{
"username": "string",
"password": "string",
"nickname": "string"
}
响应: { success: true, role: "admin"|"user" }
POST /api/auth/login - 用户登录
请求体:
{
"username": "string",
"password": "string"
}
响应:
{
"token": "jwt_token",
"user": {
"id": 1,
"username": "admin",
"nickname": "管理员",
"role": "admin",
"avatar": "/avatars/xxx.png"
}
}
5.2 系统设置 API
GET /api/settings/public - 获取公开设置(无需认证)
响应:
{
"allow_registration": false,
"allow_course_creation": true,
"max_material_size": 100,
"enable_transcoding": false,
"appName": "轻课堂",
"version": "1.0.6",
"transcode": {
"enabled": false
}
}
GET /api/settings - 获取所有设置(管理员)
POST /api/settings - 更新设置(管理员)
请求体: { key: "string", value: "any" }
5.3 课程管理 API
GET /api/courses - 获取课程列表
查询参数:
q: 搜索关键词filter: 过滤类型 (all|favorites|uploads)
响应: 返回课程列表,包含进度统计和收藏状态
POST /api/courses - 创建课程
请求体:
{
"title": "课程标题",
"description": "课程描述",
"cover_image": "封面路径",
"category_id": 1,
"folder_path": "存储路径(可选)"
}
GET /api/courses/:id - 获取课程详情
响应: 包含课程信息和所有章节(素材)
PUT /api/courses/:id - 更新课程
权限: 课程创建者或管理员
DELETE /api/courses/:id - 删除课程
权限: 课程创建者或管理员
注意: 仅删除课程记录,保留学习记录和笔记
PUT /api/courses/:id/visibility - 切换课程可见性
响应: { is_hidden: boolean, is_shared: boolean }
POST /api/courses/:id/scan - 重新扫描课程目录
适用: 挂载类型课程
5.4 分类管理 API(管理员)
GET /api/categories - 获取分类列表
POST /api/categories - 创建分类
PUT /api/categories/:id - 更新分类
DELETE /api/categories/:id - 删除分类
5.5 文件上传 API
POST /api/upload - 单文件上传
支持: 分片上传和断点续传
限制: 最大5GB
权限: 课程创建者或管理员
GET /api/upload/check - 检查已上传分片
POST /api/upload/chunk - 上传分片
POST /api/upload/merge - 合并分片
POST /api/upload/cover - 上传课程封面
POST /api/upload/avatar - 上传用户头像
POST /api/upload/note-image - 上传笔记图片
5.6 视频流播放 API
GET /api/stream/:materialId - 获取视频流
功能:
- 原生格式直接流式传输(支持Range请求)
- 需要转码格式返回HLS信息
- 缓存MP4直接播放
查询参数:
token: JWT认证令牌quality: 画质选择 (original|1080p|720p|480p)
GET /api/stream/:materialId/hls/playlist.m3u8 - HLS播放列表
GET /api/stream/:materialId/hls/:segment - HLS分片流
GET /api/transcode/status/:materialId - 获取转码状态
GET /api/transcode/qualities - 获取可用画质列表
5.7 学习进度与笔记 API
GET /api/notes/:materialId - 获取笔记列表
POST /api/notes - 创建笔记
PUT /api/notes/:id - 更新笔记
DELETE /api/notes/:id - 删除笔记
POST /api/progress - 保存学习进度
请求体:
{
"course_id": 1,
"material_id": 10,
"played_seconds": 120,
"is_finished": false
}
5.8 历史记录 API
GET /api/history - 获取最近观看记录(最多10条)
GET /api/history/dates - 获取有活动的日期列表
GET /api/history/calendar - 获取月度日历(按月查询)
GET /api/history/by-date - 获取指定日期的记录
DELETE /api/history/by-date - 清除指定日期的记录
DELETE /api/history/item - 删除单条记录
5.9 用户资料 API
GET /api/user/materials/:courseId - 获取用户私有资料
POST /api/user/materials - 上传用户资料
DELETE /api/user/materials/:id - 删除用户资料
GET /api/user/materials/:id/download - 下载用户资料
5.10 历史课程 API
GET /api/user/history-courses - 获取已删除课程(但有笔记/资料)
GET /api/user/history-courses/:courseId/notes - 获取历史课程笔记
DELETE /api/user/history-courses/:courseId - 永久删除历史课程数据
5.11 收藏 API
POST /api/courses/:id/favorite - 切换收藏状态
GET /api/favorites - 获取收藏列表
POST /api/favorites - 添加收藏
DELETE /api/favorites/:courseId - 取消收藏
GET /api/favorites/check/:courseId - 检查收藏状态
5.12 用户管理 API(管理员)
GET /api/admin/users - 获取用户列表
PUT /api/admin/users/:id - 更新用户信息
PUT /api/admin/users/:id/password - 修改用户密码
DELETE /api/admin/users/:id - 删除用户
5.13 课程统计 API(管理员)
GET /api/admin/courses/:id/members - 获取课程成员统计
5.14 素材管理 API
DELETE /api/materials/:id - 删除素材
PUT /api/materials/:id/rename - 重命名素材
PUT /api/courses/:id/materials/sort - 更新排序
DELETE /api/courses/:id/materials/batch - 批量删除素材
5.15 个人中心 API
PUT /api/user/profile - 更新个人资料
请求体: { nickname: "string", password: "string" }
六、视频转码服务
6.1 转码架构
6.1.1 支持的视频格式
原生支持(无需转码):
- MP4 (H.264视频 + AAC音频)
- WebM
- MP3, WAV, AAC
需要转码:
- MKV, AVI, MOV, FLV, WMV, M4V, 3GP, RMVB, RM
6.1.2 转码策略
-
实时HLS转码:
- 首次播放时启动
- 按需生成TS分片
- 60秒无请求自动停止
- 支持多画质选择
-
后台MP4缓存:
- 后台异步生成
- 队列机制管理
- 缓存有效期30天
- 二次播放直接使用缓存
-
智能编码策略:
- 原画质: 尝试流复制(容器转换)
- 非原画质: 重新编码
- 音频始终转AAC(保证兼容性)
6.2 GPU硬件加速
6.2.1 支持的编码器
| 编码器 | 硬件平台 | 加速类型 |
|---|---|---|
| h264_nvenc | NVIDIA | CUDA |
| h264_vaapi | Intel/AMD | VAAPI |
| h264_qsv | Intel | QSV |
| h264_amf | AMD | AMF |
6.2.2 自动检测流程
- 检测系统FFmpeg路径
- 检查硬件设备文件(/dev/dri/*)
- 检查lspci信息
- 检查nvidia-smi(如存在)
- 逐个测试编码器可用性
- 回退到CPU编码(libx264)
6.3 画质预设
| 画质 | 分辨率 | 视频码率 | 音频码率 |
|---|---|---|---|
| 原画 | 原分辨率 | 不限制 | 192kbps |
| 1080p | 1920x1080 | 4000kbps | 192kbps |
| 720p | 1280x720 | 2000kbps | 128kbps |
| 480p | 854x480 | 1000kbps | 128kbps |
6.4 缓存管理
缓存目录结构
transcode_cache/
├── {materialId}_original.mp4 # 原画质缓存
├── {materialId}_1080p.mp4 # 1080p缓存
├── hls_{materialId}_original/ # HLS临时目录
│ ├── playlist.m3u8
│ ├── segment_000.ts
│ ├── segment_001.ts
│ └── ...
缓存清理策略
- HLS进程: 60秒无请求自动停止
- MP4文件: 30天未访问自动删除
- 定时任务: 每天检查一次
七、前端架构与组件
7.1 路由结构
/
├── /login # 登录页(公开)
└── [PrivateRoute] # 需要认证
├── / # 首页(学习日历)
├── /courses # 课程列表
├── /course/:id # 课程详情与播放
├── /course/:id/manage # 章节管理
└── /profile # 个人中心
7.2 核心组件说明
7.2.1 Layout组件
- 提供底部导航栏
- 渲染子路由
- 深色主题支持
7.2.2 Home组件(首页)
-
学习日历:
- 月度视图
- 标记有活动的日期
- 点击查看当日学习记录
-
观看记录:
- 显示当日观看的视频
- 显示播放进度
- 支持删除单条记录
- 支持清除当日记录
7.2.3 Courses组件(课程列表)
-
三个标签页:
- 全部课程: 显示所有公开课程
- 我的上传: 显示用户创建的课程
- 我的收藏: 显示收藏的课程
-
功能:
- 搜索课程
- 切换课程可见性
- 创建新课程
- 进入课程详情
7.2.4 CourseDetail组件(课程详情与播放)
-
视频播放器:
- 自定义控制条
- HLS集成
- 倍速播放(0.5x ~ 3.0x)
- 画面截图
- 画中画模式
- 键盘快捷键
-
播放模式:
- 顺序播放
- 单集循环
- 全部循环
-
进度管理:
- 自动保存播放进度
- 标记已看完
- 继续播放(跳转到上次位置)
-
目录树:
- 支持树形结构(章节)
- 智能排序
- 手动排序
- 文件预览
-
笔记功能:
- 实时笔记
- 时间戳定位
- 图片上传
- 笔记列表
-
用户资料:
- 上传私有资料
- 下载/预览资料
- 资料管理
-
历史课程:
- 查看已删除课程的笔记
- 永久删除历史数据
7.2.5 CourseChapterManager组件(章节管理)
- 功能:
- 文件上传(支持分片)
- 批量删除
- 重命名章节
- 拖拽排序
- 扫描目录(挂载课程)
7.2.6 Profile组件(个人中心)
-
个人信息:
- 昵称修改
- 密码修改
- 头像上传
-
管理员功能:
- 用户管理
- 系统设置
- 转码开关
- 分类管理
-
历史课程管理:
- 查看历史课程
- 删除历史数据
7.2.7 HlsPlayer组件
- 基于hls.js
- 支持多种视频格式
- 错误处理
- 加载状态
7.3 自定义Hooks
useTheme
- 管理深色/浅色主题
- 响应式颜色方案
useSafeBack
- 安全返回导航
- 记录历史路径
八、运行逻辑与流程
8.1 应用启动流程
1. 系统启动
↓
2. 执行 cmd/main start
↓
3. 读取配置
- 端口配置 (port.conf)
- 管理员凭据 (环境变量)
↓
4. 环境变量设置
- DATABASE_URL
- DATA_DIR
- UPLOAD_DIR
- PORT
- ADMIN_USERNAME
- ADMIN_PASSWORD
↓
5. 创建必要目录
- 共享目录 (SHARE_DIR)
- 上传目录 (UPLOAD_DIR)
↓
6. 启动Node.js服务
cd app/server && node index.js
↓
7. 服务初始化
- 连接SQLite数据库
- 初始化数据表
- 执行数据库迁移
- 初始化转码服务
- 创建管理员账号(如果不存在)
↓
8. 监听端口
默认: 8083 (可通过配置修改)
↓
9. 启动完成
用户可通过浏览器访问
8.2 用户登录流程
1. 用户打开应用
↓
2. 前端检查Token
- 有Token → 验证有效性
- 无Token → 跳转登录页
↓
3. 输入用户名密码
↓
4. POST /api/auth/login
↓
5. 后端验证
- 查询用户
- bcrypt.compare对比密码
↓
6. 生成JWT Token
jwt.sign({id, username, role}, secret, {expiresIn: '7d'})
↓
7. 返回Token和用户信息
↓
8. 前端存储
- localStorage.setItem('token', token)
- localStorage.setItem('user', JSON.stringify(user))
↓
9. 跳转到首页
8.3 课程播放流程
1. 用户进入课程详情
↓
2. GET /api/courses/:id
- 获取课程信息
- 获取章节列表
↓
3. 用户点击播放章节
↓
4. 检查视频格式
↓
5. GET /api/stream/:materialId
├─ 原生格式
│ ├─ 支持Range请求
│ ├─ 直接流式传输
│ └─ 前端Video标签播放
│
└─ 需要转码格式
├─ 检查缓存
│ └─ 有缓存 → 直接播放缓存MP4
│
└─ 无缓存
├─ 启动HLS转码 (transcoder.startHlsTranscode)
│ ├─ 检测GPU编码器
│ ├─ 构建FFmpeg参数
│ ├─ 启动FFmpeg进程
│ ├─ 等待m3u8生成
│ └─ 同时启动后台缓存 (transcoder.startBackgroundCache)
│
├─ 返回HLS信息
│ {
│ needsTranscode: true,
│ hlsUrl: '/api/stream/:materialId/hls/playlist.m3u8'
│ }
│
└─ 前端HlsPlayer加载m3u8
├─ 请求playlist.m3u8
├─ 按需请求segment_XXX.ts
└─ 实时播放
↓
6. 播放进度记录
- 每30秒或暂停时保存
- POST /api/progress
- {course_id, material_id, played_seconds, is_finished}
8.4 文件上传流程
1. 用户选择文件
↓
2. 前端检查文件大小
- 超过限制(默认100MB)→ 提示分片上传
↓
3. 小文件(单次上传)
├─ 构建FormData
│ {courseId, file}
├─ POST /api/upload
├─ 保存到课程目录
├─ 插入数据库
└─ 返回成功
↓
4. 大文件(分片上传)
├─ 文件切片(每片10MB)
├─ 逐片上传
│ POST /api/upload/chunk
│ {fileId, chunkIndex, totalChunks, courseId}
│ ↓
│ 保存到临时目录
│ UPLOAD_DIR/temp/fileId/chunk_0
│ UPLOAD_DIR/temp/fileId/chunk_1
│ ...
↓
├─ 所有分片上传完成
│ POST /api/upload/merge
│ {fileId, filename, courseId, totalChunks}
│ ↓
│ 合并分片
│ ├─ 读取所有分片
│ ├─ 按顺序拼接
│ ├─ 写入最终文件
│ └─ 清理临时目录
│
└─ 插入数据库
↓
5. 上传完成
- 刷新章节列表
8.5 课程扫描流程(挂载类型)
1. 管理员创建挂载课程
POST /api/courses
{title, type: 'mount', folder_path: '/shares/course1'}
↓
2. 后台启动扫描
setImmediate(() => scanDirectory(courseId, folderPath))
↓
3. 递归扫描目录
scanDirectoryRecursive(courseId, basePath, relativePath, existingPaths)
├─ 遍历所有文件和子目录
├─ 识别媒体类型(video/audio/document)
├─ 跳过已存在的文件
├─ 插入新文件到数据库
└─ 记录chapter_title(相对路径)
↓
4. 清理已删除的文件
├─ 对比数据库记录
├─ 删除不存在的记录
↓
5. 重新排序
resortCourseMaterials(courseId)
├─ 智能排序算法
├─ 支持中英文数字
├─ 更新sort_order字段
↓
6. 自动生成封面
autoUpdateCourseCover(courseId)
├─ 查找第一个视频
├─ 使用FFmpeg生成缩略图
└─ 保存到DATA_DIR/covers/
↓
7. 扫描完成
- 前端刷新课程列表
8.6 笔记管理流程
1. 用户在播放器中打开笔记面板
↓
2. GET /api/notes/:materialId
- 获取该视频的所有笔记
- 按时间戳排序
↓
3. 添加新笔记
├─ 输入内容
├─ 可选:上传图片
│ POST /api/upload/note-image
│ 保存到 DATA_DIR/note_images/{userId}/
↓
├─ POST /api/notes
│ {
│ materialId: 10,
│ content: "笔记内容",
│ timestamp: 120 // 当前播放时间
│ }
│ ↓
└─ 插入数据库
↓
4. 编辑笔记
├─ PUT /api/notes/:id
└─ 更新内容
↓
5. 删除笔记
├─ DELETE /api/notes/:id
└─ 从数据库删除
↓
6. 笔记关联
- 笔记永久保存
- 即使课程被删除,笔记仍可访问
- 通过"历史课程"查看
8.7 学习进度同步流程
视频播放中
↓
每30秒或以下事件触发
- 播放暂停
- 播放结束
- 切换章节
- 页面关闭
↓
保存进度
POST /api/progress
{
course_id: 1,
material_id: 10,
played_seconds: 245,
is_finished: false
}
↓
后端UPSERT
INSERT INTO learning_progress ...
ON CONFLICT(...) DO UPDATE SET
played_seconds = excluded.played_seconds,
is_finished = excluded.is_finished,
last_updated = datetime('now')
↓
前端更新状态
- 更新进度条
- 更新"已看X分X秒"
- 如果看完,标记为完成
九、部署与配置
9.1 安装配置(向导)
向导配置文件: wizard/install
步骤1: 基本配置
- 应用端口: 默认8083
- 可配置其他可用端口
步骤2: 管理员设置
- 管理员用户名: 默认admin
- 管理员密码: 默认admin123
9.2 环境变量
启动时自动设置的环境变量:
# 数据库路径
export DATABASE_URL="$SHARE_DIR/liteclass.db"
# 持久化数据目录
export DATA_DIR="$TRIM_PKGVAR"
# 上传目录
export UPLOAD_DIR="$SHARE_DIR/user-uploads"
# 服务端口
export PORT="$APP_PORT"
# 监听地址
export HOST="::"
# 管理员账号
export ADMIN_USERNAME="$admin_username"
export ADMIN_PASSWORD="$admin_password"
9.3 目录权限要求
- 共享目录: 需要读写权限(用于存储数据库和文件)
- 上传目录: 需要读写权限
- 数据目录: 需要读写权限(用于封面、头像、转码缓存)
9.4 FFmpeg安装要求
系统需要预装FFmpeg:
fnOS/Synology:
# fnOS
/var/packages/ffmpeg/target/bin/ffmpeg
# Synology
/usr/bin/ffmpeg
通用Linux:
# Debian/Ubuntu
apt-get install ffmpeg
# CentOS/RHEL
yum install ffmpeg
9.5 端口配置
默认端口: 8083
修改端口方式:
- 通过向导安装时指定
- 编辑
TRIM_PKGVAR/port.conf - 重启服务
9.6 数据备份
重要数据位置:
- 数据库:
$SHARE_DIR/liteclass.db - 上传文件:
$SHARE_DIR/user-uploads/ - 持久化数据:
$DATA_DIR/- 封面:
covers/ - 头像:
avatars/ - 笔记图片:
note_images/ - 转码缓存:
transcode_cache/
- 封面:
十、系统安全
10.1 认证机制
- JWT Token: 7天有效期
- 密码加密: bcrypt (10轮哈希)
- Token存储: localStorage
10.2 权限控制
管理员权限:
- 所有课程操作
- 用户管理
- 系统设置
- 分类管理
- 挂载课程(远程目录)
普通用户权限:
- 创建上传型课程
- 管理自己的课程
- 上传/管理自己的资料
- 查看公开课程
10.3 文件安全
- 上传文件类型检查
- 文件大小限制(可配置)
- 认证Token验证(视频流)
- 路径遍历防护
10.4 输入验证
- SQL注入防护(参数化查询)
- XSS防护(React自动转义)
- 文件上传类型验证
- 用户名密码格式验证
十一、性能优化
11.1 前端优化
- 代码分割: React路由懒加载
- 静态资源: CDN加速(如使用)
- 图片优化: 懒加载
- 缓存策略: LocalStorage
11.2 后端优化
- 数据库: SQLite连接池
- 静态文件: Fastify-static
- 文件流: Range请求支持
- 转码: GPU硬件加速
11.3 转码优化
- 缓存机制: HLS + MP4双重缓存
- 队列管理: 后台任务队列
- 智能编码: 流复制优先
- 资源清理: 自动清理过期缓存
11.4 网络优化
- 分片上传: 大文件断点续传
- Range请求: 视频按需加载
- HLS流式: 边转码边播放
十二、故障排查
12.1 常见问题
问题1: 服务无法启动
- 检查Node.js版本(需要v22)
- 检查端口是否被占用
- 查看日志:
$TRIM_PKGVAR/info.log
问题2: 视频无法播放
- 检查FFmpeg是否安装
- 检查转码服务是否开启
- 查看浏览器控制台错误
问题3: 转码失败
- 检查磁盘空间
- 检查FFmpeg版本
- 查看转码日志
问题4: 文件上传失败
- 检查磁盘空间
- 检查文件大小限制
- 检查目录权限
12.2 日志查看
服务日志:
tail -f $TRIM_PKGVAR/info.log
系统日志:
- fnOS: 系统日志 → 应用日志
- Synology: 控制面板 → 日志中心
12.3 数据库维护
备份数据库:
cp $SHARE_DIR/liteclass.db $SHARE_DIR/liteclass.db.backup
恢复数据库:
cp $SHARE_DIR/liteclass.db.backup $SHARE_DIR/liteclass.db
十三、扩展开发
13.1 添加新API
在 app/server/index.js 中添加路由:
fastify.get('/api/new-endpoint', { preValidation: [fastify.authenticate] }, async (request, reply) => {
// 处理逻辑
return { data: 'response' };
});
13.2 添加新组件
在 app/frontend/src/components/ 中创建新组件,然后在 App.jsx 中注册路由。
13.3 数据库迁移
// 在initSchema函数的migrations数组中添加
const migrations = [
// ...现有迁移
"ALTER TABLE courses ADD COLUMN new_field TEXT",
];
13.4 转码功能扩展
在 app/server/transcoder.js 中:
- 添加新的画质预设
- 添加新的编码器支持
- 自定义FFmpeg参数
十四、总结
14.1 项目优势
- 轻量级: 基于Node.js和SQLite,资源占用低
- NAS友好: 专为NAS环境优化
- 功能完善: 涵盖学习管理全流程
- 技术先进: React + Fastify现代化架构
- 易部署: 自动化安装向导
- 性能优化: GPU转码、缓存机制
14.2 适用场景
- 家庭NAS学习平台
- 企业内部培训系统
- 在线教育私有部署
- 视频资源管理
14.3 后续改进方向
- 支持更多视频格式
- 增加学习统计报表
- 支持移动端App
- 增加社区功能
- 支持更多存储方式(对象存储)
- 优化转码性能
附录
A. 键盘快捷键
| 快捷键 | 功能 |
|---|---|
| Space | 播放/暂停 |
| ← | 快退10秒 |
| → | 快进10秒 |
| ↑ | 音量增加 |
| ↓ | 音量减少 |
| M | 静音/取消静音 |
| F | 全屏/退出全屏 |
| P | 画中画 |
B. API响应码
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 206 | 部分内容(视频流) |
| 400 | 请求参数错误 |
| 401 | 未授权/Token过期 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 416 | Range请求无效 |
| 500 | 服务器内部错误 |
C. 支持的视频编码
- H.264 (AVC)
- H.265 (HEVC) - 需转码
- VP8/VP9 - 需转码
- AV1 - 需转码
D. 技术支持
- 交流QQ群: 1072565705
- 作者: 落地长安
- 版本: 1.0.6
文档生成时间: 2026-01-28
项目版本: lite.class 1.0.6