@h-ear/core 1.0.0-dev.202604132134 → 1.0.0-dev.202604140003

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/README.md CHANGED
@@ -86,16 +86,12 @@ const config: ServerConfig = {
86
86
  | `apiUrl(config, path)` | Resolve full URL for a given API path |
87
87
  | `ENVIRONMENTS` | Base URL map per environment |
88
88
  | `HEAR_API` | API constants (formats, limits, noop callback URL) |
89
- | `hasFFmpeg`, `splitAudioFile`, `mergeChunkResults`, | Large-file chunker utilities |
90
-
91
- ## Large File Chunking
92
-
93
- `splitAudioFile()` splits audio over 25 MB into 120-second overlapping chunks using `ffmpeg`. `mergeChunkResults()` deduplicates and merges the results. Requires `ffmpeg` + `ffprobe` on PATH — optional, only needed for local files over 25 MB.
89
+ | `getAudioDuration(filePath)` | Audio duration detection via ffprobe (returns 0 when unavailable) |
94
90
 
95
91
  ## Requirements
96
92
 
97
93
  - Node.js >= 18
98
- - ffmpeg + ffprobe (optional — large file chunking only)
94
+ - ffprobe (optional — duration detection for upload routing)
99
95
 
100
96
  ## License
101
97
 
package/dist/chunker.d.ts CHANGED
@@ -1,46 +1,8 @@
1
1
  /**
2
- * Audio file chunking for large files that exceed the API size limit.
3
- * Uses ffmpeg to split audio into overlapping chunks, preserving temporal connectivity.
4
- *
5
- * Overlap: 30s between chunks so boundary events are not lost.
2
+ * Audio duration detection via ffprobe.
3
+ * The ffmpeg-based splitAudioFile/mergeChunkResults chunker was removed
4
+ * replaced by byte-slice upload in api-client.ts (submitClassifyChunked).
6
5
  */
7
- import type { ClassifyResult } from './types.js';
8
- /** Chunk duration (seconds). Keeps each chunk under API 25MB limit. */
9
- export declare const CHUNK_DURATION_SEC = 120;
10
- /** Chunk overlap (seconds). Preserves temporal connectivity at chunk boundaries. */
11
- export declare const CHUNK_OVERLAP_SEC = 30;
12
- /** Minimum trailing chunk duration (seconds). Chunks shorter than this are merged into the previous chunk. */
13
- export declare const MIN_TRAILING_CHUNK_SEC = 5;
14
- export interface ChunkInfo {
15
- path: string;
16
- startTime: number;
17
- duration: number;
18
- index: number;
19
- }
20
- /** Check if ffmpeg is available */
21
- export declare function hasFFmpeg(): boolean;
22
6
  /** Get audio duration in seconds using ffprobe */
23
7
  export declare function getAudioDuration(filePath: string): number;
24
- /**
25
- * Split audio file into overlapping chunks using ffmpeg.
26
- * Returns array of chunk file paths with their time offsets.
27
- */
28
- export declare function splitAudioFile(filePath: string, totalDuration: number, options?: {
29
- chunkDurationSec?: number;
30
- overlapSec?: number;
31
- }): ChunkInfo[];
32
- /** Clean up chunk temp files */
33
- export declare function cleanupChunks(chunks: ChunkInfo[]): void;
34
- /**
35
- * Merge classification results from multiple chunks into a unified result.
36
- * Uses TIME-CHOP: each chunk owns a non-overlapping time window.
37
- * Events outside the owned window are discarded — the overlap served its ML context purpose.
38
- *
39
- * Chunk N owns [N*step, (N+1)*step) where step = chunkDuration - overlap.
40
- * Last chunk owns [start, totalDuration].
41
- */
42
- export declare function mergeChunkResults(chunkResults: Array<{
43
- chunk: ChunkInfo;
44
- result: ClassifyResult;
45
- }>, _originalFileName: string, totalDuration: number): ClassifyResult;
46
8
  //# sourceMappingURL=chunker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,8GAA8G;AAC9G,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,mCAAmC;AACnC,wBAAgB,SAAS,IAAI,OAAO,CAOnC;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D,SAAS,EAAE,CAuDb;AAED,gCAAgC;AAChC,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAOvD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,YAAY,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,EACjE,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,GACtB,cAAc,CAmChB"}
1
+ {"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUzD"}
package/dist/chunker.js CHANGED
@@ -1,29 +1,9 @@
1
1
  /**
2
- * Audio file chunking for large files that exceed the API size limit.
3
- * Uses ffmpeg to split audio into overlapping chunks, preserving temporal connectivity.
4
- *
5
- * Overlap: 30s between chunks so boundary events are not lost.
2
+ * Audio duration detection via ffprobe.
3
+ * The ffmpeg-based splitAudioFile/mergeChunkResults chunker was removed
4
+ * replaced by byte-slice upload in api-client.ts (submitClassifyChunked).
6
5
  */
7
- import { execSync, spawnSync } from 'child_process';
8
- import { existsSync, mkdirSync, unlinkSync, rmdirSync } from 'fs';
9
- import { join, basename } from 'path';
10
- import { tmpdir } from 'os';
11
- /** Chunk duration (seconds). Keeps each chunk under API 25MB limit. */
12
- export const CHUNK_DURATION_SEC = 120;
13
- /** Chunk overlap (seconds). Preserves temporal connectivity at chunk boundaries. */
14
- export const CHUNK_OVERLAP_SEC = 30;
15
- /** Minimum trailing chunk duration (seconds). Chunks shorter than this are merged into the previous chunk. */
16
- export const MIN_TRAILING_CHUNK_SEC = 5;
17
- /** Check if ffmpeg is available */
18
- export function hasFFmpeg() {
19
- try {
20
- execSync('ffmpeg -version', { stdio: 'pipe', timeout: 5000 });
21
- return true;
22
- }
23
- catch {
24
- return false;
25
- }
26
- }
6
+ import { execSync } from 'child_process';
27
7
  /** Get audio duration in seconds using ffprobe */
28
8
  export function getAudioDuration(filePath) {
29
9
  try {
@@ -34,109 +14,4 @@ export function getAudioDuration(filePath) {
34
14
  return 0;
35
15
  }
36
16
  }
37
- /**
38
- * Split audio file into overlapping chunks using ffmpeg.
39
- * Returns array of chunk file paths with their time offsets.
40
- */
41
- export function splitAudioFile(filePath, totalDuration, options) {
42
- const chunkDuration = options?.chunkDurationSec ?? CHUNK_DURATION_SEC;
43
- const overlap = options?.overlapSec ?? CHUNK_OVERLAP_SEC;
44
- const chunkDir = join(tmpdir(), `h-ear-chunks-${Date.now()}`);
45
- mkdirSync(chunkDir, { recursive: true });
46
- const chunks = [];
47
- const name = basename(filePath, '.mp3').replace(/\.[^.]+$/, '');
48
- let startTime = 0;
49
- let index = 0;
50
- const step = chunkDuration - overlap;
51
- while (startTime < totalDuration) {
52
- const chunkFile = join(chunkDir, `${name}_chunk${index}.mp3`);
53
- let duration = Math.min(chunkDuration, totalDuration - startTime);
54
- // Peek: if the next step would leave a trailing chunk shorter than MIN_TRAILING_CHUNK_SEC,
55
- // extend this chunk to eat the remainder and finish.
56
- const nextStart = startTime + step;
57
- const remaining = totalDuration - nextStart;
58
- if (remaining > 0 && remaining < MIN_TRAILING_CHUNK_SEC) {
59
- duration = totalDuration - startTime;
60
- }
61
- const result = spawnSync('ffmpeg', [
62
- '-y',
63
- '-ss', String(startTime),
64
- '-i', filePath,
65
- '-t', String(duration),
66
- '-acodec', 'libmp3lame',
67
- '-q:a', '4', // Good quality MP3 (~128kbps)
68
- chunkFile,
69
- ], {
70
- stdio: ['pipe', 'pipe', 'pipe'],
71
- encoding: 'utf-8',
72
- timeout: 30000,
73
- });
74
- if (result.status !== 0 || !existsSync(chunkFile)) {
75
- process.stderr.write(`[h-ear-core] ffmpeg chunk ${index} failed: ${(result.stderr || '').split('\n').pop()}\n`);
76
- break;
77
- }
78
- chunks.push({ path: chunkFile, startTime, duration, index });
79
- // If we ate the trailing remainder, we're done
80
- if (duration >= totalDuration - startTime)
81
- break;
82
- startTime += step;
83
- index++;
84
- }
85
- return chunks;
86
- }
87
- /** Clean up chunk temp files */
88
- export function cleanupChunks(chunks) {
89
- if (chunks.length === 0)
90
- return;
91
- const chunkDir = join(chunks[0].path, '..');
92
- for (const chunk of chunks) {
93
- try {
94
- unlinkSync(chunk.path);
95
- }
96
- catch { /* ignore */ }
97
- }
98
- try {
99
- rmdirSync(chunkDir);
100
- }
101
- catch { /* ignore */ }
102
- }
103
- /**
104
- * Merge classification results from multiple chunks into a unified result.
105
- * Uses TIME-CHOP: each chunk owns a non-overlapping time window.
106
- * Events outside the owned window are discarded — the overlap served its ML context purpose.
107
- *
108
- * Chunk N owns [N*step, (N+1)*step) where step = chunkDuration - overlap.
109
- * Last chunk owns [start, totalDuration].
110
- */
111
- export function mergeChunkResults(chunkResults, _originalFileName, totalDuration) {
112
- const allClassifications = [];
113
- for (let i = 0; i < chunkResults.length; i++) {
114
- const { chunk, result } = chunkResults[i];
115
- if (!result.classifications)
116
- continue;
117
- const isLast = i === chunkResults.length - 1;
118
- const ownedStart = chunk.startTime;
119
- const ownedEnd = isLast ? totalDuration : chunkResults[i + 1].chunk.startTime;
120
- for (const cls of result.classifications) {
121
- const absoluteStart = (cls.startTime || 0) + chunk.startTime;
122
- const absoluteEnd = (cls.endTime || 0) + chunk.startTime;
123
- // Time-chop: only keep events within this chunk's owned window
124
- if (absoluteStart >= ownedStart && absoluteStart < ownedEnd) {
125
- allClassifications.push({
126
- ...cls,
127
- startTime: absoluteStart,
128
- endTime: absoluteEnd,
129
- });
130
- }
131
- }
132
- }
133
- allClassifications.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
134
- return {
135
- requestId: `merged-${Date.now()}`,
136
- duration: totalDuration,
137
- processingTimeMs: 0,
138
- eventCount: allClassifications.length,
139
- classifications: allClassifications,
140
- };
141
- }
142
17
  //# sourceMappingURL=chunker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CACnB,+DAA+D,QAAQ,GAAG,EAC1E,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CACzE,CAAC;QACF,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,CAAC;IACb,CAAC;AACL,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,7 +7,6 @@ export { resolveConfigFromEnv, apiUrl } from './config.js';
7
7
  export type { ServerConfig } from './config.js';
8
8
  export { HEAR_API, ENVIRONMENTS } from './constants.js';
9
9
  export type { HearEnvironment } from './constants.js';
10
- export { hasFFmpeg, getAudioDuration, splitAudioFile, cleanupChunks, mergeChunkResults, CHUNK_DURATION_SEC, CHUNK_OVERLAP_SEC, MIN_TRAILING_CHUNK_SEC, } from './chunker.js';
11
- export type { ChunkInfo } from './chunker.js';
10
+ export { getAudioDuration } from './chunker.js';
12
11
  export type { ClassifyRequest, ClassifyResult, Classification, NoiseEvent, AsyncAccepted, ChunkResult, ClientCapturedMetadata, ClassifyOptions, BatchFile, BatchRequest, BatchAccepted, AudioClass, ClassesResult, HealthResult, UsageResult, JobSummary, JobsResult, JobResult, JobNoiseEvent, JobEventsResult, JobAudioResult, JobWaveformResult, WebhookRegister, WebhookResult, EnterpriseWebhookCreate, EnterpriseWebhook, EnterpriseWebhookCreateResult, EnterpriseWebhookListResult, EnterpriseWebhookUpdate, PingResult, WebhookDelivery, WebhookDeliveriesResult, ApiErrorBody, } from './types.js';
13
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EACH,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAC3C,aAAa,EAAE,iBAAiB,EAChC,kBAAkB,EAAE,iBAAiB,EAAE,sBAAsB,GAChE,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,YAAY,EACR,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EACvF,sBAAsB,EAAE,eAAe,EACvC,SAAS,EAAE,YAAY,EAAE,aAAa,EACtC,UAAU,EAAE,aAAa,EACzB,YAAY,EACZ,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAC9C,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EACjE,eAAe,EAAE,aAAa,EAC9B,uBAAuB,EAAE,iBAAiB,EAAE,6BAA6B,EACzE,2BAA2B,EAAE,uBAAuB,EACpD,UAAU,EAAE,eAAe,EAAE,uBAAuB,EACpD,YAAY,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,YAAY,EACR,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EACvF,sBAAsB,EAAE,eAAe,EACvC,SAAS,EAAE,YAAY,EAAE,aAAa,EACtC,UAAU,EAAE,aAAa,EACzB,YAAY,EACZ,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAC9C,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EACjE,eAAe,EAAE,aAAa,EAC9B,uBAAuB,EAAE,iBAAiB,EAAE,6BAA6B,EACzE,2BAA2B,EAAE,uBAAuB,EACpD,UAAU,EAAE,eAAe,EAAE,uBAAuB,EACpD,YAAY,GACf,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,6 @@ export { HearApiClient, HearApiError } from './api-client.js';
7
7
  export { resolveConfigFromEnv, apiUrl } from './config.js';
8
8
  // Constants
9
9
  export { HEAR_API, ENVIRONMENTS } from './constants.js';
10
- // Chunker
11
- export { hasFFmpeg, getAudioDuration, splitAudioFile, cleanupChunks, mergeChunkResults, CHUNK_DURATION_SEC, CHUNK_OVERLAP_SEC, MIN_TRAILING_CHUNK_SEC, } from './chunker.js';
10
+ // Chunker (duration detection only — ffmpeg chunking removed, replaced by byte-slice upload)
11
+ export { getAudioDuration } from './chunker.js';
12
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,aAAa;AACb,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG9D,SAAS;AACT,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG3D,YAAY;AACZ,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGxD,UAAU;AACV,OAAO,EACH,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAC3C,aAAa,EAAE,iBAAiB,EAChC,kBAAkB,EAAE,iBAAiB,EAAE,sBAAsB,GAChE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,aAAa;AACb,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG9D,SAAS;AACT,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG3D,YAAY;AACZ,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGxD,6FAA6F;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-ear/core",
3
- "version": "1.0.0-dev.202604132134",
3
+ "version": "1.0.0-dev.202604140003",
4
4
  "description": "Shared API client for H-ear World audio classification — used by @h-ear/mcp-server and @h-ear/openclaw",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,8 +55,7 @@
55
55
  "node": ">=18"
56
56
  },
57
57
  "systemDependencies": {
58
- "ffmpeg": "optional — integration test ML comparison only (splitAudioFile). Not used by MCP tools.",
59
- "ffprobe": "optional — integration test duration detection only (getAudioDuration). Not used by MCP tools."
58
+ "ffprobe": "optional — duration detection (getAudioDuration) for upload routing. Returns 0 when unavailable."
60
59
  },
61
60
  "files": [
62
61
  "dist",