Add Output.cancel

This commit is contained in:
Vanilagy
2025-01-02 19:57:32 +01:00
parent c42495ec7e
commit 141bed1b37
4 changed files with 49 additions and 4 deletions
+12 -2
View File
@@ -20,6 +20,8 @@ export abstract class MediaSource {
/** @internal */ /** @internal */
_connectedTrack: OutputTrack | null = null; _connectedTrack: OutputTrack | null = null;
/** @internal */ /** @internal */
_closing = false;
/** @internal */
_closed = false; _closed = false;
/** @internal */ /** @internal */
_offsetTimestamps = false; _offsetTimestamps = false;
@@ -30,6 +32,10 @@ export abstract class MediaSource {
throw new Error('Cannot call digest without connecting the source to an output track.'); throw new Error('Cannot call digest without connecting the source to an output track.');
} }
if (this._connectedTrack.output._canceled) {
throw new Error('Cannot call digest after output has been canceled.');
}
if (!this._connectedTrack.output._started) { if (!this._connectedTrack.output._started) {
throw new Error('Cannot call digest before output has been started.'); throw new Error('Cannot call digest before output has been started.');
} }
@@ -48,8 +54,8 @@ export abstract class MediaSource {
/** @internal */ /** @internal */
async _flush() {} async _flush() {}
close() { async close() {
if (this._closed) { if (this._closing) {
throw new Error('Source already closed.'); throw new Error('Source already closed.');
} }
@@ -61,6 +67,10 @@ export abstract class MediaSource {
throw new Error('Cannot call close before output has been started.'); throw new Error('Cannot call close before output has been started.');
} }
this._closing = true;
await this._flush();
this._closed = true; this._closed = true;
if (this._connectedTrack.output._finalizing) { if (this._connectedTrack.output._finalizing) {
+24
View File
@@ -53,6 +53,8 @@ export class Output {
/** @internal */ /** @internal */
_started = false; _started = false;
/** @internal */ /** @internal */
_canceled = false;
/** @internal */
_finalizing = false; _finalizing = false;
/** @internal */ /** @internal */
_mutex = new AsyncMutex(); _mutex = new AsyncMutex();
@@ -150,6 +152,9 @@ export class Output {
} }
async start() { async start() {
if (this._canceled) {
throw new Error('Output has been canceled.');
}
if (this._started) { if (this._started) {
throw new Error('Output already started.'); throw new Error('Output already started.');
} }
@@ -168,6 +173,25 @@ export class Output {
release(); release();
} }
async cancel() {
if (this._finalizing) {
throw new Error('Cannot cancel after calling finalize.');
}
if (this._canceled) {
throw new Error('Output already canceled.');
}
this._canceled = true;
const release = await this._mutex.acquire();
const promises = this._tracks.map(x => x.source._flush());
await Promise.all(promises);
await this._writer.close();
release();
}
async finalize() { async finalize() {
if (!this._started) { if (!this._started) {
throw new Error('Cannot finalize before starting.'); throw new Error('Cannot finalize before starting.');
+12
View File
@@ -17,6 +17,8 @@ export abstract class Writer {
abstract flush(): Promise<void>; abstract flush(): Promise<void>;
/** Called after muxing has finished. */ /** Called after muxing has finished. */
abstract finalize(): Promise<void>; abstract finalize(): Promise<void>;
/** Closes the writer. */
abstract close(): Promise<void>;
} }
/** /**
@@ -74,6 +76,8 @@ export class ArrayBufferTargetWriter extends Writer {
this.target.buffer = this.buffer.slice(0, Math.max(this.maxPos, this.pos)); this.target.buffer = this.buffer.slice(0, Math.max(this.maxPos, this.pos));
} }
async close() {}
getSlice(start: number, end: number) { getSlice(start: number, end: number) {
return this.bytes.slice(start, end); return this.bytes.slice(start, end);
} }
@@ -185,6 +189,10 @@ export class StreamTargetWriter extends Writer {
assert(this.writer); assert(this.writer);
return this.writer.close(); return this.writer.close();
} }
async close() {
return this.writer?.close();
}
} }
const DEFAULT_CHUNK_SIZE = 2 ** 24; const DEFAULT_CHUNK_SIZE = 2 ** 24;
@@ -375,4 +383,8 @@ export class ChunkedStreamTargetWriter extends Writer {
return this.writer.close(); return this.writer.close();
} }
async close() {
return this.writer?.close();
}
} }
+1 -2
View File
@@ -4,5 +4,4 @@
- Audio codec string regex validation - Audio codec string regex validation
- Add the new audio codecs to muxers - Add the new audio codecs to muxers
- Mov muxer!!! Only mov can hold PCM audio, MP4 cannot - Mov muxer!!! Only mov can hold PCM audio, MP4 cannot
- Metadata methods for computing average fps and bitrate - Metadata methods for computing average fps and bitrate
- close method on Output to cancel it (and dispose the encoders). Perhaps abort is a better title