audio-video-sync 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright © 2026 EuanTop
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # audio-video-sync
2
+
3
+ [![npm version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://www.npmjs.com/package/audio-video-sync)
4
+ [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ **English** | [中文版](./README.zh-CN.md)
8
+
9
+ ---
10
+
11
+ 🙆‍♀️ Multi-camera recording alignment timeline tool, **a must-have for research!**
12
+
13
+ 📱 Aligns via audio, bypassing the additional processing inconsistencies of video source data on Apple, Android, and Xiaomi devices, as well as the inherent inaccuracies of the recording equipment's system time.
14
+
15
+ ✨ Multi-camera video synchronization using audio cross-correlation. Automatically align multiple video timelines by analyzing audio waveforms with millisecond precision.
16
+
17
+ ![eg_img](<cover.png>)
18
+ ## Features
19
+
20
+ - 🎯 **High Precision** - Millisecond-level sync accuracy (±2ms)
21
+ - ⚡ **High Performance** - FFT-accelerated cross-correlation algorithm
22
+ - 🌐 **Browser Native** - Based on FFmpeg.wasm, no server required
23
+ - 📦 **Zero Config** - Works out of the box with automatic audio extraction
24
+ - 🔧 **Flexible** - Supports custom FFmpeg instances and parameters
25
+ - 📝 **TypeScript** - Full type definitions included
26
+
27
+ ## How it Works
28
+
29
+ Multi-camera recordings may have inaccurate creation_time metadata, but the ambient sound is consistent across all recordings. By performing cross-correlation analysis on audio waveforms, we can precisely calculate the time offset between videos.
30
+
31
+ ```
32
+ Video A audio: ──────█████████████──────────
33
+ Video B audio: ────────────█████████████────
34
+
35
+ offset Δt
36
+ ```
37
+
38
+ <!-- ## Requirements (uncertain)
39
+
40
+ - **Node.js**: >= 16.0.0
41
+ - **Browser**: Must support SharedArrayBuffer (Chrome 92+, Firefox 79+, Safari 15.2+)
42
+ - **HTTPS**: Required for SharedArrayBuffer in production -->
43
+
44
+ ## Installation
45
+
46
+ ```bash
47
+ npm install audio-video-sync @ffmpeg/ffmpeg @ffmpeg/util
48
+ ```
49
+
50
+ ## Development
51
+
52
+ ### Clone and Setup
53
+
54
+ ```bash
55
+ git clone https://github.com/EuanTop/audio-video-sync.git
56
+ cd audio-video-sync
57
+ npm install
58
+ ```
59
+
60
+ ### Build from Source
61
+
62
+ ```bash
63
+ # Build the package
64
+ npm run build
65
+ ```
66
+
67
+ ### Test the Build
68
+
69
+ ```bash
70
+ # Open test.html in browser to test the built package
71
+ # npx serve -p 3333
72
+ open test.html
73
+ ```
74
+
75
+ ### Scripts
76
+
77
+ - `npm run build` - Build the package for distribution
78
+ - `npm run test` - Run tests (placeholder)
79
+ - `npm run prepublishOnly` - Automatically builds before publishing
80
+
81
+ ## Quick Start
82
+
83
+ ### Basic Usage
84
+
85
+ ```javascript
86
+ import { syncVideos } from 'audio-video-sync';
87
+
88
+ const result = await syncVideos([
89
+ { file: video1File, id: 'cam1' },
90
+ { file: video2File, id: 'cam2' },
91
+ { file: video3File, id: 'cam3' },
92
+ { file: video4File, id: 'cam4' }
93
+ ], {
94
+ referenceIndex: 0, // Use first video as reference
95
+ sampleRate: 16000, // Sample rate
96
+ maxDuration: 60 // Only analyze first 60 seconds
97
+ });
98
+
99
+ console.log(result);
100
+ // {
101
+ // referenceId: 'cam1',
102
+ // results: [
103
+ // { id: 'cam1', offsetSeconds: 0, confidence: 1 },
104
+ // { id: 'cam2', offsetSeconds: 0.523, confidence: 0.89 },
105
+ // { id: 'cam3', offsetSeconds: -0.127, confidence: 0.92 },
106
+ // { id: 'cam4', offsetSeconds: 1.234, confidence: 0.85 }
107
+ // ],
108
+ // success: true
109
+ // }
110
+ ```
111
+
112
+ ### Using Existing FFmpeg Instance
113
+
114
+ ```javascript
115
+ import { FFmpeg } from '@ffmpeg/ffmpeg';
116
+ import { AudioVideoSync } from 'audio-video-sync';
117
+
118
+ const ffmpeg = new FFmpeg();
119
+ await ffmpeg.load();
120
+
121
+ const sync = new AudioVideoSync(ffmpeg);
122
+ const result = await sync.syncVideos(videos);
123
+ ```
124
+
125
+ ### Calculate Offset Between Two Videos
126
+
127
+ ```javascript
128
+ import { createSync } from 'audio-video-sync';
129
+
130
+ const sync = createSync();
131
+ const { offsetSeconds, confidence } = await sync.calculateOffset(
132
+ referenceVideoFile,
133
+ targetVideoFile
134
+ );
135
+
136
+ console.log(`Target video offset: ${offsetSeconds} seconds`);
137
+ console.log(`Confidence: ${(confidence * 100).toFixed(1)}%`);
138
+ ```
139
+
140
+ ### With Progress Callback
141
+
142
+ ```javascript
143
+ const result = await syncVideos(videos, {
144
+ onProgress: (stage, progress) => {
145
+ if (stage === 'extracting') {
146
+ console.log(`Extracting audio: ${(progress * 100).toFixed(0)}%`);
147
+ } else if (stage === 'correlating') {
148
+ console.log(`Computing correlation: ${(progress * 100).toFixed(0)}%`);
149
+ }
150
+ }
151
+ });
152
+ ```
153
+
154
+ ## API
155
+
156
+ ### syncVideos(videos, options)
157
+
158
+ Synchronize multiple video files.
159
+
160
+ **Parameters:**
161
+ - `videos`: `VideoInput[]` - Array of video inputs
162
+ - `file`: `File | Blob` - Video file
163
+ - `id`: `string` (optional) - Video identifier
164
+ - `originalStartTime`: `Date` (optional) - Original start time
165
+ - `options`: `SyncOptions` (optional)
166
+ - `referenceIndex`: `number` - Reference video index, default 0
167
+ - `sampleRate`: `number` - Sample rate, default 16000
168
+ - `maxDuration`: `number` - Max analysis duration (seconds), default 60
169
+ - `minConfidence`: `number` - Min confidence threshold, default 0.3
170
+ - `onProgress`: `(stage, progress) => void` - Progress callback
171
+
172
+ **Returns:** `Promise<MultiSyncResult>`
173
+
174
+ ### AudioVideoSync
175
+
176
+ Synchronizer class with FFmpeg instance reuse support.
177
+
178
+ ```javascript
179
+ const sync = new AudioVideoSync(ffmpeg?);
180
+ await sync.load();
181
+ const result = await sync.syncVideos(videos, options);
182
+ const offset = await sync.calculateOffset(refVideo, targetVideo);
183
+ ```
184
+
185
+ ### Low-level API
186
+
187
+ ```javascript
188
+ import {
189
+ extractAudio, // Extract audio from video
190
+ crossCorrelate, // Compute cross-correlation
191
+ findPeakOffset, // Find peak offset
192
+ calculateConfidence // Calculate confidence score
193
+ } from 'audio-video-sync';
194
+ ```
195
+
196
+ ## Types
197
+
198
+ ```typescript
199
+ interface VideoInput {
200
+ file: File | Blob;
201
+ id?: string;
202
+ originalStartTime?: Date;
203
+ }
204
+
205
+ interface SyncResult {
206
+ id: string;
207
+ offsetSeconds: number;
208
+ offsetSamples: number;
209
+ confidence: number;
210
+ correctedStartTime: Date | null;
211
+ }
212
+
213
+ interface MultiSyncResult {
214
+ referenceId: string;
215
+ results: SyncResult[];
216
+ sampleRate: number;
217
+ success: boolean;
218
+ error?: string;
219
+ }
220
+ ```
221
+
222
+ ## Accuracy Comparison
223
+
224
+ | Method | Accuracy |
225
+ |--------|----------|
226
+ | creation_time | ±seconds |
227
+ | File timestamp | ±100ms |
228
+ | Audio cross-correlation | **±2ms** |
229
+
230
+ ## Notes
231
+
232
+ 1. **Audio Quality**: Ensure videos have clear ambient sound; silent videos cannot be synced
233
+ 2. **Sample Rate**: 16000 Hz is sufficient for sync; higher rates increase computation
234
+ 3. **Analysis Duration**: Usually 30-60 seconds is enough; no need to process entire video
235
+ 4. **Memory Usage**: For long videos, limit `maxDuration` to control memory usage
236
+ 5. **Browser Compatibility**: Requires SharedArrayBuffer support
237
+
238
+ ## Tech Stack
239
+
240
+ - FFmpeg.wasm - Video decoding and audio extraction
241
+ - FFT (Fast Fourier Transform) - Frequency domain cross-correlation
242
+ - TypeScript - Type safety
243
+
244
+ ## Contributing
245
+
246
+ Issues and Pull Requests are welcome!
247
+
248
+ ## License
249
+
250
+ [MIT](LICENSE)
@@ -0,0 +1,278 @@
1
+ # audio-video-sync
2
+
3
+ [![npm version](https://img.shields.io/badge/npm-v1.0.0-blue.svg)](https://www.npmjs.com/package/audio-video-sync)
4
+ [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ [English](./README.md) | **中文版**
8
+
9
+ ---
10
+ 🙆‍♀️ 多机位录影对齐时间轴工具,**科研常备!**
11
+ 📱 通过音频对齐,绕开视频源数据在不同系统(苹果、安卓和小米)不一致的额外处理,以及录像设备系统时间本身就不正确的问题。
12
+ 🌟 基于音频互相关的多机位视频同步库。使用 FFT 加速的互相关算法,通过分析音频波形自动对齐多个视频的时间轴,精度可达毫秒级。
13
+ ![eg_img](<cover.png>)
14
+
15
+ ## 特性
16
+
17
+ - 🎯 **高精度** - 毫秒级同步精度(±2ms)
18
+ - ⚡ **高性能** - FFT 加速的互相关算法
19
+ - 🌐 **浏览器原生** - 基于 FFmpeg.wasm,无需服务端
20
+ - 📦 **零配置** - 开箱即用,自动处理音频提取
21
+ - 🔧 **灵活** - 支持自定义 FFmpeg 实例和参数
22
+ - 📝 **TypeScript** - 完整的类型定义
23
+
24
+ ## 原理
25
+
26
+ 多机位录制的视频虽然 creation_time 可能不准确,但录制的环境声音是一致的。通过对音频波形进行互相关分析,可以精确计算出各视频之间的时间偏移。
27
+
28
+ ```
29
+ 视频A音频: ──────█████████████──────────
30
+ 视频B音频: ────────────█████████████────
31
+
32
+ 偏移量 Δt
33
+ ```
34
+
35
+ <!-- ## 环境要求 (不确定)
36
+
37
+ - **Node.js**: >= 16.0.0
38
+ - **浏览器**: 需要支持 SharedArrayBuffer(Chrome 92+、Firefox 79+、Safari 15.2+)
39
+ - **HTTPS**: 生产环境需要 HTTPS 才能使用 SharedArrayBuffer -->
40
+
41
+ ## 安装
42
+
43
+ ```bash
44
+ npm install audio-video-sync @ffmpeg/ffmpeg @ffmpeg/util
45
+ ```
46
+
47
+ ## 开发
48
+
49
+ ### 克隆和设置
50
+
51
+ ```bash
52
+ git clone https://github.com/EuanTop/audio-video-sync.git
53
+ cd audio-video-sync
54
+ npm install
55
+ ```
56
+
57
+ ### 从源码构建
58
+
59
+ ```bash
60
+ # 构建包
61
+ npm run build
62
+
63
+ # 这会生成:
64
+ # - dist/index.js (CommonJS 格式)
65
+ # - dist/index.esm.js (ES Module 格式)
66
+ # - dist/index.d.ts (TypeScript 类型定义)
67
+ ```
68
+
69
+ ### 测试构建结果
70
+
71
+ ```bash
72
+ # 在浏览器中打开 test.html 来测试构建的包
73
+ open test.html
74
+ ```
75
+
76
+ ### 脚本命令
77
+
78
+ - `npm run build` - 构建用于发布的包
79
+ - `npm run test` - 运行测试(占位符)
80
+ - `npm run prepublishOnly` - 发布前自动构建
81
+
82
+ ## 快速开始
83
+
84
+ ### 基本用法
85
+
86
+ ```javascript
87
+ import { syncVideos } from 'audio-video-sync';
88
+
89
+ // 同步多个视频文件
90
+ const result = await syncVideos([
91
+ { file: video1File, id: 'cam1' },
92
+ { file: video2File, id: 'cam2' },
93
+ { file: video3File, id: 'cam3' },
94
+ { file: video4File, id: 'cam4' }
95
+ ], {
96
+ referenceIndex: 0, // 以第一个视频为参考
97
+ sampleRate: 16000, // 采样率
98
+ maxDuration: 60 // 只分析前60秒
99
+ });
100
+
101
+ console.log(result);
102
+ // {
103
+ // referenceId: 'cam1',
104
+ // results: [
105
+ // { id: 'cam1', offsetSeconds: 0, confidence: 1 },
106
+ // { id: 'cam2', offsetSeconds: 0.523, confidence: 0.89 },
107
+ // { id: 'cam3', offsetSeconds: -0.127, confidence: 0.92 },
108
+ // { id: 'cam4', offsetSeconds: 1.234, confidence: 0.85 }
109
+ // ],
110
+ // success: true
111
+ // }
112
+ ```
113
+
114
+ ### 使用已有的 FFmpeg 实例
115
+
116
+ ```javascript
117
+ import { FFmpeg } from '@ffmpeg/ffmpeg';
118
+ import { AudioVideoSync } from 'audio-video-sync';
119
+
120
+ // 如果你的项目已经有 FFmpeg 实例
121
+ const ffmpeg = new FFmpeg();
122
+ await ffmpeg.load();
123
+
124
+ const sync = new AudioVideoSync(ffmpeg);
125
+ const result = await sync.syncVideos(videos);
126
+ ```
127
+
128
+ ### 计算两个视频的偏移
129
+
130
+ ```javascript
131
+ import { createSync } from 'audio-video-sync';
132
+
133
+ const sync = createSync();
134
+ const { offsetSeconds, confidence } = await sync.calculateOffset(
135
+ referenceVideoFile,
136
+ targetVideoFile
137
+ );
138
+
139
+ console.log(`目标视频相对参考视频偏移: ${offsetSeconds} 秒`);
140
+ console.log(`置信度: ${(confidence * 100).toFixed(1)}%`);
141
+ ```
142
+
143
+ ### 带进度回调
144
+
145
+ ```javascript
146
+ const result = await syncVideos(videos, {
147
+ onProgress: (stage, progress) => {
148
+ if (stage === 'extracting') {
149
+ console.log(`提取音频: ${(progress * 100).toFixed(0)}%`);
150
+ } else if (stage === 'correlating') {
151
+ console.log(`计算相关: ${(progress * 100).toFixed(0)}%`);
152
+ }
153
+ }
154
+ });
155
+ ```
156
+
157
+ ### 与 RFID 数据对齐
158
+
159
+ ```javascript
160
+ import { syncVideos } from 'audio-video-sync';
161
+
162
+ // 假设 cam1 的时间与 RFID 数据是对齐的
163
+ const videos = [
164
+ {
165
+ file: cam1File,
166
+ id: 'cam1',
167
+ originalStartTime: new Date('2024-01-11T10:00:00') // RFID 对齐的时间
168
+ },
169
+ { file: cam2File, id: 'cam2' },
170
+ { file: cam3File, id: 'cam3' },
171
+ { file: cam4File, id: 'cam4' }
172
+ ];
173
+
174
+ const result = await syncVideos(videos, { referenceIndex: 0 });
175
+
176
+ // 所有视频都会得到校正后的开始时间
177
+ result.results.forEach(r => {
178
+ console.log(`${r.id}: 校正后开始时间 = ${r.correctedStartTime}`);
179
+ });
180
+ ```
181
+
182
+ ## API
183
+
184
+ ### syncVideos(videos, options)
185
+
186
+ 同步多个视频文件。
187
+
188
+ **参数:**
189
+ - `videos`: `VideoInput[]` - 视频输入数组
190
+ - `file`: `File | Blob` - 视频文件
191
+ - `id`: `string` (可选) - 视频标识
192
+ - `originalStartTime`: `Date` (可选) - 原始开始时间
193
+ - `options`: `SyncOptions` (可选)
194
+ - `referenceIndex`: `number` - 参考视频索引,默认 0
195
+ - `sampleRate`: `number` - 采样率,默认 16000
196
+ - `maxDuration`: `number` - 最大分析时长(秒),默认 60
197
+ - `minConfidence`: `number` - 最小置信度阈值,默认 0.3
198
+ - `onProgress`: `(stage, progress) => void` - 进度回调
199
+
200
+ **返回:** `Promise<MultiSyncResult>`
201
+
202
+ ### AudioVideoSync
203
+
204
+ 同步器类,支持复用 FFmpeg 实例。
205
+
206
+ ```javascript
207
+ const sync = new AudioVideoSync(ffmpeg?);
208
+ await sync.load();
209
+ const result = await sync.syncVideos(videos, options);
210
+ const offset = await sync.calculateOffset(refVideo, targetVideo);
211
+ ```
212
+
213
+ ### 底层 API
214
+
215
+ ```javascript
216
+ import {
217
+ extractAudio, // 从视频提取音频
218
+ crossCorrelate, // 计算互相关
219
+ findPeakOffset, // 找到峰值偏移
220
+ calculateConfidence // 计算置信度
221
+ } from 'audio-video-sync';
222
+ ```
223
+
224
+ ## 类型定义
225
+
226
+ ```typescript
227
+ interface VideoInput {
228
+ file: File | Blob;
229
+ id?: string;
230
+ originalStartTime?: Date;
231
+ }
232
+
233
+ interface SyncResult {
234
+ id: string;
235
+ offsetSeconds: number;
236
+ offsetSamples: number;
237
+ confidence: number;
238
+ correctedStartTime: Date | null;
239
+ }
240
+
241
+ interface MultiSyncResult {
242
+ referenceId: string;
243
+ results: SyncResult[];
244
+ sampleRate: number;
245
+ success: boolean;
246
+ error?: string;
247
+ }
248
+ ```
249
+
250
+ ## 精度对比
251
+
252
+ | 方法 | 精度 |
253
+ |------|------|
254
+ | creation_time | ±秒级 |
255
+ | 文件时间戳 | ±百毫秒 |
256
+ | 音频互相关 | **±2ms** |
257
+
258
+ ## 注意事项
259
+
260
+ 1. **音频质量**: 确保视频有清晰的环境音,纯静音视频无法同步
261
+ 2. **采样率**: 16000 Hz 足够用于同步,更高采样率会增加计算量
262
+ 3. **分析时长**: 通常分析前 30-60 秒就足够,不需要处理整个视频
263
+ 4. **内存占用**: 长视频建议限制 `maxDuration` 以控制内存使用
264
+ 5. **浏览器兼容**: 需要支持 SharedArrayBuffer 的浏览器环境
265
+
266
+ ## 技术栈
267
+
268
+ - FFmpeg.wasm - 视频解码和音频提取
269
+ - FFT (Fast Fourier Transform) - 频域互相关计算
270
+ - TypeScript - 类型安全
271
+
272
+ ## 贡献
273
+
274
+ 欢迎提交 Issue 和 Pull Request!
275
+
276
+ ## 许可证
277
+
278
+ [MIT](LICENSE)
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 音频提取模块
3
+ * 使用 FFmpeg.wasm 从视频文件中提取音频 PCM 数据
4
+ */
5
+ import { FFmpeg } from '@ffmpeg/ffmpeg';
6
+ export interface AudioData {
7
+ samples: Float32Array;
8
+ sampleRate: number;
9
+ duration: number;
10
+ channels: number;
11
+ }
12
+ export interface ExtractOptions {
13
+ /** 目标采样率,默认 16000 Hz(足够用于同步,且计算快) */
14
+ sampleRate?: number;
15
+ /** 是否转为单声道,默认 true */
16
+ mono?: boolean;
17
+ /** 只提取前 N 秒用于同步(节省内存和计算),默认 60 秒 */
18
+ maxDuration?: number;
19
+ }
20
+ /**
21
+ * 从视频文件提取音频 PCM 数据
22
+ *
23
+ * @param ffmpeg 已加载的 FFmpeg 实例
24
+ * @param videoFile 视频文件(File 或 Blob)
25
+ * @param options 提取选项
26
+ * @returns 音频 PCM 数据
27
+ */
28
+ export declare function extractAudio(ffmpeg: FFmpeg, videoFile: File | Blob, options?: ExtractOptions): Promise<AudioData>;
29
+ /**
30
+ * 从 AudioBuffer 获取 PCM 数据(用于 Web Audio API)
31
+ */
32
+ export declare function audioBufferToFloat32(audioBuffer: AudioBuffer): Float32Array;
33
+ /**
34
+ * 对音频数据进行降采样
35
+ */
36
+ export declare function downsample(samples: Float32Array, fromRate: number, toRate: number): Float32Array;
37
+ /**
38
+ * 对音频应用简单的预处理(去直流偏移、归一化)
39
+ */
40
+ export declare function preprocessAudio(samples: Float32Array): Float32Array;
package/dist/fft.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * FFT (Fast Fourier Transform) 实现
3
+ * 用于音频信号的频域分析和互相关计算
4
+ */
5
+ export type Complex = [number, number];
6
+ /**
7
+ * 将数组填充到 2 的幂次长度
8
+ */
9
+ export declare function padToPowerOfTwo(arr: Float32Array, targetLength: number): Float32Array;
10
+ /**
11
+ * 计算下一个 2 的幂次
12
+ */
13
+ export declare function nextPowerOfTwo(n: number): number;
14
+ /**
15
+ * Cooley-Tukey FFT 算法
16
+ */
17
+ export declare function fft(input: Float32Array): Complex[];
18
+ /**
19
+ * 逆 FFT
20
+ */
21
+ export declare function ifft(input: Complex[]): Complex[];
22
+ /**
23
+ * 复数输入的 FFT
24
+ */
25
+ export declare function fftComplex(input: Complex[]): Complex[];
26
+ /**
27
+ * 计算两个信号的互相关
28
+ * 使用 FFT 加速: corr(a,b) = IFFT(FFT(a) * conj(FFT(b)))
29
+ *
30
+ * @param signalA 参考信号
31
+ * @param signalB 待对齐信号
32
+ * @returns 互相关结果数组
33
+ */
34
+ export declare function crossCorrelate(signalA: Float32Array, signalB: Float32Array): Float32Array;
35
+ /**
36
+ * 从互相关结果中找到最大峰值位置
37
+ *
38
+ * @param correlation 互相关结果
39
+ * @param signalBLength 信号 B 的原始长度
40
+ * @returns 偏移量(正值表示 B 相对于 A 延迟,负值表示 B 领先)
41
+ */
42
+ export declare function findPeakOffset(correlation: Float32Array, signalBLength: number): number;
43
+ /**
44
+ * 计算互相关的置信度(归一化相关系数)
45
+ */
46
+ export declare function calculateConfidence(signalA: Float32Array, signalB: Float32Array, correlation: Float32Array, peakIndex: number): number;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * audio-video-sync
3
+ *
4
+ * 基于音频互相关的多机位视频同步库
5
+ * Multi-camera video synchronization using audio cross-correlation
6
+ */
7
+ export { AudioVideoSync, createSync, syncVideos, type VideoInput, type SyncResult, type MultiSyncResult, type SyncOptions } from './sync';
8
+ export { extractAudio, preprocessAudio, downsample, audioBufferToFloat32, type AudioData, type ExtractOptions } from './audio';
9
+ export { fft, ifft, crossCorrelate, findPeakOffset, calculateConfidence, nextPowerOfTwo, padToPowerOfTwo, type Complex } from './fft';