feat(web): 端口分离 + VMD 动作支持;契约升至 0.2.0
需求 1:管理端端口与软件 API 端口分离 - 软件 API 端口 PORT(默认 3000)只提供 /api、/health、/static、/contracts, 不提供管理页面(未命中路径 404);管理端端口 ADMIN_PORT(默认 3001) 提供管理页面与全部接口;ADMIN_HOST 可单独限制管理端来源 - main.ts 同进程监听两个端口,用 req.socket.localPort 区分端口行为; ADMIN_PORT=PORT 为单端口兼容模式(只创建一个 server,无 EADDRINUSE) - 端口非法在生产环境中止启动;ADMIN_PORT=PORT 只 warn - 启动日志分别打印两个端口的访问地址 需求 2:动作数据支持 VMD(MikuMikuDance) - vmd-parser.ts:二进制解析(30 字节头 + Shift-JIS 模型名 + 111 字节/条骨骼 关键帧 + morph 段)、MMD 贝塞尔插值、GBK 模型名回退、固定 30fps - mmd-skeleton.ts:标准 MMD 骨架;静止比例从参考 PMX 骨骼段实测得到 (足首 1.43 / 膝 6.57 / 髋 11.50 / 首 16.21 / 頭 17.16,腿长 10.09) - mmd-pose.ts:FK + 两骨骼解析腿部 IK(膝盖朝正面,不可达收敛为伸直) + 左手系→右手系 Z 镜像(由真实数据对照实验确定:94.1% vs 5.9%) - retarget.ts:抽出 worldFramesToKeypointFrames(),BVH 与 VMD 共用重定向 - MotionFormat 增 vmd、扩展名映射增 .vmd;管理端上传支持 .vmd - scripts/inspect-vmd.mjs:上传前自查工具 契约:rest-api / data-models / model-formats → 0.2.0(另两库已同步逐字节一致) 验证:85 项单测通过(VMD 31 项);契约与 29 条路由一致;typecheck/build 通过; 真实样本经 HTTP 端到端:霜雪千年 2901 帧(IK 腿)、恋爱循环 4604 帧(FK 腿) 均 preprocessState=done、0 NaN、0 越界(测试数据已从数据库清理)。
This commit is contained in:
+57
-13
@@ -18,13 +18,19 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
只在 deploy/proxy/ 下提供 IIS 与 nginx 的配置说明文档。
|
||||
|
||||
部署形态
|
||||
Node 业务服务由系统服务托管,同时提供:
|
||||
/ 管理端页面(本服务自带,含 SPA 深链接回退)
|
||||
Node 业务服务由系统服务托管,同时监听**两个端口**,职责分开:
|
||||
|
||||
软件 API 端口(默认 3000,给 Windows/Godot 客户端与 Android App)
|
||||
/api/ REST API
|
||||
/health 健康检查
|
||||
/static/ 上传文件
|
||||
/contracts/ 契约快照
|
||||
因为静态页面也由本服务提供,反向代理**只需一条全匹配转发规则**。
|
||||
该端口**不提供管理页面**,/ 与 /songs 等一律返回 404(有意设计)
|
||||
|
||||
管理端端口(默认 3001,给浏览器)
|
||||
管理页面(本服务自带,含 SPA 深链接回退)+ 上面全部接口
|
||||
|
||||
反向代理按用途分别转发两个端口,每个端口各一条全匹配转发规则即可。
|
||||
|
||||
前置要求
|
||||
- Linux 服务器,有 root 权限(不需要 sudo,直接以 root 执行即可)
|
||||
@@ -56,18 +62,23 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
注册并启动系统服务(systemd / OpenRC / SysVinit / 后台进程)→ 等待健康检查
|
||||
|
||||
部署完成后(直接访问后端端口,<host> 为服务器 IP)
|
||||
管理端首页: http://<host>:3000/
|
||||
API 前缀: http://<host>:3000/api
|
||||
客户端接口: http://<host>:3000/api
|
||||
健康检查: http://<host>:3000/health
|
||||
契约快照: http://<host>:3000/contracts/
|
||||
管理端首页: http://<host>:3001/
|
||||
(软件 API 端口上没有管理页面:http://<host>:3000/ 返回 404,属正常)
|
||||
|
||||
对外访问
|
||||
由反向代理把请求转发到 http://<后端地址>:3000 即可。
|
||||
配置样例与说明:
|
||||
由反向代理**按用途分别转发两个端口**:
|
||||
浏览器管理界面 → http://<后端地址>:3001
|
||||
Windows/Godot 客户端与 Android App → http://<后端地址>:3000
|
||||
配置样例与说明(含两个端口的转发写法):
|
||||
deploy/proxy/nginx.conf.example nginx 站点配置
|
||||
deploy/proxy/web.config.example IIS(ARR + URL Rewrite)配置
|
||||
deploy/proxy/README.md 完整说明、自检清单与常见故障
|
||||
|
||||
直连后端时,防火墙需同时放行两个端口(默认 3000 与 3001)。
|
||||
|
||||
外部访问不了?安装脚本结尾会直接给出结论(监听地址、对外可达性、
|
||||
防火墙提示);也可以在服务器上跑一次自检脚本(只读,不改配置):
|
||||
bash deploy/check-access.sh # 或 bash deploy/check-access.sh /opt/opendance
|
||||
@@ -78,6 +89,8 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
APP_DIR=/opt/opendance 程序目录
|
||||
SERVICE_USER=opendance 运行服务的系统用户
|
||||
STORAGE_DIR=/var/lib/opendance/storage 上传文件目录
|
||||
PORT=3000 软件 API 端口
|
||||
ADMIN_PORT=3001 管理端端口(默认 PORT + 1)
|
||||
|
||||
例:APP_DIR=/srv/opendance bash deploy/install.sh
|
||||
|
||||
@@ -118,7 +131,7 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
cp .env.example .env # 填写 DB_*
|
||||
npm install
|
||||
npm run migration:run # 首次需要
|
||||
npm run start:dev # http://localhost:3000
|
||||
npm run start:dev # API http://localhost:3000;管理端 http://localhost:3001
|
||||
|
||||
管理前端
|
||||
cd web-server/admin
|
||||
@@ -132,7 +145,7 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
cd web-server
|
||||
npm run contracts:check # 契约版本一致性
|
||||
npm run typecheck # TypeScript 严格检查
|
||||
npm run test # 31 项单元测试
|
||||
npm run test # 85 项单元测试(含 31 项 VMD)
|
||||
npm run build # 生产构建
|
||||
npm run start:prod & # 启动
|
||||
npm run test:smoke # 57 项端到端冒烟(需要数据库可连通)
|
||||
@@ -151,9 +164,18 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
所有表结构变更通过 TypeORM migration 执行。
|
||||
|
||||
DB_LOGGING 是否打印 SQL(默认 false)
|
||||
PORT API 监听端口(默认 3000)
|
||||
HOST 监听地址。反代与后端同机用 127.0.0.1(推荐);
|
||||
反代在别的机器用 0.0.0.0,并用防火墙限制来源
|
||||
PORT 软件 API 监听端口(默认 3000)。给 Windows/Godot 客户端
|
||||
与 Android App 调用,只提供 /api、/health、/static、
|
||||
/contracts,**不提供管理页面**
|
||||
ADMIN_PORT 管理端端口(默认 PORT + 1,即 3001)。浏览器访问管理界面
|
||||
(管理页面 + 上面全部接口);设为与 PORT 相同即为
|
||||
单端口兼容模式,日志会提示「未分端口」
|
||||
HOST 监听地址(软件 API 端口)。反代与后端同机用 127.0.0.1
|
||||
(推荐);反代在别的机器用 0.0.0.0,并用防火墙限制来源
|
||||
ADMIN_HOST 管理端监听地址(可选,默认跟随 HOST)。需要接口对外、
|
||||
管理端只对本机时设为 127.0.0.1
|
||||
端口配置非法(非 1..65535 整数)时,生产环境启动会直接中止;
|
||||
ADMIN_PORT 设为与 PORT 相同只打印提示,不中止。
|
||||
ADMIN_DIR 管理端静态站点目录(默认 ../admin,即 /opt/opendance/admin)
|
||||
STORAGE_DIR 上传文件存储目录(原生部署默认 /var/lib/opendance/storage)
|
||||
UPLOAD_MAX_BYTES 单文件上限,默认 536870912(512 MiB)。
|
||||
@@ -177,7 +199,7 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
POST /api/songs/:id/audio 上传音频
|
||||
GET /api/motions 动作列表
|
||||
POST /api/motions 上传动作 + 来源信息
|
||||
POST /api/motions/:id/preprocess BVH/FBX → MediaPipe33 关键点
|
||||
POST /api/motions/:id/preprocess BVH/VMD/FBX → MediaPipe33 关键点
|
||||
GET /api/motions/:id/keypoints 下载关键点序列(NDJSON)
|
||||
GET /api/models 模型列表
|
||||
POST /api/models 上传模型 + 来源信息(VRM 优先)
|
||||
@@ -193,6 +215,28 @@ OpenDance Studio —— Web 管理服务端 v0.1.0 使用说明
|
||||
上传文件通过 /static/<kind>/<yyyy>/<mm>/<sha256>.ext 访问,
|
||||
相同内容只落盘一次(sha256 去重)。
|
||||
|
||||
支持的动作格式(POST /api/motions 上传 → POST /api/motions/:id/preprocess 预处理)
|
||||
BVH .bvh 内置纯 TS 解析器,保留源帧率
|
||||
VMD .vmd 内置解析(MikuMikuDance),固定 30fps;
|
||||
腿部按「足IK是否带位移」自动选 IK 或 FK
|
||||
FBX .fbx 需可选的 Assimp 先转 BVH
|
||||
glTF / GLB .gltf / .glb 同上
|
||||
关键点 JSON .json 已是 MediaPipe33 结构,只做校验与规范化
|
||||
|
||||
VMD 动作上传前后自查
|
||||
服务端对 .vmd 是内置解析,不依赖 Assimp。上传前可先在 web-server 目录下
|
||||
跑诊断工具(只读:不写数据库、不访问网络),确认骨骼名能识别、腿走 IK
|
||||
还是 FK、关键点序列无异常:
|
||||
|
||||
cd web-server
|
||||
npm run build
|
||||
node scripts/inspect-vmd.mjs 动作.vmd
|
||||
node scripts/inspect-vmd.mjs 动作.vmd --frames 300 # 只采样前 300 帧
|
||||
node scripts/inspect-vmd.mjs 动作.vmd --json out.json # 导出关键点序列
|
||||
|
||||
它会打印头部 / 模型名 / 帧数 / 轨道数、未识别骨骼、走 IK 还是 FK、关键点
|
||||
序列异常统计与膝肘角分布。上传后再调用 /preprocess 走正式通路。
|
||||
|
||||
----------------------------------------------------------------
|
||||
六、目录结构
|
||||
----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user