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:
@@ -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 };
|
||||
}
|
||||
Reference in New Issue
Block a user