feat: VRSub 单体应用(WOV 单机版)初始提交

为视频生成 VR 双眼字幕的单体实现:FastAPI 后端、调度器与全部节点
(提音/转写/翻译/ASS/抽帧/OCR/LLM 过滤)在单进程内运行。

- 节点协议(wov_sdk 数据模型)与分布式版保持一致,预留回退桥梁
- 工作流即数据:DAG 存于 workflows/*.json,模型/链路改动只改数据
- 调度器:拓扑顺序执行、断点续跑(产物重建)、任务暂停/继续
- 抽帧按帧间隔(select 按帧号精确取帧),VLM OCR 与 LLM 过滤使用
  自适应线程池弹性并发,并打印数据处理速度进度日志
- 100% 行覆盖率(pytest --cov-fail-under=100)
This commit is contained in:
2026-08-16 23:58:25 +08:00
commit 4746e0363f
75 changed files with 10969 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
// WOV OCR 前端 crop 归一化工具(纯函数,供 node 单测与浏览器共用)。
// 负责把用户在视频预览上框选的矩形(显示坐标)与 crop 比例 [x,y,w,h]0~1
// 互转,映射基于视频固有分辨率并处理 object-fit: contain 的留边(letterbox)。
// 计算 <video> 在指定容器内 contain 显示后的实际渲染矩形(容器坐标)。
function videoDisplayRect(videoWidth, videoHeight, boxWidth, boxHeight) {
const scale = Math.min(boxWidth / videoWidth, boxHeight / videoHeight);
const w = videoWidth * scale;
const h = videoHeight * scale;
return { x: (boxWidth - w) / 2, y: (boxHeight - h) / 2, w, h };
}
// 框选矩形(容器坐标)→ crop 比例 [x, y, w, h],钳制到 0~1,保留 3 位小数。
function rectToCrop(rect, videoWidth, videoHeight, boxWidth, boxHeight) {
const display = videoDisplayRect(videoWidth, videoHeight, boxWidth, boxHeight);
const clamp = (v) => Math.min(1, Math.max(0, Math.round(v * 1000) / 1000));
return [
clamp((rect.x - display.x) / display.w),
clamp((rect.y - display.y) / display.h),
clamp(rect.w / display.w),
clamp(rect.h / display.h),
];
}
// crop 比例 → 框选矩形(容器坐标),用于回显。
function cropToRect(crop, videoWidth, videoHeight, boxWidth, boxHeight) {
const display = videoDisplayRect(videoWidth, videoHeight, boxWidth, boxHeight);
return {
x: display.x + crop[0] * display.w,
y: display.y + crop[1] * display.h,
w: crop[2] * display.w,
h: crop[3] * display.h,
};
}
if (typeof module !== "undefined" && module.exports) {
module.exports = { videoDisplayRect, rectToCrop, cropToRect };
}