music-segment-detector 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 +21 -0
- package/README.md +139 -0
- package/dist/audioAnalyzer.d.ts +80 -0
- package/dist/audioAnalyzer.d.ts.map +1 -0
- package/dist/audioAnalyzer.js +217 -0
- package/dist/audioAnalyzer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/segmentDetector.d.ts +19 -0
- package/dist/segmentDetector.d.ts.map +1 -0
- package/dist/segmentDetector.js +190 -0
- package/dist/segmentDetector.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Music Segment Detector
|
|
2
|
+
|
|
3
|
+
Audio music segment detection library - Automatically detect music segments from WAV audio files.
|
|
4
|
+
|
|
5
|
+
English | [中文](./README_ZH.md)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Multi-feature analysis (RMS, energy, MFCC, spectral centroid, etc.)
|
|
10
|
+
- Automatic detection of music segment start and end times
|
|
11
|
+
- Customizable detection parameters
|
|
12
|
+
- No external dependencies (no ffmpeg required)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install music-segment-detector
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { analyzeAudio, detectMusicSegments } from "music-segment-detector";
|
|
24
|
+
|
|
25
|
+
// 1. Analyze WAV audio file (with progress callback)
|
|
26
|
+
const features = await analyzeAudio("audio.wav", 2048, 512, (progress) => {
|
|
27
|
+
console.log(`Analysis progress: ${(progress * 100).toFixed(1)}%`);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// 2. Detect music segments
|
|
31
|
+
const segments = detectMusicSegments(features, {
|
|
32
|
+
energyPercentile: 50, // Energy percentile threshold (0-100)
|
|
33
|
+
minSegmentDuration: 25, // Minimum segment duration in seconds
|
|
34
|
+
maxGapDuration: 15, // Maximum gap duration in seconds
|
|
35
|
+
smoothWindowSize: 4, // Smoothing window size in seconds
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// 3. Use detected segments
|
|
39
|
+
segments.forEach((segment) => {
|
|
40
|
+
console.log(`Segment: ${segment.startTime}s - ${segment.endTime}s`);
|
|
41
|
+
console.log(`Duration: ${segment.duration}s`);
|
|
42
|
+
console.log(`Confidence: ${segment.confidence}`);
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
### `analyzeAudio(audioPath, windowSize?, hopSize?, onProgress?)`
|
|
49
|
+
|
|
50
|
+
Analyze a WAV audio file and extract features.
|
|
51
|
+
|
|
52
|
+
- `audioPath`: Path to WAV file
|
|
53
|
+
- `windowSize`: Analysis window size (default: 2048)
|
|
54
|
+
- `hopSize`: Window hop size (default: 512)
|
|
55
|
+
- `onProgress`: Optional progress callback function `(progress: number) => void`, parameter is progress value between 0-1
|
|
56
|
+
- Returns: `Promise<AudioFeatures[]>`
|
|
57
|
+
|
|
58
|
+
### `detectMusicSegments(features, config?)`
|
|
59
|
+
|
|
60
|
+
Detect music segments from audio features.
|
|
61
|
+
|
|
62
|
+
- `features`: Array of audio features
|
|
63
|
+
- `config`: Detection configuration (optional)
|
|
64
|
+
- `energyPercentile`: Energy percentile threshold (0-100, default: 50)
|
|
65
|
+
- `minSegmentDuration`: Minimum segment duration in seconds (default: 25)
|
|
66
|
+
- `maxGapDuration`: Maximum gap duration in seconds (default: 15)
|
|
67
|
+
- `smoothWindowSize`: Smoothing window size in seconds (default: 4)
|
|
68
|
+
- Returns: `MusicSegment[]`
|
|
69
|
+
|
|
70
|
+
### `saveSegmentsToJson(segments, outputPath, mediaFileName)`
|
|
71
|
+
|
|
72
|
+
Save detection results to JSON format.
|
|
73
|
+
|
|
74
|
+
- `segments`: Array of music segments
|
|
75
|
+
- `outputPath`: Output file path
|
|
76
|
+
- `mediaFileName`: Media file name
|
|
77
|
+
- Returns: `Promise<void>`
|
|
78
|
+
|
|
79
|
+
### `getFeatureStats(features)`
|
|
80
|
+
|
|
81
|
+
Get statistical information of audio features (for debugging and analysis).
|
|
82
|
+
|
|
83
|
+
- `features`: Array of audio features
|
|
84
|
+
- Returns: Statistics object containing min, max, mean, median for each feature
|
|
85
|
+
|
|
86
|
+
## Type Definitions
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
interface AudioFeatures {
|
|
90
|
+
timestamp: number;
|
|
91
|
+
rms: number;
|
|
92
|
+
energy: number;
|
|
93
|
+
zcr: number;
|
|
94
|
+
spectralEnergy: number;
|
|
95
|
+
variance: number;
|
|
96
|
+
mfcc: number[];
|
|
97
|
+
spectralCentroid: number;
|
|
98
|
+
spectralRolloff: number;
|
|
99
|
+
spectralFlatness: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface MusicSegment {
|
|
103
|
+
startTime: number;
|
|
104
|
+
endTime: number;
|
|
105
|
+
duration: number;
|
|
106
|
+
confidence: number;
|
|
107
|
+
name?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface DetectionConfig {
|
|
111
|
+
energyPercentile?: number;
|
|
112
|
+
minSegmentDuration?: number;
|
|
113
|
+
maxGapDuration?: number;
|
|
114
|
+
smoothWindowSize?: number;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## How It Works
|
|
119
|
+
|
|
120
|
+
1. **Feature Extraction**: Analyze audio using sliding windows to extract multi-dimensional features (energy, MFCC, spectral features, etc.)
|
|
121
|
+
2. **Multi-Feature Scoring**: Score each time window based on 7 features:
|
|
122
|
+
- Energy intensity
|
|
123
|
+
- Energy stability
|
|
124
|
+
- Spectral centroid (timbre brightness)
|
|
125
|
+
- Spectral flatness (tone vs noise)
|
|
126
|
+
- MFCC continuity (timbre consistency)
|
|
127
|
+
- Zero-crossing rate
|
|
128
|
+
- Spectral rolloff
|
|
129
|
+
3. **Post-processing**: Smoothing, merging adjacent segments, filtering short segments
|
|
130
|
+
|
|
131
|
+
## Notes
|
|
132
|
+
|
|
133
|
+
- Only supports WAV format audio files
|
|
134
|
+
- For other formats, use tools like ffmpeg to convert to WAV first
|
|
135
|
+
- Detection accuracy depends on audio quality and configuration parameters
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export interface AudioFeatures {
|
|
2
|
+
timestamp: number;
|
|
3
|
+
rms: number;
|
|
4
|
+
energy: number;
|
|
5
|
+
zcr: number;
|
|
6
|
+
spectralEnergy: number;
|
|
7
|
+
variance: number;
|
|
8
|
+
mfcc: number[];
|
|
9
|
+
spectralCentroid: number;
|
|
10
|
+
spectralRolloff: number;
|
|
11
|
+
spectralFlatness: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 计算音频特征
|
|
15
|
+
* @param audioPath WAV 音频文件路径
|
|
16
|
+
* @param windowSize 分析窗口大小(样本数)
|
|
17
|
+
* @param hopSize 窗口跳跃大小(样本数)
|
|
18
|
+
* @param onProgress 进度回调函数,参数为 0-1 之间的进度值
|
|
19
|
+
*/
|
|
20
|
+
export declare function analyzeAudio(audioPath: string, windowSize?: number, hopSize?: number, onProgress?: (progress: number) => void): Promise<AudioFeatures[]>;
|
|
21
|
+
/**
|
|
22
|
+
* 计算特征的统计信息(用于调试和阈值设定)
|
|
23
|
+
*/
|
|
24
|
+
export declare function getFeatureStats(features: AudioFeatures[]): {
|
|
25
|
+
rms: {
|
|
26
|
+
min: number;
|
|
27
|
+
max: number;
|
|
28
|
+
mean: number;
|
|
29
|
+
median: number;
|
|
30
|
+
};
|
|
31
|
+
energy: {
|
|
32
|
+
min: number;
|
|
33
|
+
max: number;
|
|
34
|
+
mean: number;
|
|
35
|
+
median: number;
|
|
36
|
+
};
|
|
37
|
+
zcr: {
|
|
38
|
+
min: number;
|
|
39
|
+
max: number;
|
|
40
|
+
mean: number;
|
|
41
|
+
median: number;
|
|
42
|
+
};
|
|
43
|
+
spectralEnergy: {
|
|
44
|
+
min: number;
|
|
45
|
+
max: number;
|
|
46
|
+
mean: number;
|
|
47
|
+
median: number;
|
|
48
|
+
};
|
|
49
|
+
variance: {
|
|
50
|
+
min: number;
|
|
51
|
+
max: number;
|
|
52
|
+
mean: number;
|
|
53
|
+
median: number;
|
|
54
|
+
};
|
|
55
|
+
spectralCentroid: {
|
|
56
|
+
min: number;
|
|
57
|
+
max: number;
|
|
58
|
+
mean: number;
|
|
59
|
+
median: number;
|
|
60
|
+
};
|
|
61
|
+
spectralRolloff: {
|
|
62
|
+
min: number;
|
|
63
|
+
max: number;
|
|
64
|
+
mean: number;
|
|
65
|
+
median: number;
|
|
66
|
+
};
|
|
67
|
+
spectralFlatness: {
|
|
68
|
+
min: number;
|
|
69
|
+
max: number;
|
|
70
|
+
mean: number;
|
|
71
|
+
median: number;
|
|
72
|
+
};
|
|
73
|
+
mfcc: Array<{
|
|
74
|
+
min: number;
|
|
75
|
+
max: number;
|
|
76
|
+
mean: number;
|
|
77
|
+
median: number;
|
|
78
|
+
}>;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=audioAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioAnalyzer.d.ts","sourceRoot":"","sources":["../src/audioAnalyzer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAsED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,MAAa,EACzB,OAAO,GAAE,MAAY,EACrB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,aAAa,EAAE,CAAC,CAgE1B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAUzC,KAAK,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;EA+FL"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import * as WavDecoder from "wav-decoder";
|
|
3
|
+
import Meyda from "meyda";
|
|
4
|
+
/**
|
|
5
|
+
* 从 WAV 文件读取音频数据
|
|
6
|
+
*/
|
|
7
|
+
async function readWavFile(filePath) {
|
|
8
|
+
const buffer = await fs.readFile(filePath);
|
|
9
|
+
const audioData = await WavDecoder.decode(buffer.buffer);
|
|
10
|
+
// 如果是多声道,只取第一个声道
|
|
11
|
+
const channelData = audioData.channelData[0];
|
|
12
|
+
const sampleRate = audioData.sampleRate;
|
|
13
|
+
return { sampleRate, channelData };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 计算 RMS(均方根)
|
|
17
|
+
*/
|
|
18
|
+
function calculateRMS(samples) {
|
|
19
|
+
let sum = 0;
|
|
20
|
+
for (let i = 0; i < samples.length; i++) {
|
|
21
|
+
sum += samples[i] * samples[i];
|
|
22
|
+
}
|
|
23
|
+
return Math.sqrt(sum / samples.length);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 计算过零率
|
|
27
|
+
*/
|
|
28
|
+
function calculateZCR(samples) {
|
|
29
|
+
let count = 0;
|
|
30
|
+
for (let i = 1; i < samples.length; i++) {
|
|
31
|
+
if ((samples[i] >= 0 && samples[i - 1] < 0) ||
|
|
32
|
+
(samples[i] < 0 && samples[i - 1] >= 0)) {
|
|
33
|
+
count++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return count / samples.length;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 简单的 FFT 能量分布计算(高频能量)
|
|
40
|
+
*/
|
|
41
|
+
function calculateSpectralEnergy(samples) {
|
|
42
|
+
// 简化版:计算高频分量(通过差分近似)
|
|
43
|
+
let highFreqEnergy = 0;
|
|
44
|
+
for (let i = 1; i < samples.length; i++) {
|
|
45
|
+
const diff = samples[i] - samples[i - 1];
|
|
46
|
+
highFreqEnergy += diff * diff;
|
|
47
|
+
}
|
|
48
|
+
return highFreqEnergy / samples.length;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 计算方差
|
|
52
|
+
*/
|
|
53
|
+
function calculateVariance(samples, mean) {
|
|
54
|
+
let sum = 0;
|
|
55
|
+
for (let i = 0; i < samples.length; i++) {
|
|
56
|
+
const diff = samples[i] - mean;
|
|
57
|
+
sum += diff * diff;
|
|
58
|
+
}
|
|
59
|
+
return sum / samples.length;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 计算音频特征
|
|
63
|
+
* @param audioPath WAV 音频文件路径
|
|
64
|
+
* @param windowSize 分析窗口大小(样本数)
|
|
65
|
+
* @param hopSize 窗口跳跃大小(样本数)
|
|
66
|
+
* @param onProgress 进度回调函数,参数为 0-1 之间的进度值
|
|
67
|
+
*/
|
|
68
|
+
export async function analyzeAudio(audioPath, windowSize = 2048, hopSize = 512, onProgress) {
|
|
69
|
+
const { sampleRate, channelData } = await readWavFile(audioPath);
|
|
70
|
+
const features = [];
|
|
71
|
+
// 滑动窗口分析
|
|
72
|
+
const totalWindows = Math.floor((channelData.length - windowSize) / hopSize);
|
|
73
|
+
for (let i = 0; i < totalWindows; i++) {
|
|
74
|
+
const start = i * hopSize;
|
|
75
|
+
const end = start + windowSize;
|
|
76
|
+
const window = channelData.slice(start, end);
|
|
77
|
+
const timestamp = start / sampleRate;
|
|
78
|
+
// 时域特征
|
|
79
|
+
const rms = calculateRMS(window);
|
|
80
|
+
const energy = rms * rms;
|
|
81
|
+
const zcr = calculateZCR(window);
|
|
82
|
+
const spectralEnergy = calculateSpectralEnergy(window);
|
|
83
|
+
// 计算方差
|
|
84
|
+
let mean = 0;
|
|
85
|
+
for (let j = 0; j < window.length; j++) {
|
|
86
|
+
mean += Math.abs(window[j]);
|
|
87
|
+
}
|
|
88
|
+
mean /= window.length;
|
|
89
|
+
const variance = calculateVariance(window, mean);
|
|
90
|
+
// 使用 Meyda 一次性提取多个特征(更高效)
|
|
91
|
+
const meydaFeatures = Meyda.extract(["mfcc", "spectralCentroid", "spectralRolloff", "spectralFlatness"], window);
|
|
92
|
+
const mfcc = meydaFeatures?.mfcc || new Array(13).fill(0);
|
|
93
|
+
const spectralCentroid = meydaFeatures?.spectralCentroid || 0;
|
|
94
|
+
const spectralRolloff = meydaFeatures?.spectralRolloff || 0;
|
|
95
|
+
const spectralFlatness = meydaFeatures?.spectralFlatness || 0;
|
|
96
|
+
features.push({
|
|
97
|
+
timestamp,
|
|
98
|
+
rms,
|
|
99
|
+
energy,
|
|
100
|
+
zcr,
|
|
101
|
+
spectralEnergy,
|
|
102
|
+
variance,
|
|
103
|
+
mfcc,
|
|
104
|
+
spectralCentroid,
|
|
105
|
+
spectralRolloff,
|
|
106
|
+
spectralFlatness,
|
|
107
|
+
});
|
|
108
|
+
// 调用进度回调
|
|
109
|
+
if (onProgress && i % 100 === 0) {
|
|
110
|
+
onProgress((i + 1) / totalWindows);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// 确保最后报告 100% 进度
|
|
114
|
+
if (onProgress) {
|
|
115
|
+
onProgress(1);
|
|
116
|
+
}
|
|
117
|
+
return features;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 计算特征的统计信息(用于调试和阈值设定)
|
|
121
|
+
*/
|
|
122
|
+
export function getFeatureStats(features) {
|
|
123
|
+
const stats = {
|
|
124
|
+
rms: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
125
|
+
energy: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
126
|
+
zcr: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
127
|
+
spectralEnergy: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
128
|
+
variance: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
129
|
+
spectralCentroid: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
130
|
+
spectralRolloff: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
131
|
+
spectralFlatness: { min: Infinity, max: -Infinity, mean: 0, median: 0 },
|
|
132
|
+
mfcc: [],
|
|
133
|
+
};
|
|
134
|
+
// 收集所有值用于计算中位数
|
|
135
|
+
const values = {
|
|
136
|
+
rms: [],
|
|
137
|
+
energy: [],
|
|
138
|
+
zcr: [],
|
|
139
|
+
spectralEnergy: [],
|
|
140
|
+
variance: [],
|
|
141
|
+
spectralCentroid: [],
|
|
142
|
+
spectralRolloff: [],
|
|
143
|
+
spectralFlatness: [],
|
|
144
|
+
};
|
|
145
|
+
// 初始化MFCC统计
|
|
146
|
+
const numMfcc = features[0]?.mfcc?.length || 13;
|
|
147
|
+
for (let i = 0; i < numMfcc; i++) {
|
|
148
|
+
stats.mfcc.push({ min: Infinity, max: -Infinity, mean: 0, median: 0 });
|
|
149
|
+
values[`mfcc${i}`] = [];
|
|
150
|
+
}
|
|
151
|
+
features.forEach((f) => {
|
|
152
|
+
// 处理标量特征
|
|
153
|
+
const scalarKeys = [
|
|
154
|
+
"rms",
|
|
155
|
+
"energy",
|
|
156
|
+
"zcr",
|
|
157
|
+
"spectralEnergy",
|
|
158
|
+
"variance",
|
|
159
|
+
"spectralCentroid",
|
|
160
|
+
"spectralRolloff",
|
|
161
|
+
"spectralFlatness",
|
|
162
|
+
];
|
|
163
|
+
for (const key of scalarKeys) {
|
|
164
|
+
const value = f[key];
|
|
165
|
+
if (!isNaN(value) && isFinite(value)) {
|
|
166
|
+
stats[key].min = Math.min(stats[key].min, value);
|
|
167
|
+
stats[key].max = Math.max(stats[key].max, value);
|
|
168
|
+
stats[key].mean += value;
|
|
169
|
+
values[key].push(value);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// 处理MFCC特征
|
|
173
|
+
if (f.mfcc) {
|
|
174
|
+
f.mfcc.forEach((value, i) => {
|
|
175
|
+
if (!isNaN(value) && isFinite(value)) {
|
|
176
|
+
stats.mfcc[i].min = Math.min(stats.mfcc[i].min, value);
|
|
177
|
+
stats.mfcc[i].max = Math.max(stats.mfcc[i].max, value);
|
|
178
|
+
stats.mfcc[i].mean += value;
|
|
179
|
+
values[`mfcc${i}`].push(value);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// 计算均值和中位数
|
|
185
|
+
const scalarKeys = [
|
|
186
|
+
"rms",
|
|
187
|
+
"energy",
|
|
188
|
+
"zcr",
|
|
189
|
+
"spectralEnergy",
|
|
190
|
+
"variance",
|
|
191
|
+
"spectralCentroid",
|
|
192
|
+
"spectralRolloff",
|
|
193
|
+
"spectralFlatness",
|
|
194
|
+
];
|
|
195
|
+
for (const key of scalarKeys) {
|
|
196
|
+
stats[key].mean /= features.length;
|
|
197
|
+
// 计算中位数
|
|
198
|
+
const sorted = values[key].sort((a, b) => a - b);
|
|
199
|
+
const mid = Math.floor(sorted.length / 2);
|
|
200
|
+
stats[key].median =
|
|
201
|
+
sorted.length % 2 === 0
|
|
202
|
+
? (sorted[mid - 1] + sorted[mid]) / 2
|
|
203
|
+
: sorted[mid];
|
|
204
|
+
}
|
|
205
|
+
// 计算MFCC的均值和中位数
|
|
206
|
+
for (let i = 0; i < stats.mfcc.length; i++) {
|
|
207
|
+
stats.mfcc[i].mean /= features.length;
|
|
208
|
+
const sorted = values[`mfcc${i}`].sort((a, b) => a - b);
|
|
209
|
+
const mid = Math.floor(sorted.length / 2);
|
|
210
|
+
stats.mfcc[i].median =
|
|
211
|
+
sorted.length % 2 === 0
|
|
212
|
+
? (sorted[mid - 1] + sorted[mid]) / 2
|
|
213
|
+
: sorted[mid];
|
|
214
|
+
}
|
|
215
|
+
return stats;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=audioAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioAnalyzer.js","sourceRoot":"","sources":["../src/audioAnalyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,OAAO,EACL,YAAY,EAEZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,GAGpB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AudioFeatures } from "./audioAnalyzer.js";
|
|
2
|
+
export interface MusicSegment {
|
|
3
|
+
startTime: number;
|
|
4
|
+
endTime: number;
|
|
5
|
+
duration: number;
|
|
6
|
+
confidence: number;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DetectionConfig {
|
|
10
|
+
energyPercentile?: number;
|
|
11
|
+
minSegmentDuration?: number;
|
|
12
|
+
maxGapDuration?: number;
|
|
13
|
+
smoothWindowSize?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 检测音乐片段 - 使用多特征综合判断(包括MFCC)
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectMusicSegments(features: AudioFeatures[], config?: DetectionConfig): MusicSegment[];
|
|
19
|
+
//# sourceMappingURL=segmentDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmentDetector.d.ts","sourceRoot":"","sources":["../src/segmentDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAmB,MAAM,oBAAoB,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAE9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgCD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,GAAE,eAAoB,GAC3B,YAAY,EAAE,CAkMhB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { getFeatureStats } from "./audioAnalyzer.js";
|
|
2
|
+
const DEFAULT_CONFIG = {
|
|
3
|
+
energyPercentile: 50, // 能量超过中位数
|
|
4
|
+
minSegmentDuration: 25, // 提高到15秒,过滤更多短片段
|
|
5
|
+
maxGapDuration: 15, // 提高到10秒,合并更多相邻片段
|
|
6
|
+
smoothWindowSize: 4, // 提高到3秒,增强平滑效果
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* 对布尔序列进行平滑处理
|
|
10
|
+
*/
|
|
11
|
+
function smoothBooleanSequence(sequence, windowSize) {
|
|
12
|
+
const result = [];
|
|
13
|
+
const halfWindow = Math.floor(windowSize / 2);
|
|
14
|
+
for (let i = 0; i < sequence.length; i++) {
|
|
15
|
+
const start = Math.max(0, i - halfWindow);
|
|
16
|
+
const end = Math.min(sequence.length, i + halfWindow + 1);
|
|
17
|
+
const window = sequence.slice(start, end);
|
|
18
|
+
// 如果窗口内大部分为 true,则判定为音乐
|
|
19
|
+
const trueCount = window.filter((v) => v).length;
|
|
20
|
+
result.push(trueCount > window.length / 2);
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 检测音乐片段 - 使用多特征综合判断(包括MFCC)
|
|
26
|
+
*/
|
|
27
|
+
export function detectMusicSegments(features, config = {}) {
|
|
28
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
29
|
+
// 计算特征统计信息
|
|
30
|
+
const stats = getFeatureStats(features);
|
|
31
|
+
// 使用百分位数计算阈值
|
|
32
|
+
const energyValues = features.map((f) => f.energy).sort((a, b) => a - b);
|
|
33
|
+
const energyThreshold = energyValues[Math.floor((energyValues.length * cfg.energyPercentile) / 100)];
|
|
34
|
+
// 计算MFCC相似度阈值(用于检测音乐的连续性)
|
|
35
|
+
const mfccVariances = features.map((f, idx) => {
|
|
36
|
+
if (idx === 0)
|
|
37
|
+
return 0;
|
|
38
|
+
let variance = 0;
|
|
39
|
+
for (let i = 0; i < f.mfcc.length && i < features[idx - 1].mfcc.length; i++) {
|
|
40
|
+
const diff = f.mfcc[i] - features[idx - 1].mfcc[i];
|
|
41
|
+
variance += diff * diff;
|
|
42
|
+
}
|
|
43
|
+
return Math.sqrt(variance);
|
|
44
|
+
});
|
|
45
|
+
const avgMfccVariance = mfccVariances.reduce((a, b) => a + b, 0) / mfccVariances.length;
|
|
46
|
+
// 第一步:基于多特征判断每个时间窗口是否可能是音乐
|
|
47
|
+
const isMusicWindow = features.map((f, idx) => {
|
|
48
|
+
let musicScore = 0;
|
|
49
|
+
let totalWeight = 0;
|
|
50
|
+
// 1. 能量判断(权重:2.0)
|
|
51
|
+
const hasHighEnergy = f.energy > energyThreshold;
|
|
52
|
+
if (hasHighEnergy) {
|
|
53
|
+
musicScore += 2.0;
|
|
54
|
+
}
|
|
55
|
+
totalWeight += 2.0;
|
|
56
|
+
// 2. 能量稳定性判断(权重:1.5)
|
|
57
|
+
if (idx > 0 && idx < features.length - 1) {
|
|
58
|
+
const prevEnergy = features[idx - 1].energy;
|
|
59
|
+
const nextEnergy = features[idx + 1].energy;
|
|
60
|
+
const avgEnergy = (prevEnergy + f.energy + nextEnergy) / 3;
|
|
61
|
+
if (avgEnergy > 0) {
|
|
62
|
+
const variation = Math.abs(f.energy - avgEnergy) / avgEnergy;
|
|
63
|
+
const stabilityScore = 1 - Math.min(variation, 1);
|
|
64
|
+
// 音乐通常更稳定(stabilityScore > 0.3)
|
|
65
|
+
if (stabilityScore > 0.3) {
|
|
66
|
+
musicScore += 1.5 * stabilityScore;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
totalWeight += 1.5;
|
|
71
|
+
// 3. 频谱质心判断(权重:1.0)
|
|
72
|
+
// 音乐通常有更丰富的频率成分,质心在中高频
|
|
73
|
+
const centroidScore = f.spectralCentroid > stats.spectralCentroid.mean * 0.7 &&
|
|
74
|
+
f.spectralCentroid < stats.spectralCentroid.mean * 1.3;
|
|
75
|
+
if (centroidScore) {
|
|
76
|
+
musicScore += 1.0;
|
|
77
|
+
}
|
|
78
|
+
totalWeight += 1.0;
|
|
79
|
+
// 4. 频谱平坦度判断(权重:1.0)
|
|
80
|
+
// 音乐的频谱平坦度通常较低(更多音调特性)
|
|
81
|
+
if (f.spectralFlatness < stats.spectralFlatness.median) {
|
|
82
|
+
musicScore += 1.0;
|
|
83
|
+
}
|
|
84
|
+
totalWeight += 1.0;
|
|
85
|
+
// 5. MFCC连续性判断(权重:2.0)
|
|
86
|
+
// 音乐的MFCC变化通常比人声更平滑
|
|
87
|
+
if (idx > 0) {
|
|
88
|
+
const mfccVariance = mfccVariances[idx];
|
|
89
|
+
if (mfccVariance < avgMfccVariance * 1.2) {
|
|
90
|
+
const smoothness = 1 - Math.min(mfccVariance / (avgMfccVariance * 1.5), 1);
|
|
91
|
+
musicScore += 2.0 * smoothness;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
musicScore += 1.0; // 第一帧给一半分数
|
|
96
|
+
}
|
|
97
|
+
totalWeight += 2.0;
|
|
98
|
+
// 6. 过零率判断(权重:0.5)
|
|
99
|
+
// 音乐通常有适中的过零率
|
|
100
|
+
if (f.zcr > stats.zcr.min * 2 && f.zcr < stats.zcr.median * 1.5) {
|
|
101
|
+
musicScore += 0.5;
|
|
102
|
+
}
|
|
103
|
+
totalWeight += 0.5;
|
|
104
|
+
// 7. 频谱滚降判断(权重:0.8)
|
|
105
|
+
// 音乐通常有更多高频内容
|
|
106
|
+
if (f.spectralRolloff > stats.spectralRolloff.mean * 0.8) {
|
|
107
|
+
musicScore += 0.8;
|
|
108
|
+
}
|
|
109
|
+
totalWeight += 0.8;
|
|
110
|
+
// 计算最终得分(0-1)
|
|
111
|
+
const finalScore = musicScore / totalWeight;
|
|
112
|
+
// 阈值设为0.6,即需要60%的特征符合音乐特性
|
|
113
|
+
return finalScore > 0.6;
|
|
114
|
+
});
|
|
115
|
+
// 第二步:平滑处理
|
|
116
|
+
const smoothWindowSamples = Math.floor(cfg.smoothWindowSize / (features[1].timestamp - features[0].timestamp));
|
|
117
|
+
const smoothed = smoothBooleanSequence(isMusicWindow, smoothWindowSamples);
|
|
118
|
+
// 第三步:提取连续的音乐片段
|
|
119
|
+
const rawSegments = [];
|
|
120
|
+
let segmentStart = null;
|
|
121
|
+
let segmentScores = [];
|
|
122
|
+
for (let i = 0; i < smoothed.length; i++) {
|
|
123
|
+
const isMusic = smoothed[i];
|
|
124
|
+
const timestamp = features[i].timestamp;
|
|
125
|
+
if (isMusic && segmentStart === null) {
|
|
126
|
+
segmentStart = timestamp;
|
|
127
|
+
segmentScores = [];
|
|
128
|
+
}
|
|
129
|
+
if (isMusic && segmentStart !== null) {
|
|
130
|
+
// 收集片段内的置信度分数
|
|
131
|
+
segmentScores.push(isMusicWindow[i] ? 1 : 0);
|
|
132
|
+
}
|
|
133
|
+
if (!isMusic && segmentStart !== null) {
|
|
134
|
+
const avgConfidence = segmentScores.length > 0
|
|
135
|
+
? segmentScores.reduce((a, b) => a + b, 0) / segmentScores.length
|
|
136
|
+
: 0.8;
|
|
137
|
+
rawSegments.push({
|
|
138
|
+
startTime: segmentStart,
|
|
139
|
+
endTime: timestamp,
|
|
140
|
+
duration: timestamp - segmentStart,
|
|
141
|
+
confidence: avgConfidence,
|
|
142
|
+
});
|
|
143
|
+
segmentStart = null;
|
|
144
|
+
segmentScores = [];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (segmentStart !== null) {
|
|
148
|
+
const lastTimestamp = features[features.length - 1].timestamp;
|
|
149
|
+
const avgConfidence = segmentScores.length > 0
|
|
150
|
+
? segmentScores.reduce((a, b) => a + b, 0) / segmentScores.length
|
|
151
|
+
: 0.8;
|
|
152
|
+
rawSegments.push({
|
|
153
|
+
startTime: segmentStart,
|
|
154
|
+
endTime: lastTimestamp,
|
|
155
|
+
duration: lastTimestamp - segmentStart,
|
|
156
|
+
confidence: avgConfidence,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// 第四步:过滤太短的片段和低置信度片段
|
|
160
|
+
const filteredSegments = rawSegments.filter((s) => s.duration >= cfg.minSegmentDuration && s.confidence > 0.5);
|
|
161
|
+
// 第五步:合并相近的片段
|
|
162
|
+
const mergedSegments = [];
|
|
163
|
+
for (const segment of filteredSegments) {
|
|
164
|
+
if (mergedSegments.length === 0) {
|
|
165
|
+
mergedSegments.push(segment);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const lastSegment = mergedSegments[mergedSegments.length - 1];
|
|
169
|
+
const gap = segment.startTime - lastSegment.endTime;
|
|
170
|
+
if (gap <= cfg.maxGapDuration) {
|
|
171
|
+
lastSegment.endTime = segment.endTime;
|
|
172
|
+
lastSegment.duration = lastSegment.endTime - lastSegment.startTime;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
mergedSegments.push(segment);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return mergedSegments;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* 格式化时间为 HH:MM:SS
|
|
183
|
+
*/
|
|
184
|
+
function formatTime(seconds) {
|
|
185
|
+
const hours = Math.floor(seconds / 3600);
|
|
186
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
187
|
+
const secs = Math.floor(seconds % 60);
|
|
188
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=segmentDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmentDetector.js","sourceRoot":"","sources":["../src/segmentDetector.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "music-segment-detector",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Audio music segment detection library - Automatically detect music segments from WAV audio files",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"audio",
|
|
21
|
+
"music",
|
|
22
|
+
"detection",
|
|
23
|
+
"segment",
|
|
24
|
+
"analysis",
|
|
25
|
+
"mfcc",
|
|
26
|
+
"audio-features",
|
|
27
|
+
"wav",
|
|
28
|
+
"music-detection",
|
|
29
|
+
"audio-analysis"
|
|
30
|
+
],
|
|
31
|
+
"author": "",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": ""
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"meyda": "^5.6.3",
|
|
39
|
+
"wav-decoder": "^1.3.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^20.11.5",
|
|
43
|
+
"typescript": "^5.3.3"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=16.0.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"watch": "tsc --watch",
|
|
51
|
+
"release": "pnpm run build && pnpm publish --access public"
|
|
52
|
+
}
|
|
53
|
+
}
|