audio-chunkify 1.0.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 +326 -0
- package/dist/index.d.ts +257 -0
- package/dist/index.js +746 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils/audioCodec.ts","../src/AudioChunkify.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Default audio analysis and chunking constants.\n * All values can be overridden via RecorderOptions.\n */\nexport const DEFAULT_AUDIO_CONSTANTS = {\n /** FFT size for the AnalyserNode (must be a power of 2). Affects frequency resolution. */\n ANALYSIS_BUFFER_SIZE: 2048,\n\n /** Silence threshold in dB used for chunk splitting (-Infinity to 0). */\n SILENCE_THRESHOLD: -50,\n\n /** Maximum chunk duration in seconds before a forced split. */\n MAX_CHUNK_DURATION: 300,\n\n /** Minimum chunk duration in seconds before a silence-based split is allowed. */\n MIN_CHUNK_DURATION: 30,\n\n /** Minimum continuous silence duration in seconds required to trigger a split. */\n MIN_SILENCE_DURATION: 1,\n} as const\n\nexport type AudioConstants = typeof DEFAULT_AUDIO_CONSTANTS\n","/**\n * Ordered list of preferred MIME types for audio recording.\n * The first supported type by the browser will be used.\n */\nconst PREFERRED_MIME_TYPES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/mp4;codecs=mp4a.40.2',\n 'audio/mp4',\n 'audio/ogg;codecs=opus',\n 'audio/ogg',\n] as const\n\n/**\n * Returns the first audio MIME type supported by the current browser,\n * or null if MediaRecorder is unavailable.\n */\nexport function getCompatibleMimeType(): string | null {\n if (typeof MediaRecorder === 'undefined') {\n return null\n }\n\n for (const mimeType of PREFERRED_MIME_TYPES) {\n if (MediaRecorder.isTypeSupported(mimeType)) {\n return mimeType\n }\n }\n\n return null\n}\n\n/**\n * Derives a file extension from a MIME type string.\n * Falls back to 'webm' if the type is unrecognised.\n */\nexport function getFileExtensionFromMimeType(mimeType: string | null): string {\n if (!mimeType) return 'webm'\n if (mimeType.startsWith('audio/mp4')) return 'mp4'\n if (mimeType.startsWith('audio/ogg')) return 'ogg'\n if (mimeType.startsWith('audio/webm')) return 'webm'\n\n const match = mimeType.match(/audio\\/(\\w+)/)\n return match?.[1] ?? 'webm'\n}\n","import { DEFAULT_AUDIO_CONSTANTS } from './constants.js'\nimport {\n getCompatibleMimeType,\n getFileExtensionFromMimeType,\n} from './utils/audioCodec.js'\nimport type {\n ChunkOptions,\n ChunkProcessedPayload,\n DestroyOptions,\n RecorderCreateOptions,\n RecorderState,\n} from './types.js'\n\ninterface MixedStreamNode {\n source: MediaStreamAudioSourceNode\n gainNode: GainNode\n}\n\n/**\n * AudioChunkify\n *\n * A framework-agnostic MediaRecorder wrapper that adds:\n * - Automatic MIME type detection\n * - Multi-stream mixing via AudioContext\n * - Silence detection with configurable threshold\n * - Automatic chunk splitting (time + silence based)\n * - Recording time tracking\n * - Pause/resume with correct duration accounting\n */\nexport class AudioChunkify {\n // ── Core recorder ────────────────────────────────────────────────────────\n private _mediaRecorder: MediaRecorder | null = null\n private _stream: MediaStream | null = null\n private _audioStreams: MediaStream[] = []\n private _mimeType: string | null = null\n private _timeslice: number | null = null\n\n // ── Event callbacks ───────────────────────────────────────────────────────\n private _onDataAvailableCallback: ((event: BlobEvent) => void) | null = null\n private _onStartCallback: (() => void) | null = null\n private _onPauseCallback: (() => void) | null = null\n private _onResumeCallback: (() => void) | null = null\n private _onStopCallback: (() => void) | null = null\n private _onErrorCallback: ((event: Event) => void) | null = null\n\n // ── Time tracking ─────────────────────────────────────────────────────────\n private _recordingTime = 0\n private _intervalId: ReturnType<typeof setInterval> | null = null\n private _onTimeUpdateCallback: ((seconds: number) => void) | null = null\n\n // ── Silence analysis ─────────────────────────────────────────────────────\n private _audioContext: AudioContext | null = null\n private _analyserNode: AnalyserNode | null = null\n private _sourceNode: MediaStreamAudioSourceNode | null = null\n private _silenceTime = 0\n private _silenceIntervalId: ReturnType<typeof setInterval> | null = null\n private _silenceCheckIntervalId: ReturnType<typeof setInterval> | null = null\n private _silenceThreshold: number = DEFAULT_AUDIO_CONSTANTS.SILENCE_THRESHOLD\n private _isInSilence = false\n private _onSilenceDetectedCallback: (() => void) | null = null\n private _onAudioDetectedCallback: (() => void) | null = null\n\n // ── Mixed stream ──────────────────────────────────────────────────────────\n private _mixedStreamContext: AudioContext | null = null\n private _mixedStreamDestination: MediaStreamAudioDestinationNode | null = null\n private _mixedStreamSourceNodes: MixedStreamNode[] = []\n\n // ── Chunk management ─────────────────────────────────────────────────────\n private _audioChunks: Blob[] = []\n private _currentChunkIndex = 0\n private _processingChunk = false\n private _isChunkSplit = false\n private _lastChunkEnd: number | null = null\n private _silenceStartForChunking: number | null = null\n private _chunkSplitIntervalId: ReturnType<typeof setInterval> | null = null\n private _onChunkProcessedCallback:\n | ((payload: ChunkProcessedPayload) => Promise<void> | void)\n | null = null\n private _pauseStartTime: number | null = null\n private _totalPausedTime = 0\n\n // ── Chunk options ─────────────────────────────────────────────────────────\n private _chunkOptions: ChunkOptions = {\n maxDuration: DEFAULT_AUDIO_CONSTANTS.MAX_CHUNK_DURATION,\n minDuration: DEFAULT_AUDIO_CONSTANTS.MIN_CHUNK_DURATION,\n minSilenceDuration: DEFAULT_AUDIO_CONSTANTS.MIN_SILENCE_DURATION,\n }\n\n // ── Public API ────────────────────────────────────────────────────────────\n\n /**\n * Initialises the recorder with the given stream and options.\n *\n * @example\n * const recorder = new AudioChunkify()\n * const stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n * recorder.create(stream, { timeslice: 250 })\n */\n create(stream: MediaStream, options: RecorderCreateOptions = {}): MediaRecorder {\n if (!(stream instanceof MediaStream)) {\n throw new TypeError('stream must be a MediaStream instance.')\n }\n\n // Resolve MIME type\n if (options.mimeType) {\n if (!MediaRecorder.isTypeSupported(options.mimeType)) {\n throw new Error(`MIME type \"${options.mimeType}\" is not supported by this browser.`)\n }\n this._mimeType = options.mimeType\n } else {\n this._mimeType = getCompatibleMimeType()\n }\n\n this._timeslice = options.timeslice ?? null\n\n if (options.silenceThreshold !== undefined) {\n this.setSilenceThreshold(options.silenceThreshold)\n }\n\n if (options.chunkOptions) {\n this._chunkOptions = { ...this._chunkOptions, ...options.chunkOptions }\n }\n\n this._audioStreams = [stream]\n this._stream = this._createMixedStream()\n\n const recorderOptions: MediaRecorderOptions = {}\n if (this._mimeType) recorderOptions.mimeType = this._mimeType\n\n this._mediaRecorder = new MediaRecorder(this._stream, recorderOptions)\n this._setupEventHandlers()\n this._setupAudioAnalysis()\n\n return this._mediaRecorder\n }\n\n /** Starts recording. Optionally overrides the timeslice set in create(). */\n start(timeslice?: number): void {\n const mr = this._assertReady()\n\n if (mr.state === 'recording') {\n console.warn('[AudioChunkify] Already recording.')\n return\n }\n\n this._silenceStartForChunking = null\n const slice = timeslice ?? this._timeslice\n\n if (slice !== null && slice !== undefined) {\n mr.start(slice)\n } else {\n mr.start()\n }\n }\n\n /** Pauses an active recording. */\n pause(): void {\n const mr = this._assertReady()\n if (mr.state === 'recording') {\n mr.pause()\n } else {\n console.warn(`[AudioChunkify] Cannot pause — state is \"${mr.state}\".`)\n }\n }\n\n /** Resumes a paused recording. */\n resume(): void {\n const mr = this._assertReady()\n if (mr.state === 'paused') {\n mr.resume()\n } else {\n console.warn(`[AudioChunkify] Cannot resume — state is \"${mr.state}\".`)\n }\n }\n\n /** Stops the recording and finalises all pending chunks. */\n stop(): void {\n const mr = this._assertReady()\n this._stopChunkSplitting()\n if (mr.state !== 'inactive') {\n mr.stop()\n }\n }\n\n /**\n * Dynamically mixes in an additional audio stream.\n * The recorder is briefly restarted to rebuild the AudioContext graph.\n */\n addAudioStream(stream: MediaStream): void {\n if (!(stream instanceof MediaStream)) {\n throw new TypeError('stream must be a MediaStream instance.')\n }\n this._assertReady()\n if (this._audioStreams.includes(stream)) {\n console.warn('[AudioChunkify] Stream is already being mixed.')\n return\n }\n\n const { wasRecording, wasPaused } = this._captureState()\n if (wasRecording || wasPaused) this._mediaRecorder?.stop()\n this._audioStreams.push(stream)\n this._recreateMediaRecorder()\n this._restoreState(wasRecording, wasPaused)\n }\n\n /**\n * Removes a previously added audio stream from the mix.\n * At least one stream must remain — call destroy() to tear everything down.\n */\n removeAudioStream(stream: MediaStream): void {\n this._assertReady()\n const index = this._audioStreams.indexOf(stream)\n if (index === -1) {\n console.warn('[AudioChunkify] Stream not found.')\n return\n }\n\n if (this._audioStreams.length === 1) {\n throw new Error(\n 'Cannot remove the last stream. Call destroy() to clean up instead.',\n )\n }\n\n const { wasRecording, wasPaused } = this._captureState()\n if (wasRecording || wasPaused) this._mediaRecorder?.stop()\n this._audioStreams.splice(index, 1)\n this._recreateMediaRecorder()\n this._restoreState(wasRecording, wasPaused)\n }\n\n // ── State & metadata ──────────────────────────────────────────────────────\n\n /** Current recorder state: 'inactive' | 'recording' | 'paused' */\n getState(): RecorderState {\n return (this._mediaRecorder?.state ?? 'inactive') as RecorderState\n }\n\n /** Active MIME type (resolved at create() time). */\n getMimeType(): string | null {\n return this._mimeType\n }\n\n /** The mixed MediaStream used internally by the recorder. */\n getStream(): MediaStream | null {\n return this._stream\n }\n\n /** The underlying MediaRecorder instance. */\n getMediaRecorder(): MediaRecorder | null {\n return this._mediaRecorder\n }\n\n /** Elapsed recording time in seconds (excludes paused time). */\n getRecordingTime(): number {\n return this._recordingTime\n }\n\n /** Resets the elapsed recording time counter to zero. */\n resetRecordingTime(): void {\n this._recordingTime = 0\n this._onTimeUpdateCallback?.(this._recordingTime)\n }\n\n /** Current continuous silence duration in seconds. */\n getSilenceTime(): number {\n return this._silenceTime\n }\n\n /** Current silence detection threshold in dB. */\n getSilenceThreshold(): number {\n return this._silenceThreshold\n }\n\n /**\n * Updates the silence detection threshold.\n * @param threshold — Must be a negative number in dB (e.g. -50).\n */\n setSilenceThreshold(threshold: number): void {\n if (typeof threshold !== 'number' || threshold > 0) {\n throw new RangeError('Silence threshold must be a negative number (dB).')\n }\n this._silenceThreshold = threshold\n }\n\n /** Accumulated audio chunks since the last start() or split. */\n getAudioChunks(): Blob[] {\n return [...this._audioChunks]\n }\n\n /** Zero-based index of the current chunk. */\n getCurrentChunkIndex(): number {\n return this._currentChunkIndex\n }\n\n /** Clears the internal chunk buffer. */\n clearAudioChunks(): void {\n this._audioChunks = []\n }\n\n // ── Event registration ────────────────────────────────────────────────────\n\n onDataAvailable(callback: (event: BlobEvent) => void): this {\n this._assertCallback(callback)\n this._onDataAvailableCallback = callback\n if (this._mediaRecorder) this._mediaRecorder.ondataavailable = callback\n return this\n }\n\n onStart(callback: () => void): this {\n this._assertCallback(callback)\n this._onStartCallback = callback\n if (this._mediaRecorder) this._setupEventHandlers()\n return this\n }\n\n onPause(callback: () => void): this {\n this._assertCallback(callback)\n this._onPauseCallback = callback\n if (this._mediaRecorder) this._setupEventHandlers()\n return this\n }\n\n onResume(callback: () => void): this {\n this._assertCallback(callback)\n this._onResumeCallback = callback\n if (this._mediaRecorder) this._setupEventHandlers()\n return this\n }\n\n onStop(callback: () => void): this {\n this._assertCallback(callback)\n this._onStopCallback = callback\n if (this._mediaRecorder) this._setupEventHandlers()\n return this\n }\n\n onError(callback: (event: Event) => void): this {\n this._assertCallback(callback)\n this._onErrorCallback = callback\n if (this._mediaRecorder) this._mediaRecorder.onerror = callback\n return this\n }\n\n onTimeUpdate(callback: (seconds: number) => void): this {\n this._assertCallback(callback)\n this._onTimeUpdateCallback = callback\n return this\n }\n\n onSilenceDetected(callback: () => void): this {\n this._assertCallback(callback)\n this._onSilenceDetectedCallback = callback\n return this\n }\n\n onAudioDetected(callback: () => void): this {\n this._assertCallback(callback)\n this._onAudioDetectedCallback = callback\n return this\n }\n\n /**\n * Called each time a chunk is finalised (either by splitting or on stop).\n *\n * @example\n * recorder.onChunkProcessed(async ({ file, index, duration, isLastChunk }) => {\n * await uploadChunk(file)\n * if (isLastChunk) console.log('Recording complete')\n * })\n */\n onChunkProcessed(\n callback: (payload: ChunkProcessedPayload) => Promise<void> | void,\n ): this {\n this._assertCallback(callback)\n this._onChunkProcessedCallback = callback\n return this\n }\n\n /**\n * Fully tears down the recorder: stops recording, closes AudioContexts\n * and clears all internal state.\n *\n * By default also stops every track on the input streams. Pass\n * `{ stopStreams: false }` to keep those streams alive for reuse.\n */\n destroy(options: DestroyOptions = {}): void {\n const { stopStreams = true } = options\n\n if (this._mediaRecorder?.state !== 'inactive') {\n this._mediaRecorder?.stop()\n }\n\n if (stopStreams) {\n this._audioStreams.forEach((s) => s.getTracks().forEach((t) => t.stop()))\n }\n\n this._stopTimeTracking()\n this._recordingTime = 0\n\n this._cleanupAudioAnalysis()\n this._silenceTime = 0\n this._isInSilence = false\n\n this._stopChunkSplitting()\n this._audioChunks = []\n this._currentChunkIndex = 0\n this._processingChunk = false\n this._isChunkSplit = false\n this._lastChunkEnd = null\n this._silenceStartForChunking = null\n this._pauseStartTime = null\n this._totalPausedTime = 0\n\n this._cleanupMixedStream()\n\n this._mediaRecorder = null\n this._stream = null\n this._audioStreams = []\n this._mimeType = null\n this._timeslice = null\n\n this._onDataAvailableCallback = null\n this._onStartCallback = null\n this._onPauseCallback = null\n this._onResumeCallback = null\n this._onStopCallback = null\n this._onErrorCallback = null\n this._onTimeUpdateCallback = null\n this._onSilenceDetectedCallback = null\n this._onAudioDetectedCallback = null\n this._onChunkProcessedCallback = null\n }\n\n // ── Private helpers ───────────────────────────────────────────────────────\n\n private _assertReady(): MediaRecorder {\n if (!this._mediaRecorder) {\n throw new Error('[AudioChunkify] Not initialised. Call create() first.')\n }\n return this._mediaRecorder\n }\n\n private _assertCallback(fn: unknown): void {\n if (typeof fn !== 'function') {\n throw new TypeError('Callback must be a function.')\n }\n }\n\n private _captureState() {\n return {\n wasRecording: this._mediaRecorder?.state === 'recording',\n wasPaused: this._mediaRecorder?.state === 'paused',\n }\n }\n\n private _restoreState(wasRecording: boolean, wasPaused: boolean): void {\n if (wasRecording) {\n this.start()\n } else if (wasPaused) {\n this.start()\n this.pause()\n }\n }\n\n private _now(): number {\n if (this._audioContext?.state === 'running') {\n return this._audioContext.currentTime\n }\n return Date.now() / 1000\n }\n\n // ── Time tracking ─────────────────────────────────────────────────────────\n\n private _startTimeTracking(): void {\n this._stopTimeTracking()\n this._intervalId = setInterval(() => {\n this._recordingTime++\n this._onTimeUpdateCallback?.(this._recordingTime)\n }, 1000)\n }\n\n private _stopTimeTracking(): void {\n if (this._intervalId !== null) {\n clearInterval(this._intervalId)\n this._intervalId = null\n }\n }\n\n private _pauseTimeTracking(): void {\n this._stopTimeTracking()\n }\n\n private _resumeTimeTracking(): void {\n this._startTimeTracking()\n }\n\n // ── Audio analysis ────────────────────────────────────────────────────────\n\n private _setupAudioAnalysis(): void {\n if (!this._stream) return\n this._cleanupAudioAnalysis()\n\n try {\n this._audioContext = new AudioContext()\n this._analyserNode = this._audioContext.createAnalyser()\n this._analyserNode.fftSize = DEFAULT_AUDIO_CONSTANTS.ANALYSIS_BUFFER_SIZE\n this._analyserNode.smoothingTimeConstant = 0.8\n this._sourceNode = this._audioContext.createMediaStreamSource(this._stream)\n this._sourceNode.connect(this._analyserNode)\n } catch (err) {\n console.warn('[AudioChunkify] Could not set up audio analysis:', err)\n this._cleanupAudioAnalysis()\n }\n }\n\n private _cleanupAudioAnalysis(): void {\n this._stopSilenceTracking()\n\n try { this._sourceNode?.disconnect() } catch { /* noop */ }\n this._sourceNode = null\n\n try { this._analyserNode?.disconnect() } catch { /* noop */ }\n this._analyserNode = null\n\n if (this._audioContext && this._audioContext.state !== 'closed') {\n this._audioContext.close().catch(() => { /* noop */ })\n }\n this._audioContext = null\n }\n\n /**\n * Measures the current audio level in dBFS via time-domain RMS.\n * Shared by silence events and chunk-splitting logic.\n */\n private _measureAudioLevelDb(): number {\n if (!this._analyserNode) return -Infinity\n\n const data = new Float32Array(this._analyserNode.fftSize)\n this._analyserNode.getFloatTimeDomainData(data)\n\n let sum = 0\n for (let i = 0; i < data.length; i++) sum += data[i]! * data[i]!\n const rms = Math.sqrt(sum / data.length)\n return rms > 0 ? 20 * Math.log10(rms) : -Infinity\n }\n\n private _isCurrentlySilent(): boolean {\n if (!this._analyserNode || this._audioContext?.state !== 'running') return false\n\n try {\n return this._measureAudioLevelDb() < this._silenceThreshold\n } catch {\n return false\n }\n }\n\n private _checkSilence(): void {\n if (!this._analyserNode || this._audioContext?.state !== 'running') return\n\n try {\n const isSilent = this._isCurrentlySilent()\n\n if (isSilent && !this._isInSilence) {\n this._isInSilence = true\n if (!this._silenceIntervalId) {\n this._silenceIntervalId = setInterval(() => {\n if (this._isInSilence) this._silenceTime++\n }, 1000)\n }\n this._onSilenceDetectedCallback?.()\n } else if (!isSilent && this._isInSilence) {\n this._isInSilence = false\n if (this._silenceIntervalId !== null) {\n clearInterval(this._silenceIntervalId)\n this._silenceIntervalId = null\n }\n this._silenceTime = 0\n this._onAudioDetectedCallback?.()\n }\n } catch (err) {\n console.warn('[AudioChunkify] Silence check error:', err)\n }\n }\n\n private _startSilenceChecking(): void {\n if (this._silenceCheckIntervalId !== null) {\n clearInterval(this._silenceCheckIntervalId)\n }\n this._silenceCheckIntervalId = setInterval(() => this._checkSilence(), 100)\n }\n\n private _stopSilenceTracking(): void {\n if (this._silenceIntervalId !== null) {\n clearInterval(this._silenceIntervalId)\n this._silenceIntervalId = null\n }\n if (this._silenceCheckIntervalId !== null) {\n clearInterval(this._silenceCheckIntervalId)\n this._silenceCheckIntervalId = null\n }\n this._isInSilence = false\n }\n\n // ── Chunk splitting ───────────────────────────────────────────────────────\n\n private _shouldSplitChunk(): boolean {\n if (this._mediaRecorder?.state === 'paused') return false\n if (this._lastChunkEnd === null) return false\n\n const currentTime = this._now()\n const elapsed = currentTime - this._lastChunkEnd\n\n if (elapsed >= this._chunkOptions.maxDuration) return true\n\n if (elapsed >= this._chunkOptions.minDuration) {\n if (this._isCurrentlySilent()) {\n if (!this._silenceStartForChunking) {\n this._silenceStartForChunking = currentTime\n }\n if (currentTime - this._silenceStartForChunking >= this._chunkOptions.minSilenceDuration) {\n return true\n }\n } else {\n this._silenceStartForChunking = null\n }\n }\n\n return false\n }\n\n private _restartRecorderSegment(): void {\n if (\n this._mediaRecorder?.state === 'recording' &&\n !this._processingChunk\n ) {\n this._isChunkSplit = true\n this._mediaRecorder.stop()\n }\n }\n\n private _startChunkSplitting(): void {\n this._stopChunkSplitting()\n this._chunkSplitIntervalId = setInterval(() => {\n if (\n this._mediaRecorder?.state === 'recording' &&\n !this._processingChunk &&\n this._shouldSplitChunk()\n ) {\n this._restartRecorderSegment()\n }\n }, 100)\n }\n\n private _stopChunkSplitting(): void {\n if (this._chunkSplitIntervalId !== null) {\n clearInterval(this._chunkSplitIntervalId)\n this._chunkSplitIntervalId = null\n }\n }\n\n // ── Mixed stream ──────────────────────────────────────────────────────────\n\n private _createMixedStream(): MediaStream {\n if (!this._audioStreams.length) return new MediaStream()\n\n if (this._mixedStreamDestination) this._cleanupMixedStream()\n\n try {\n this._mixedStreamContext = new AudioContext()\n this._mixedStreamDestination =\n this._mixedStreamContext.createMediaStreamDestination()\n this._mixedStreamSourceNodes = []\n\n for (const stream of this._audioStreams) {\n if (stream.getAudioTracks().length > 0) {\n const source = this._mixedStreamContext.createMediaStreamSource(stream)\n const gainNode = this._mixedStreamContext.createGain()\n gainNode.gain.value = 1.0\n source.connect(gainNode)\n gainNode.connect(this._mixedStreamDestination)\n this._mixedStreamSourceNodes.push({ source, gainNode })\n }\n }\n\n return this._mixedStreamDestination.stream\n } catch (err) {\n console.warn('[AudioChunkify] Could not create mixed stream, falling back:', err)\n const fallback = new MediaStream()\n this._audioStreams.forEach((s) =>\n s.getAudioTracks().forEach((t) => fallback.addTrack(t)),\n )\n return fallback\n }\n }\n\n private _recreateMediaRecorder(): void {\n this._stream = this._createMixedStream()\n\n const opts: MediaRecorderOptions = {}\n if (this._mimeType) opts.mimeType = this._mimeType\n\n this._mediaRecorder = new MediaRecorder(this._stream, opts)\n this._setupEventHandlers()\n this._setupAudioAnalysis()\n }\n\n private _cleanupMixedStream(): void {\n for (const { source, gainNode } of this._mixedStreamSourceNodes) {\n try { gainNode.disconnect() } catch { /* noop */ }\n try { source.disconnect() } catch { /* noop */ }\n }\n this._mixedStreamSourceNodes = []\n\n try {\n this._mixedStreamDestination?.stream\n .getTracks()\n .forEach((t) => t.stop())\n } catch { /* noop */ }\n this._mixedStreamDestination = null\n\n if (this._mixedStreamContext?.state !== 'closed') {\n this._mixedStreamContext?.close().catch(() => { /* noop */ })\n }\n this._mixedStreamContext = null\n }\n\n // ── Event wiring ──────────────────────────────────────────────────────────\n\n private _setupEventHandlers(): void {\n if (!this._mediaRecorder) return\n\n this._mediaRecorder.ondataavailable = (event: BlobEvent) => {\n if (event.data?.size > 0) {\n this._audioChunks.push(event.data)\n this._onDataAvailableCallback?.(event)\n }\n }\n\n this._mediaRecorder.onstart = () => {\n this._startTimeTracking()\n\n if (this._audioContext?.state === 'suspended') {\n this._audioContext.resume()\n }\n this._startSilenceChecking()\n\n if (this._lastChunkEnd === null) {\n this._lastChunkEnd = this._now()\n }\n\n this._audioChunks = []\n this._silenceStartForChunking = null\n this._startChunkSplitting()\n this._onStartCallback?.()\n }\n\n this._mediaRecorder.onpause = () => {\n this._pauseTimeTracking()\n this._stopSilenceTracking()\n this._stopChunkSplitting()\n this._pauseStartTime = this._now()\n this._onPauseCallback?.()\n }\n\n this._mediaRecorder.onresume = () => {\n this._resumeTimeTracking()\n\n if (this._audioContext?.state === 'suspended') {\n this._audioContext.resume()\n }\n\n if (this._pauseStartTime !== null) {\n const pausedDuration = this._now() - this._pauseStartTime\n this._totalPausedTime += pausedDuration\n if (this._lastChunkEnd !== null) {\n this._lastChunkEnd += pausedDuration\n }\n this._pauseStartTime = null\n }\n\n this._startSilenceChecking()\n this._startChunkSplitting()\n this._onResumeCallback?.()\n }\n\n this._mediaRecorder.onstop = async () => {\n this._stopTimeTracking()\n this._stopSilenceTracking()\n this._stopChunkSplitting()\n\n if (this._isChunkSplit) {\n await this._processChunk(false)\n\n this._audioChunks = []\n this._silenceStartForChunking = null\n\n // Restart the MediaRecorder to get fresh headers for the next segment\n const opts: MediaRecorderOptions = {}\n if (this._mimeType) opts.mimeType = this._mimeType\n\n this._mediaRecorder = new MediaRecorder(this._stream!, opts)\n this._setupEventHandlers()\n this._isChunkSplit = false\n\n if (this._timeslice !== null) {\n this._mediaRecorder.start(this._timeslice)\n } else {\n this._mediaRecorder.start()\n }\n } else {\n await this._processChunk(true)\n\n this.resetRecordingTime()\n this._silenceTime = 0\n this._audioChunks = []\n this._currentChunkIndex = 0\n this._lastChunkEnd = null\n this._silenceStartForChunking = null\n this._pauseStartTime = null\n this._totalPausedTime = 0\n this._onStopCallback?.()\n }\n }\n\n if (this._onErrorCallback) {\n this._mediaRecorder.onerror = this._onErrorCallback\n }\n }\n\n private async _processChunk(isLastChunk: boolean): Promise<void> {\n if (\n !this._audioChunks.length ||\n !this._onChunkProcessedCallback ||\n this._processingChunk\n ) return\n\n this._processingChunk = true\n\n try {\n const mimeType = this._mimeType ?? getCompatibleMimeType() ?? 'audio/webm'\n const ext = getFileExtensionFromMimeType(mimeType)\n\n const now = this._now()\n let pausedCompensation = 0\n if (this._pauseStartTime !== null) {\n pausedCompensation = now - this._pauseStartTime\n }\n\n const duration =\n this._lastChunkEnd !== null\n ? now - this._lastChunkEnd - pausedCompensation\n : 0\n\n const index = this._currentChunkIndex\n const blob = new Blob(this._audioChunks, { type: mimeType })\n const file = new File([blob], `chunk-${index}.${ext}`, { type: mimeType })\n\n await this._onChunkProcessedCallback({ file, index, duration, isLastChunk })\n\n if (!isLastChunk) {\n this._currentChunkIndex = index + 1\n this._lastChunkEnd = this._now()\n this._totalPausedTime = 0\n }\n } catch (err) {\n console.error('[AudioChunkify] Error processing chunk:', err)\n } finally {\n this._processingChunk = false\n }\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "audio-chunkify",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Record audio in the browser and automatically split it into chunks — by silence, time, or both. Framework agnostic, zero dependencies.",
|
|
5
|
+
"author": "Leandro Frederico",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"audio",
|
|
9
|
+
"chunk",
|
|
10
|
+
"chunking",
|
|
11
|
+
"audio-chunking",
|
|
12
|
+
"audio-split",
|
|
13
|
+
"mediarecorder",
|
|
14
|
+
"audio-recording",
|
|
15
|
+
"silence-detection",
|
|
16
|
+
"stream-mixing",
|
|
17
|
+
"web-audio",
|
|
18
|
+
"browser",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"dev": "tsup --watch",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"prepublishOnly": "npm run build"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.4.0",
|
|
47
|
+
"vitest": "^3.2.4"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.0.0"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/leofred/audio-chunkify.git"
|
|
55
|
+
},
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/leofred/audio-chunkify/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/leofred/audio-chunkify#readme"
|
|
60
|
+
}
|