mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 19:03:46 +02:00
Add Output.cancel
This commit is contained in:
+12
-2
@@ -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) {
|
||||||
|
|||||||
@@ -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.');
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user