fix: properly dispose WebCodecs resources in video cache (#663)
The VideoCache was creating Input objects but not storing them, so input.dispose() was never called. This caused WebCodecs VideoDecoder resources to leak, leading to browser crashes during video playback. Changes: - Store Input object in VideoSinkData - Call input.dispose() on initialization errors - Call input.dispose() when clearing video from cache - Clear frame references when disposing This follows the same pattern as AudioManager which properly manages Input disposal. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
de5293b024
commit
80b229c3bf
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from "mediabunny";
|
||||
|
||||
interface VideoSinkData {
|
||||
input: Input;
|
||||
sink: CanvasSink;
|
||||
iterator: AsyncGenerator<WrappedCanvas, void, unknown> | null;
|
||||
currentFrame: WrappedCanvas | null;
|
||||
|
|
@ -246,19 +247,21 @@ export class VideoCache {
|
|||
mediaId: string;
|
||||
file: File;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
const input = new Input({
|
||||
source: new BlobSource(file),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const input = new Input({
|
||||
source: new BlobSource(file),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
|
||||
try {
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
if (!videoTrack) {
|
||||
input.dispose();
|
||||
throw new Error("No video track found");
|
||||
}
|
||||
|
||||
const canDecode = await videoTrack.canDecode();
|
||||
if (!canDecode) {
|
||||
input.dispose();
|
||||
throw new Error("Video codec not supported for decoding");
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +271,7 @@ export class VideoCache {
|
|||
});
|
||||
|
||||
this.sinks.set(mediaId, {
|
||||
input,
|
||||
sink,
|
||||
iterator: null,
|
||||
currentFrame: null,
|
||||
|
|
@ -277,6 +281,7 @@ export class VideoCache {
|
|||
prefetchPromise: null,
|
||||
});
|
||||
} catch (error) {
|
||||
input.dispose();
|
||||
console.error(`Failed to initialize video sink for ${mediaId}:`, error);
|
||||
throw error;
|
||||
}
|
||||
|
|
@ -289,6 +294,13 @@ export class VideoCache {
|
|||
void sinkData.iterator.return();
|
||||
}
|
||||
|
||||
// Clear frame references
|
||||
sinkData.currentFrame = null;
|
||||
sinkData.nextFrame = null;
|
||||
|
||||
// Dispose the input to release WebCodecs resources
|
||||
sinkData.input.dispose();
|
||||
|
||||
this.sinks.delete(mediaId);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue