diff --git a/src/lib/exporter/gifExporter.ts b/src/lib/exporter/gifExporter.ts index 531477d..3ab3ba9 100644 --- a/src/lib/exporter/gifExporter.ts +++ b/src/lib/exporter/gifExporter.ts @@ -92,6 +92,7 @@ export class GifExporter { } async export(): Promise { + let webcamFrameQueue: AsyncVideoFrameQueue | null = null; try { this.cleanup(); this.cancelled = false; @@ -165,7 +166,8 @@ export class GifExporter { console.log("[GifExporter] Using streaming decode (web-demuxer + VideoDecoder)"); let frameIndex = 0; - const webcamFrameQueue = this.config.webcamVideoUrl ? new AsyncVideoFrameQueue() : null; + webcamFrameQueue = this.config.webcamVideoUrl ? new AsyncVideoFrameQueue() : null; + let webcamDecodeError: Error | null = null; const webcamDecodePromise = this.webcamDecoder && webcamFrameQueue ? this.webcamDecoder @@ -180,13 +182,18 @@ export class GifExporter { webcamFrameQueue.enqueue(webcamFrame); }, ) - .then(() => { - webcamFrameQueue.close(); - }) .catch((error) => { - webcamFrameQueue.fail(error instanceof Error ? error : new Error(String(error))); + webcamDecodeError = + error instanceof Error ? error : new Error(String(error)); throw error; }) + .finally(() => { + if (webcamDecodeError) { + webcamFrameQueue.fail(webcamDecodeError); + } else { + webcamFrameQueue.close(); + } + }) : null; // Stream decode and process frames — no seeking! @@ -277,6 +284,7 @@ export class GifExporter { error: error instanceof Error ? error.message : String(error), }; } finally { + webcamFrameQueue?.destroy(); this.cleanup(); } } diff --git a/src/lib/exporter/videoExporter.ts b/src/lib/exporter/videoExporter.ts index eb09ab9..bd30eb8 100644 --- a/src/lib/exporter/videoExporter.ts +++ b/src/lib/exporter/videoExporter.ts @@ -56,6 +56,7 @@ export class VideoExporter { } async export(): Promise { + let webcamFrameQueue: AsyncVideoFrameQueue | null = null; try { this.cleanup(); this.cancelled = false; @@ -116,7 +117,8 @@ export class VideoExporter { const frameDuration = 1_000_000 / this.config.frameRate; // in microseconds let frameIndex = 0; - const webcamFrameQueue = this.config.webcamVideoUrl ? new AsyncVideoFrameQueue() : null; + webcamFrameQueue = this.config.webcamVideoUrl ? new AsyncVideoFrameQueue() : null; + let webcamDecodeError: Error | null = null; const webcamDecodePromise = this.webcamDecoder && webcamFrameQueue ? this.webcamDecoder @@ -131,13 +133,18 @@ export class VideoExporter { webcamFrameQueue.enqueue(webcamFrame); }, ) - .then(() => { - webcamFrameQueue.close(); - }) .catch((error) => { - webcamFrameQueue.fail(error instanceof Error ? error : new Error(String(error))); + webcamDecodeError = + error instanceof Error ? error : new Error(String(error)); throw error; }) + .finally(() => { + if (webcamDecodeError) { + webcamFrameQueue.fail(webcamDecodeError); + } else { + webcamFrameQueue.close(); + } + }) : null; // Stream decode and process frames — no seeking! @@ -259,6 +266,7 @@ export class VideoExporter { error: error instanceof Error ? error.message : String(error), }; } finally { + webcamFrameQueue?.destroy(); this.cleanup(); } }