Replace broken per-segment Opus decode with WebCodecs AudioDecoder streaming pipeline
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Minimal ambient WebCodecs declarations.
|
||||
*
|
||||
* TypeScript 5.9's bundled lib.dom.d.ts does NOT yet ship the WebCodecs audio types
|
||||
* (`AudioDecoder`, `EncodedAudioChunk`, `AudioData`, `AudioDecoderConfig`), and this repo has no
|
||||
* package.json / node_modules to pull in `@types/dom-webcodecs`. Rather than add a dependency
|
||||
* toolchain for one feature, this declares exactly the slice of the WebCodecs surface the Opus
|
||||
* streaming decoder uses — nothing more. The shapes follow the W3C WebCodecs spec.
|
||||
*
|
||||
* These are runtime-optional: `AudioDecoder` is absent on Safari < 16.4 and older Firefox, so every
|
||||
* use site guards on `typeof AudioDecoder !== 'undefined'` before touching it (the capability gate).
|
||||
*/
|
||||
|
||||
interface AudioDecoderConfig {
|
||||
codec: string;
|
||||
sampleRate: number;
|
||||
numberOfChannels: number;
|
||||
/** Codec-specific setup bytes. For Opus this is the OpusHead identification header. */
|
||||
description?: BufferSource;
|
||||
}
|
||||
|
||||
interface AudioDecoderSupport {
|
||||
supported: boolean;
|
||||
config: AudioDecoderConfig;
|
||||
}
|
||||
|
||||
type AudioSampleFormat = 'u8' | 's16' | 's24' | 's32' | 'f32' | 'u8-planar' | 's16-planar' | 's24-planar' | 's32-planar' | 'f32-planar';
|
||||
|
||||
interface AudioDataCopyToOptions {
|
||||
planeIndex: number;
|
||||
frameOffset?: number;
|
||||
frameCount?: number;
|
||||
format?: AudioSampleFormat;
|
||||
}
|
||||
|
||||
interface AudioData {
|
||||
readonly format: AudioSampleFormat | null;
|
||||
readonly sampleRate: number;
|
||||
readonly numberOfFrames: number;
|
||||
readonly numberOfChannels: number;
|
||||
readonly duration: number;
|
||||
/** Presentation timestamp in microseconds. */
|
||||
readonly timestamp: number;
|
||||
allocationSize(options: AudioDataCopyToOptions): number;
|
||||
copyTo(destination: BufferSource, options: AudioDataCopyToOptions): void;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
interface EncodedAudioChunkInit {
|
||||
type: 'key' | 'delta';
|
||||
/** Presentation timestamp in microseconds. */
|
||||
timestamp: number;
|
||||
duration?: number;
|
||||
data: BufferSource;
|
||||
}
|
||||
|
||||
declare class EncodedAudioChunk {
|
||||
constructor(init: EncodedAudioChunkInit);
|
||||
readonly type: 'key' | 'delta';
|
||||
readonly timestamp: number;
|
||||
readonly duration: number | null;
|
||||
readonly byteLength: number;
|
||||
}
|
||||
|
||||
interface AudioDecoderInit {
|
||||
output: (data: AudioData) => void;
|
||||
error: (error: DOMException) => void;
|
||||
}
|
||||
|
||||
type CodecState = 'unconfigured' | 'configured' | 'closed';
|
||||
|
||||
declare class AudioDecoder {
|
||||
constructor(init: AudioDecoderInit);
|
||||
readonly state: CodecState;
|
||||
readonly decodeQueueSize: number;
|
||||
configure(config: AudioDecoderConfig): void;
|
||||
decode(chunk: EncodedAudioChunk): void;
|
||||
flush(): Promise<void>;
|
||||
reset(): void;
|
||||
close(): void;
|
||||
static isConfigSupported(config: AudioDecoderConfig): Promise<AudioDecoderSupport>;
|
||||
}
|
||||
Reference in New Issue
Block a user