Wjs Syncing Multicam

Polar Sponsor
爱发电 赞助
.NET 9.0

当用户拥有两个或以上不同设备录制的同一事件视频/音频,并希望将它们同步或合并时使用。

wjs-syncing-multim. 使用音频交叉对调来计算同一事件的每次多源记录的单个时间抵消,并在每个原版旁边发出一台.sync.json侧车. 原件

功能概述

wjs-syncing-multim. 使用音频交叉对调来计算同一事件的每次多源记录的单个时间抵消,并在每个原版旁边发出一台.sync.json侧车. 原件是一项面向实际任务的技能。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。

核心要点

  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。
  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。

使用与执行

实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

wjs-syncing-multicam

针对同一事件的多源录制素材,利用音频互相关(audio cross-correlation)计算每个素材相对于参考时间线的单一时间偏移量,并在各原始文件旁生成对应的 .sync.json 侧车文件(sidecar)。原始文件绝不会被修改、复制或重新编码。 下游工具通过 -itsoffset 参数在消费(consume)阶段动态应用该偏移量。

设计原则 —— 侧车文件优于重编码

该能力早期版本通过裁剪 + 重编码生成 *_synced.MOV 文件,将偏移“烘焙”进文件中。我们已移除该行为:

  • 磁盘空间 —— 3 台摄像机拍摄的 75 分钟 4K 素材约 60+ GB;重编码生成的同步副本将体积翻倍,却未带来任何信息增益。
  • 画质 —— 每次重编码均有损。原始文件是唯一真实来源(source of truth);侧车文件仅是可逆的元数据。
  • 速度 —— 在 Apple Silicon 上,单个 _synced.MOV 文件生成耗时超 10 分钟;而生成侧车文件仅需数秒。
  • 可组合性 —— 任意下游工具(如 autoedit.py、NLE 导入、ffmpeg 单行命令)均可读取侧车文件并自行应用偏移量。无工具专属格式锁定风险。

不适用场景

  • 单机位素材 —— 无可同步对象。若需将单路素材切分为多个片段,请使用 video-segmentation。
  • 已在 NLE 时间线上对齐的素材 —— 勿与剪辑师对抗。
  • 自动剪辑 / 切点 / 画中画(PiP)渲染等同步之后的步骤,请使用 wjs-editing-multicam(该能力消费本能力生成的侧车文件)。

为何采用包络法而非原始波形

原始 PCM 波形互相关在两支麦克风增益/房间响应差异较大时(即副机位几乎总是如此),会产生弱峰值与错误匹配。对数能量包络(log-energy envelope)能有效捕捉对话与音乐的动态特征,这些特征无论频率响应如何,两支麦克风均能共同捕获。切勿跳过包络提取步骤 —— 这正是本能力在低信噪比(low SNR)下保持鲁棒性的根本原因。

算法流程

  1. 从各输入中提取单声道 PCM 音频:采样率 8 kHz,位深 16-bit。
  2. 计算对数能量包络:帧率为 100 Hz(帧移 10 ms,窗长 50 ms)。使用二阶 Butterworth 高通滤波器(截止频率 0.05 Hz),并以 filtfilt 方式零相位滤波 —— 用于消除缓慢漂移与增益偏置。
  3. 对包络进行全段 FFT 互相关 → 得到粗略偏移量(精度约 ±10 ms)。
  4. 在样本级精修偏移量:以粗对齐位置为中心,在参考素材 A 中截取长度为 60 秒的探测片段 B,搜索窗口为 ±2 秒,采用抛物线插值法定位峰值。
  5. 多段探测漂移校验:每约 3 分钟重复步骤 4。对偏移量随时间变化关系 delta(t) = slope·t + intercept 进行线性拟合,可识别真实时钟漂移(典型值为 5–50 ppm)。最终采用中点规范偏移量(slope · midpoint + intercept),使残差围绕零对称分布。
  6. 计算参考时间线中的重叠窗口:overlap = [max(0, delta), min(ref_dur, delta + src_dur)]。
  7. 生成 .sync.json 侧车文件:置于每个非参考输入文件旁。无任何文件被复制、裁剪或重编码。参考输入也生成侧车文件(其中 delta_seconds: 0),以便下游代码统一处理所有输入。

scripts/sync.py 是本能力的具体实现。注意:当前脚本仍会同时输出 _synced.MOV 文件,但该路径已被弃用;侧车文件是唯一权威输出。

侧车文件 Schema(.sync.json)

每个原始输入对应一个侧车文件,与其同目录存放。纯 JSON 格式,文件内不含注释 —— 下方字段说明即为权威定义。

{
  "_about": "Sync metadata for cam_b.MOV. Apply via ffmpeg -itsoffset. See wjs-syncing-multicam SKILL.md for full schema.",
  "schema_version": 1,
  "source": "cam_b.MOV",
  "reference": "cam_a.MOV",
  "delta_seconds": 12.345,
  "drift_slope": 1.8e-5,
  "overlap_in_reference": [12.345, 4512.180],
  "overlap_in_source":    [0.000,   4499.835],
  "verification": {
    "median_residual_ms": 4.2,
    "residual_spread_ms": 11.8,
    "probe_count": 24
  }
}

字段说明

字段 类型 含义
_about 字符串 面向人类的一行简要说明,含回指本 SKILL.md 的链接。始终存在。
schema_version 整数 该 Schema 发生破坏性变更时递增。当前版本:1。
source 字符串 本侧车文件所描述的原始文件名,路径相对于侧车文件所在目录。永不指向重编码后的文件。
reference 字符串 本时间线所对齐的输入文件。参考输入自身的侧车文件亦在此字段中列出自身。
delta_seconds 浮点数 本 source 的 t=0 在参考时间线中的对应时刻(单位:秒)。若为正值,表示本素材起始时间晚于参考素材;传给 ffmpeg 时应写作 -itsoffset 。 可为负值(例如某台摄像机提前开机,本素材早于参考素材开始)。
drift_slope 浮点数 线性时钟漂移斜率(无量纲,典型值 ~10⁻⁵)。0.0 表示未检测到可观测漂移。下游仅在需音画同步 / 长时唇形同步(lip-sync)时,对本素材单独应用 atempo = 1 + drift_slope;对于镜头剪辑(camera-cut editing),可忽略此字段。
overlap_in_reference [start, end](单位:秒) 源素材与参考素材在参考时间线中共同覆盖的时间窗口。可用于裁剪输出,使其严格限定在双方均有效的时间范围内。
overlap_in_source [start, end](单位:秒) 同一时间窗口在源素材本地时间线中的表达。overlap_in_reference[0] - delta_seconds = overlap_in_source[0]。
verification 对象 verify.py 的运行结果,用于驱动“同步是否收敛?”判断门限。median_residual_ms 应为几毫秒;若 residual_spread_ms 大于交付帧率(delivery fps)下的单帧时长,则表明需要但未启用漂移校正。

下游工具如何消费侧车文件

-itsoffset 是 ffmpeg 的 per-input 参数,且必须置于 -i 之前。务必始终从侧车文件中读取 delta_seconds:

# 将 cam_b 对齐至 cam_a 的时间线播放
ffmpeg -itsoffset $(jq -r .delta_seconds cam_b.MOV.sync.json) -i cam_b.MOV 
       -i cam_a.MOV 
       -filter_complex "[0:v][1:v]hstack" out.mp4

# 裁剪至双方共同覆盖的时间窗口(参数来自 cam_b.MOV.sync.json)
ffmpeg -ss  -i cam_b.MOV -t  ...

对于 wjs-editing-multicam,其 autoedit.py 中的 EDL 构建器会自动加载所有 .sync.json 文件;你无需手动拼接这些命令行参数。

部分覆盖片段(Partial-coverage clips)

常见情况:主摄像机覆盖 75 分钟,而 Riverside / 手机 / 领夹麦录音设备仅覆盖中间 30 分钟。scripts/sync_partial.py REF.MOV NEW.mp4 执行以下操作:

  1. 将新输入与参考素材进行互相关。
  2. 定位新片段的 t=0 在参考时间线中的位置(delta_seconds 可能很大,例如 1842.5)。
  3. 仅写入侧车文件 —— 不添加黑场填充、不添加音频填充、不重编码。 overlap_in_reference 明确告知消费者该输入的有效覆盖时段;超出此窗口的部分,回退至主摄像机素材。

--audio-only 标志仅用于向下游提示该源无视频流 —— 当前已无编码环节可跳过。

何时跳过漂移校正

对于镜头剪辑(camera-cut editing,最常见情形),一小时内 ±25 ms 的残差低于人眼可感知阈值 —— 此时可设 drift_slope: 0.0,仅使用中点 delta_seconds。

对于需音画同步 / 长时唇形同步(>30 分钟且 verification.residual_spread_ms > 40)的情形,下游需对源素材应用 atempo = 1 + drift_slope。源文件本身仍不作修改 —— atempo 滤镜仅在消费时运行。

验证(务必执行)

scripts/verify.py REF.MOV SRC.MOV SRC.sync.json 会依据侧车文件中记录的 delta_seconds,对两个原始文件(对源素材应用 -itsoffset)重新提取音频,并再次执行多段探测互相关。结果将写回侧车文件的 verification 字段中。

通过标准:median_residual_ms < 15 且 residual_spread_ms < 交付帧率(delivery fps)下单帧时长。失败则需启用漂移校正后重试。

常见陷阱

  • 原始波形互相关在低信噪比下易产生虚假峰值。 务必先提取包络 —— 此非可调选项,而是整个能力成立的前提。
  • -itsoffset 在音频与视频上的语义不同 —— 为确保同步正确性,它必须是该输入的第一个参数。ffmpeg -i src -itsoffset X 错误;ffmpeg -itsoffset X -i src 正确。
  • 侧车文件中 source / reference 的路径必须相对于侧车文件所在目录,而非下游进程的工作目录。请以 Path(sidecar).parent 为基准解析 source 与 reference。
  • 切勿将 drift_slope “烘焙”进侧车文件的 delta_seconds 字段中。 二者分属独立字段自有其意义 —— 简单消费者可忽略漂移,音画同步消费者可主动应用;混合二者将丢失关键信息。

相关专题

更多
js实现base64编码
js实现base64编码

在JavaScript中实现Base64编码,最直接的方式是使用内置的btoa()函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.10.24

379

9

html中如何调用外部js
html中如何调用外部js

在 html 中调用外部 js 可通过以下步骤:创建 js 文件并编写代码。在 html 代码中添加 <script> 标签,设置 src 属性为 js 文件路径。保存并刷新页面加载外部 js。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.11

1712

6

php和js的区别
php和js的区别

php和js的区别:PHP主要用于服务器端编程,而JavaScript主要用于客户端编程;PHP代码在服务器端执行,而JavaScript代码在客户端浏览器中执行。想了解更多php和js的相关内容,可以阅读本专题下面的文章。

2024.03.22

4828

11

JS的Document介绍
JS的Document介绍

在JavaScript中,document对象是一个非常重要的全局对象,它代表整个HTML文档。想了解更多Document的相关内容,可以阅读本专题下面的文章。

2024.03.14

6047

11

js中each函数的用法
js中each函数的用法

在JavaScript中,并没有一个内建的each函数,但jQuery库提供了一个非常有用的$.each() 函数,用于遍历数组或对象。想了解更多each函数的相关内容,可以阅读本专题下面的文章。

2024.03.13

1629

5

js和vue的关系
js和vue的关系

js和vue的关系:1、js作为web开发基石;2、vue.js作为前端框架的崛起;3、js与vue的互补关系;4、js与vue的实践应用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.11

353

5

js弹幕功能实现方法
js弹幕功能实现方法

PHP中文网为大家带来,js实现弹幕功能的方法:1、创建html文件;2、添加html代码架构;3、在body标签中使用div、input、button标签分给页面设计效果显示框、输入框、弹幕提交按钮;4、添加script标签并写入js代码来实现弹幕效果;5、通过浏览器方式查看设计效果即可。希望对大家有所帮助。

2024.03.04

2992

11

js事件冒泡可以解决哪些问题
js事件冒泡可以解决哪些问题

js事件冒泡可以解决的问题:1、简化事件处理逻辑;2、提高事件处理性能;3、实现自定义组件和交互效果;4、控制事件传播方向;5、解决事件覆盖问题;6、实现全局事件监听;7、方便调试和排查问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2824

4

js的split用法
js的split用法

js的split方法是字符串的一个方法,用于将字符串按照指定的分隔符分割成子字符串,并返回一个新的数组,其语法为“string.split(separator, limit)”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.24

1127

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.8万人学习