Skip to content

Commit

Permalink
Make MainSourceBufferInterface code more readable isolating inner fun…
Browse files Browse the repository at this point in the history
…ctions

The callback called on the `"updateend"` and `"error"` events on a
SourceBuffer were previously declared as arrow functions inside the
constructor.

This allowed to keep a clear JS context for the `this` keyword, but it
made the `MainSourceBufferInterface`'s constructor harder to read.

I found it more readable to declare both callback as private methods
instead, with the drawback of having to bind the `this` explictely.
  • Loading branch information
peaBerberian committed Mar 20, 2024
1 parent 796218a commit e7dfcb8
Showing 1 changed file with 49 additions and 45 deletions.
94 changes: 49 additions & 45 deletions src/mse/main_media_source_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,51 +210,8 @@ export class MainSourceBufferInterface implements ISourceBufferInterface {
this._operationQueue = [];
this._currentOperations = [];

const onError = (evt: Event) => {
let error: Error;
if ((evt as unknown as Error) instanceof Error) {
error = evt as unknown as Error;
} else if ((evt as unknown as { error: Error }).error instanceof Error) {
error = (evt as unknown as { error: Error }).error;
} else {
error = new Error("Unknown SourceBuffer Error");
}
const currentOps = this._currentOperations;
this._currentOperations = [];
if (currentOps.length === 0) {
log.error("SBI: error for an unknown operation", error);
} else {
const rejected = new SourceBufferError(
error.name,
error.message,
error.name === "QuotaExceededError",
);
for (const op of currentOps) {
op.reject(rejected);
}
}
};
const onUpdateEnd = () => {
const currentOps = this._currentOperations;
this._currentOperations = [];
try {
for (const op of currentOps) {
op.resolve(convertToRanges(this._sourceBuffer.buffered));
}
} catch (err) {
for (const op of currentOps) {
if (err instanceof Error && err.name === "InvalidStateError") {
// Most likely the SourceBuffer just has been removed from the
// `MediaSource`.
// Just return an empty buffered range.
op.resolve([]);
} else {
op.reject(err);
}
}
}
this._performNextOperation();
};
const onError = this._onError.bind(this);
const onUpdateEnd = this._onUpdateEnd.bind(this);
sourceBuffer.addEventListener("error", onError);
sourceBuffer.addEventListener("updateend", onUpdateEnd);
this._canceller.signal.register(() => {
Expand Down Expand Up @@ -322,6 +279,53 @@ export class MainSourceBufferInterface implements ISourceBufferInterface {
this._emptyCurrentQueue();
}

private _onError(evt: Event) {
let error: Error;
if ((evt as unknown as Error) instanceof Error) {
error = evt as unknown as Error;
} else if ((evt as unknown as { error: Error }).error instanceof Error) {
error = (evt as unknown as { error: Error }).error;
} else {
error = new Error("Unknown SourceBuffer Error");
}
const currentOps = this._currentOperations;
this._currentOperations = [];
if (currentOps.length === 0) {
log.error("SBI: error for an unknown operation", error);
} else {
const rejected = new SourceBufferError(
error.name,
error.message,
error.name === "QuotaExceededError",
);
for (const op of currentOps) {
op.reject(rejected);
}
}
}

private _onUpdateEnd() {
const currentOps = this._currentOperations;
this._currentOperations = [];
try {
for (const op of currentOps) {
op.resolve(convertToRanges(this._sourceBuffer.buffered));
}
} catch (err) {
for (const op of currentOps) {
if (err instanceof Error && err.name === "InvalidStateError") {
// Most likely the SourceBuffer just has been removed from the
// `MediaSource`.
// Just return an empty buffered range.
op.resolve([]);
} else {
op.reject(err);
}
}
}
this._performNextOperation();
}

private _emptyCurrentQueue(): void {
const error = new CancellationError();
if (this._currentOperations.length > 0) {
Expand Down

0 comments on commit e7dfcb8

Please sign in to comment.