UNPKG

@meframe/core

Version:

Next generation media processing framework based on WebCodecs

131 lines (130 loc) 3.31 kB
class BaseDecoder { decoder; config; controller = null; constructor(config) { this.config = config; } async initialize() { if (this.decoder?.state === "configured") { return; } const isSupported = await this.isConfigSupported(this.config); if (!isSupported.supported) { throw new Error( `Codec not supported: ${this.config.codecString || this.config.codec}` ); } this.decoder = this.createDecoder({ output: this.handleOutput.bind(this), error: this.handleError.bind(this) }); await this.configureDecoder(this.config); } async reconfigure(config) { this.config = { ...this.config, ...config }; if (!this.decoder) { await this.initialize(); return; } if (this.decoder.state === "configured") { await this.decoder.flush(); } const isSupported = await this.isConfigSupported(this.config); if (!isSupported.supported) { throw new Error( `New configuration not supported: ${this.config.codecString || this.config.codec}` ); } await this.configureDecoder(this.config); } async flush() { if (!this.decoder) return; await this.decoder.flush(); } async reset() { if (!this.decoder) return; this.decoder.reset(); this.onReset(); } async close() { if (!this.decoder) return; if (this.decoder.state === "configured") { await this.decoder.flush(); } this.decoder.close(); this.decoder = void 0; } get isReady() { return this.decoder?.state === "configured"; } get queueSize() { return this.decoder?.decodeQueueSize ?? 0; } handleOutput(data) { if (!this.controller) { this.closeIfPossible(data); return; } try { this.controller.enqueue(data); } catch (error) { if (error instanceof TypeError) { this.closeIfPossible(data); return; } throw error; } } handleError(error) { console.error(`${this.getDecoderType()} decoder error:`, error); this.controller?.error(error); } closeIfPossible(data) { data?.close?.(); data?.frame?.close?.(); } onReset() { } createStream() { return new TransformStream( { start: async (controller) => { this.controller = controller; if (!this.isReady) { await this.initialize(); } }, transform: async (input) => { if (!this.decoder || this.decoder.state !== "configured") { throw new Error("Decoder not configured"); } if (this.decoder.decodeQueueSize >= this.decodeQueueThreshold) { await new Promise((resolve) => { const check = () => { if (!this.decoder || this.decoder.decodeQueueSize < this.decodeQueueThreshold - 1) { resolve(); } else { setTimeout(check, 10); } }; check(); }); } this.decode(input); }, flush: async () => { await this.flush(); } }, { highWaterMark: this.highWaterMark, size: () => 1 } ); } } export { BaseDecoder as B }; //# sourceMappingURL=BaseDecoder.js.map