fix: always tear down webcam export queues

This commit is contained in:
Marcus Schiesser
2026-03-17 20:03:14 +08:00
parent f1a453b9b2
commit 776ed954f2
2 changed files with 26 additions and 10 deletions
+13 -5
View File
@@ -92,6 +92,7 @@ export class GifExporter {
}
async export(): Promise<ExportResult> {
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();
}
}
+13 -5
View File
@@ -56,6 +56,7 @@ export class VideoExporter {
}
async export(): Promise<ExportResult> {
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();
}
}