mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Add ducktyped Promise checks (fixes #472)
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
AsyncMutex,
|
||||
binarySearchExact,
|
||||
binarySearchLessOrEqual,
|
||||
isThenable,
|
||||
UNDETERMINED_LANGUAGE,
|
||||
} from '../misc';
|
||||
import { EncodedPacket, PLACEHOLDER_DATA } from '../packet';
|
||||
@@ -84,7 +85,7 @@ export class AdtsDemuxer extends Demuxer {
|
||||
// Skip all ID3v2 tags at the start of the file
|
||||
while (true) {
|
||||
let slice = this.reader.requestSlice(this.lastLoadedPos, ID3_V2_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
this.lastSampleLoaded = true;
|
||||
@@ -105,7 +106,7 @@ export class AdtsDemuxer extends Demuxer {
|
||||
MIN_ADTS_FRAME_HEADER_SIZE,
|
||||
MAX_ADTS_FRAME_HEADER_SIZE,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) {
|
||||
this.lastSampleLoaded = true;
|
||||
return;
|
||||
@@ -167,7 +168,7 @@ export class AdtsDemuxer extends Demuxer {
|
||||
|
||||
while (true) {
|
||||
let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
if (!headerSlice) break;
|
||||
|
||||
const id3V2Header = readId3V2Header(headerSlice);
|
||||
@@ -176,7 +177,7 @@ export class AdtsDemuxer extends Demuxer {
|
||||
}
|
||||
|
||||
let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
|
||||
if (contentSlice instanceof Promise) contentSlice = await contentSlice;
|
||||
if (isThenable(contentSlice)) contentSlice = await contentSlice;
|
||||
if (!contentSlice) break;
|
||||
|
||||
parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
|
||||
@@ -306,7 +307,7 @@ class AdtsAudioTrackBacking implements InputAudioTrackBacking {
|
||||
data = PLACEHOLDER_DATA;
|
||||
} else {
|
||||
let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null; // Data didn't fit into the rest of the file
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { assert, MaybePromise } from './misc';
|
||||
import { assert, isThenable, MaybePromise } from './misc';
|
||||
import { readBytes, Reader } from './reader';
|
||||
|
||||
// Inspired in part by https://github.com/halloweeks/AES-128-CBC/blob/main/AES_128_CBC.h
|
||||
@@ -258,7 +258,7 @@ export const createAes128CbcDecryptStream = (
|
||||
const requestedLength = CHUNK_SIZE + BLOCK_SIZE;
|
||||
|
||||
let nextSlice = reader.requestSliceRange(pos, 0, requestedLength);
|
||||
if (nextSlice instanceof Promise) nextSlice = await nextSlice;
|
||||
if (isThenable(nextSlice)) nextSlice = await nextSlice;
|
||||
if (!nextSlice || nextSlice.length === 0) {
|
||||
// Due to padding, this should never happen
|
||||
throw new Error('Invalid ciphertext.');
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
assert,
|
||||
AsyncMutex,
|
||||
binarySearchLessOrEqual,
|
||||
isThenable,
|
||||
textDecoder,
|
||||
UNDETERMINED_LANGUAGE,
|
||||
} from '../misc';
|
||||
@@ -108,7 +109,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
let currentPos = 0;
|
||||
while (true) {
|
||||
let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
|
||||
if (!headerSlice) {
|
||||
this.lastSampleLoaded = true;
|
||||
@@ -121,7 +122,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
}
|
||||
|
||||
let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
|
||||
if (contentSlice instanceof Promise) contentSlice = await contentSlice;
|
||||
if (isThenable(contentSlice)) contentSlice = await contentSlice;
|
||||
assert(contentSlice);
|
||||
|
||||
parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
|
||||
@@ -136,7 +137,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
|| currentPos < this.reader.fileSize
|
||||
) {
|
||||
let sizeSlice = this.reader.requestSlice(currentPos, 4);
|
||||
if (sizeSlice instanceof Promise) sizeSlice = await sizeSlice;
|
||||
if (isThenable(sizeSlice)) sizeSlice = await sizeSlice;
|
||||
currentPos += 4;
|
||||
|
||||
if (sizeSlice === null) {
|
||||
@@ -160,7 +161,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
currentPos,
|
||||
size,
|
||||
);
|
||||
if (streamInfoBlock instanceof Promise) streamInfoBlock = await streamInfoBlock;
|
||||
if (isThenable(streamInfoBlock)) streamInfoBlock = await streamInfoBlock;
|
||||
|
||||
assert(streamInfoBlock);
|
||||
if (streamInfoBlock === null) {
|
||||
@@ -219,7 +220,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
currentPos,
|
||||
size,
|
||||
);
|
||||
if (vorbisCommentBlock instanceof Promise) vorbisCommentBlock = await vorbisCommentBlock;
|
||||
if (isThenable(vorbisCommentBlock)) vorbisCommentBlock = await vorbisCommentBlock;
|
||||
|
||||
assert(vorbisCommentBlock);
|
||||
|
||||
@@ -237,7 +238,7 @@ export class FlacDemuxer extends Demuxer {
|
||||
currentPos,
|
||||
size,
|
||||
);
|
||||
if (pictureBlock instanceof Promise) pictureBlock = await pictureBlock;
|
||||
if (isThenable(pictureBlock)) pictureBlock = await pictureBlock;
|
||||
|
||||
assert(pictureBlock);
|
||||
const pictureType = readU32Be(pictureBlock);
|
||||
@@ -775,7 +776,7 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
||||
rawSample.byteOffset,
|
||||
rawSample.byteSize,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null; // Data didn't fit into the rest of the file
|
||||
|
||||
+16
-16
@@ -36,7 +36,7 @@ import { TS_PACKET_SIZE } from './mpeg-ts/mpeg-ts-misc';
|
||||
import { HlsDemuxer } from './hls/hls-demuxer';
|
||||
import { HLS_MIME_TYPE } from './hls/hls-misc';
|
||||
import { PathedSource } from './source';
|
||||
import { MaybePromise } from './misc';
|
||||
import { isThenable, MaybePromise } from './misc';
|
||||
|
||||
/**
|
||||
* Base class representing an input media file format.
|
||||
@@ -75,7 +75,7 @@ export abstract class IsobmffInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
protected async _getMajorBrand(input: Input) {
|
||||
let slice = input._reader.requestSlice(0, 12);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return null;
|
||||
|
||||
slice.skip(4);
|
||||
@@ -117,7 +117,7 @@ export class Mp4InputFormat extends IsobmffInputFormat {
|
||||
}
|
||||
|
||||
let slice = input._reader.requestSlice(4, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const fourCc = readAscii(slice, 4);
|
||||
@@ -169,7 +169,7 @@ export class MatroskaInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
protected async isSupportedEBMLOfDocType(input: Input, desiredDocType: string) {
|
||||
let headerSlice = input._reader.requestSlice(0, MAX_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
if (!headerSlice) return false;
|
||||
|
||||
const varIntSize = readVarIntSize(headerSlice);
|
||||
@@ -192,7 +192,7 @@ export class MatroskaInputFormat extends InputFormat {
|
||||
}
|
||||
|
||||
let dataSlice = input._reader.requestSlice(headerSlice.filePos, dataSize);
|
||||
if (dataSlice instanceof Promise) dataSlice = await dataSlice;
|
||||
if (isThenable(dataSlice)) dataSlice = await dataSlice;
|
||||
if (!dataSlice) return false;
|
||||
|
||||
const startPos = headerSlice.filePos;
|
||||
@@ -295,7 +295,7 @@ export class Mp3InputFormat extends InputFormat {
|
||||
|
||||
while (true) {
|
||||
let slice = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const id3V2Header = readId3V2Header(slice);
|
||||
@@ -315,7 +315,7 @@ export class Mp3InputFormat extends InputFormat {
|
||||
const xingOffset = getXingOffset(firstHeader.mpegVersionId, firstHeader.channel);
|
||||
|
||||
let slice = input._reader.requestSlice(firstResult.startPos + xingOffset, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const word = readU32Be(slice);
|
||||
@@ -376,7 +376,7 @@ export class WaveInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
async _canReadInput(input: Input) {
|
||||
let slice = input._reader.requestSlice(0, 12);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const riffType = readAscii(slice, 4);
|
||||
@@ -416,7 +416,7 @@ export class OggInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
async _canReadInput(input: Input) {
|
||||
let slice = input._reader.requestSlice(0, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
return readAscii(slice, 4) === 'OggS';
|
||||
@@ -451,7 +451,7 @@ export class FlacInputFormat extends InputFormat {
|
||||
// There might be ID3v2 headers at the start, skip 'em
|
||||
while (true) {
|
||||
let slice = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const id3V2Header = readId3V2Header(slice);
|
||||
@@ -463,7 +463,7 @@ export class FlacInputFormat extends InputFormat {
|
||||
}
|
||||
|
||||
let slice = input._reader.requestSlice(currentPos, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
return readAscii(slice, 4) === 'fLaC';
|
||||
@@ -498,7 +498,7 @@ export class AdtsInputFormat extends InputFormat {
|
||||
|
||||
while (true) {
|
||||
let slice = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const id3V2Header = readId3V2Header(slice);
|
||||
@@ -514,7 +514,7 @@ export class AdtsInputFormat extends InputFormat {
|
||||
MIN_ADTS_FRAME_HEADER_SIZE,
|
||||
MAX_ADTS_FRAME_HEADER_SIZE,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const firstHeader = readAdtsFrameHeader(slice);
|
||||
@@ -529,7 +529,7 @@ export class AdtsInputFormat extends InputFormat {
|
||||
MIN_ADTS_FRAME_HEADER_SIZE,
|
||||
MAX_ADTS_FRAME_HEADER_SIZE,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const secondHeader = readAdtsFrameHeader(slice);
|
||||
@@ -573,7 +573,7 @@ export class MpegTsInputFormat extends InputFormat {
|
||||
async _canReadInput(input: Input) {
|
||||
const lengthToCheck = TS_PACKET_SIZE + 16 + 1;
|
||||
let slice = input._reader.requestSlice(0, lengthToCheck);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const bytes = readBytes(slice, lengthToCheck);
|
||||
@@ -618,7 +618,7 @@ export class HlsInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
async _canReadInput(input: Input) {
|
||||
let slice = input._reader.requestSlice(0, 7);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
const isM3u8 = readAscii(slice, 7) === '#EXTM3U';
|
||||
|
||||
+9
-9
@@ -12,7 +12,7 @@ import { customAudioDecoders, customVideoDecoders } from './custom-coder';
|
||||
import { Input } from './input';
|
||||
import { Logging } from './logging';
|
||||
import { EncodedPacketSink, PacketRetrievalOptions } from './media-sink';
|
||||
import { assert, MaybePromise, Rational, Rotation, roundToDivisor, simplifyRational } from './misc';
|
||||
import { assert, isThenable, MaybePromise, Rational, Rotation, roundToDivisor, simplifyRational } from './misc';
|
||||
import { TrackType } from './output';
|
||||
import { EncodedPacket, PacketType } from './packet';
|
||||
import { TrackDisposition } from './metadata';
|
||||
@@ -528,7 +528,7 @@ export abstract class InputTrack {
|
||||
}
|
||||
|
||||
const requireSync = <T>(value: MaybePromise<T>, getterName: string, asyncName: string): T => {
|
||||
if (value instanceof Promise) {
|
||||
if (isThenable(value)) {
|
||||
throw new Error(
|
||||
`'${getterName}' is deprecated and not available synchronously for this track. Use the preferred`
|
||||
+ ` '${asyncName}()' instead.`,
|
||||
@@ -554,7 +554,7 @@ const toValidatedPredicate = <T extends InputTrack>(
|
||||
};
|
||||
|
||||
const result = predicate(track);
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(handle);
|
||||
}
|
||||
return handle(result);
|
||||
@@ -1225,7 +1225,7 @@ export const toValidatedInputTrackQuery = <T extends InputTrack>(
|
||||
};
|
||||
|
||||
const result = query.filter!(track);
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(handle);
|
||||
} else {
|
||||
return handle(result);
|
||||
@@ -1248,7 +1248,7 @@ export const toValidatedInputTrackQuery = <T extends InputTrack>(
|
||||
};
|
||||
|
||||
const result = query.sortBy!(track);
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(handle);
|
||||
} else {
|
||||
return handle(result);
|
||||
@@ -1274,7 +1274,7 @@ export const mergeInputTrackQueries = <T extends InputTrack>(
|
||||
return queryB?.filter?.(track) ?? true;
|
||||
};
|
||||
|
||||
if (resultA instanceof Promise) {
|
||||
if (isThenable(resultA)) {
|
||||
return resultA.then(handleResultA);
|
||||
} else {
|
||||
return handleResultA(resultA);
|
||||
@@ -1294,7 +1294,7 @@ export const mergeInputTrackQueries = <T extends InputTrack>(
|
||||
];
|
||||
};
|
||||
|
||||
if (resultA instanceof Promise || resultB instanceof Promise) {
|
||||
if (isThenable(resultA) || isThenable(resultB)) {
|
||||
return Promise.all([resultA, resultB]).then(([resultA, resultB]) => {
|
||||
return join(resultA, resultB);
|
||||
});
|
||||
@@ -1313,7 +1313,7 @@ export const queryInputTracks = async <T extends InputTrack>(
|
||||
let matched = tracks;
|
||||
if (query?.filter) {
|
||||
const filterMatches = tracks.map(t => query.filter!(t));
|
||||
const hasAsyncFilter = filterMatches.some(x => x instanceof Promise);
|
||||
const hasAsyncFilter = filterMatches.some(x => isThenable(x));
|
||||
if (hasAsyncFilter) {
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
const resolvedFilterMatches = await Promise.all(filterMatches);
|
||||
@@ -1328,7 +1328,7 @@ export const queryInputTracks = async <T extends InputTrack>(
|
||||
}
|
||||
|
||||
const sortValues = matched.map(t => query.sortBy!(t));
|
||||
const hasAsyncSort = sortValues.some(x => x instanceof Promise);
|
||||
const hasAsyncSort = sortValues.some(x => isThenable(x));
|
||||
const resolvedSortValues = hasAsyncSort
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
? await Promise.all(sortValues)
|
||||
|
||||
@@ -58,6 +58,7 @@ import {
|
||||
COLOR_PRIMARIES_MAP_INVERSE,
|
||||
findLastIndex,
|
||||
isIso639Dash2LanguageCode,
|
||||
isThenable,
|
||||
last,
|
||||
MATRIX_COEFFICIENTS_MAP_INVERSE,
|
||||
normalizeRotation,
|
||||
@@ -364,7 +365,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
|
||||
while (true) {
|
||||
let slice = this.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const startPos = currentPos;
|
||||
@@ -380,7 +381,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
// Found moov, load it
|
||||
|
||||
let moovSlice = this.reader.requestSlice(slice.filePos, boxInfo.contentSize);
|
||||
if (moovSlice instanceof Promise) moovSlice = await moovSlice;
|
||||
if (isThenable(moovSlice)) moovSlice = await moovSlice;
|
||||
if (!moovSlice) break;
|
||||
|
||||
this.moovSlice = moovSlice;
|
||||
@@ -431,7 +432,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
|
||||
// The last 4 bytes may contain the size of the mfra box at the end of the file
|
||||
let lastWordSlice = this.reader.requestSlice(this.reader.fileSize - 4, 4);
|
||||
if (lastWordSlice instanceof Promise) lastWordSlice = await lastWordSlice;
|
||||
if (isThenable(lastWordSlice)) lastWordSlice = await lastWordSlice;
|
||||
assert(lastWordSlice);
|
||||
|
||||
const lastWord = readU32Be(lastWordSlice);
|
||||
@@ -443,7 +444,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
MIN_BOX_HEADER_SIZE,
|
||||
MAX_BOX_HEADER_SIZE,
|
||||
);
|
||||
if (mfraHeaderSlice instanceof Promise) mfraHeaderSlice = await mfraHeaderSlice;
|
||||
if (isThenable(mfraHeaderSlice)) mfraHeaderSlice = await mfraHeaderSlice;
|
||||
|
||||
if (mfraHeaderSlice) {
|
||||
const boxInfo = readBoxHeader(mfraHeaderSlice);
|
||||
@@ -451,7 +452,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
if (boxInfo && boxInfo.name === 'mfra') {
|
||||
// We found the mfra box, allowing for much better random access. Let's parse it.
|
||||
let mfraSlice = this.reader.requestSlice(mfraHeaderSlice.filePos, boxInfo.contentSize);
|
||||
if (mfraSlice instanceof Promise) mfraSlice = await mfraSlice;
|
||||
if (isThenable(mfraSlice)) mfraSlice = await mfraSlice;
|
||||
|
||||
if (mfraSlice) {
|
||||
this.readContiguousBoxes(mfraSlice);
|
||||
@@ -678,14 +679,14 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
}
|
||||
|
||||
let headerSlice = this.reader.requestSliceRange(startPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
assert(headerSlice);
|
||||
|
||||
const moofBoxInfo = readBoxHeader(headerSlice);
|
||||
assert(moofBoxInfo?.name === 'moof');
|
||||
|
||||
let entireSlice = this.reader.requestSlice(startPos, moofBoxInfo.totalSize);
|
||||
if (entireSlice instanceof Promise) entireSlice = await entireSlice;
|
||||
if (isThenable(entireSlice)) entireSlice = await entireSlice;
|
||||
assert(entireSlice);
|
||||
|
||||
this.traverseBox(entireSlice);
|
||||
@@ -3144,7 +3145,7 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
||||
sampleInfo.sampleOffset,
|
||||
sampleInfo.sampleSize,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) {
|
||||
return null; // Data is outside
|
||||
}
|
||||
@@ -3207,7 +3208,7 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
||||
fragmentSample.byteOffset,
|
||||
fragmentSample.byteSize,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) {
|
||||
return null; // Data is outside
|
||||
}
|
||||
@@ -3321,7 +3322,7 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
||||
|
||||
// Load the header
|
||||
let slice = demuxer.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const boxStartPos = currentPos;
|
||||
@@ -3748,7 +3749,7 @@ const resolveEncryptionAuxInfo = async (
|
||||
}
|
||||
|
||||
let slice = reader.requestSlice(aux.offset, totalSize);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) {
|
||||
throw new Error('Failed to read auxiliary encryption info.');
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { MediaCodec } from '../codec';
|
||||
import { assert, assertNever, textDecoder, textEncoder } from '../misc';
|
||||
import { assert, assertNever, isThenable, textDecoder, textEncoder } from '../misc';
|
||||
import { FileSlice, readBytes, Reader, readF32Be, readF64Be, readU8 } from '../reader';
|
||||
import { Writer } from '../writer';
|
||||
|
||||
@@ -688,7 +688,7 @@ export const searchForNextElementId = async (
|
||||
|
||||
while (until === null || currentPos < until) {
|
||||
let slice = reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const elementHeader = readElementHeader(slice);
|
||||
@@ -716,7 +716,7 @@ export const resync = async (reader: Reader, startPos: number, ids: EBMLId[], un
|
||||
|
||||
while (currentPos < until) {
|
||||
let slice = reader.requestSliceRange(currentPos, 0, Math.min(CHUNK_SIZE, until - currentPos));
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
if (slice.length < MAX_VAR_INT_SIZE) break;
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
COLOR_PRIMARIES_MAP_INVERSE,
|
||||
findLastIndex,
|
||||
isIso639Dash2LanguageCode,
|
||||
isThenable,
|
||||
last,
|
||||
MATRIX_COEFFICIENTS_MAP_INVERSE,
|
||||
normalizeRotation,
|
||||
@@ -334,7 +335,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
// Loop over all top-level elements in the file
|
||||
while (true) {
|
||||
let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const header = readElementHeader(slice);
|
||||
@@ -350,7 +351,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
assertDefinedSize(size);
|
||||
|
||||
let slice = this.reader.requestSlice(dataStartPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
this.readContiguousElements(slice);
|
||||
@@ -433,7 +434,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
|
||||
while (this.currentSegment.elementEndPos === null || currentPos < this.currentSegment.elementEndPos) {
|
||||
let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const elementStartPos = currentPos;
|
||||
@@ -468,7 +469,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
assertDefinedSize(size);
|
||||
|
||||
let slice = this.reader.requestSlice(dataStartPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (slice) {
|
||||
this.readContiguousElements(slice);
|
||||
@@ -484,7 +485,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
assertDefinedSize(size);
|
||||
|
||||
let slice = this.reader.requestSlice(dataStartPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (slice) {
|
||||
this.readContiguousElements(slice);
|
||||
@@ -519,7 +520,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
MIN_HEADER_SIZE,
|
||||
MAX_HEADER_SIZE,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) continue;
|
||||
|
||||
const header = readElementHeader(slice);
|
||||
@@ -533,7 +534,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
this.currentSegment[target.flag] = true;
|
||||
|
||||
let dataSlice = this.reader.requestSlice(slice.filePos, size);
|
||||
if (dataSlice instanceof Promise) dataSlice = await dataSlice;
|
||||
if (isThenable(dataSlice)) dataSlice = await dataSlice;
|
||||
if (!dataSlice) continue;
|
||||
|
||||
this.readContiguousElements(dataSlice);
|
||||
@@ -608,7 +609,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
}
|
||||
|
||||
let headerSlice = this.reader.requestSliceRange(startPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
assert(headerSlice);
|
||||
|
||||
const elementStartPos = startPos;
|
||||
@@ -637,7 +638,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
|
||||
// Load the entire cluster
|
||||
let dataSlice = this.reader.requestSlice(dataStartPos, size);
|
||||
if (dataSlice instanceof Promise) dataSlice = await dataSlice;
|
||||
if (isThenable(dataSlice)) dataSlice = await dataSlice;
|
||||
|
||||
const cluster: Cluster = {
|
||||
segment,
|
||||
@@ -894,7 +895,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
MIN_HEADER_SIZE,
|
||||
MAX_HEADER_SIZE,
|
||||
);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) continue;
|
||||
|
||||
const header = readElementHeader(slice);
|
||||
@@ -907,7 +908,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
this.currentSegment = segment;
|
||||
|
||||
let dataSlice = this.reader.requestSlice(slice.filePos, size);
|
||||
if (dataSlice instanceof Promise) dataSlice = await dataSlice;
|
||||
if (isThenable(dataSlice)) dataSlice = await dataSlice;
|
||||
if (dataSlice) {
|
||||
this.readContiguousElements(dataSlice);
|
||||
}
|
||||
@@ -2347,7 +2348,7 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
||||
|
||||
// Load the header
|
||||
let slice = demuxer.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const elementStartPos = currentPos;
|
||||
@@ -2418,7 +2419,7 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
||||
// the first segment.
|
||||
|
||||
let slice = demuxer.reader.requestSliceRange(endPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const elementId = readElementId(slice);
|
||||
|
||||
+3
-2
@@ -28,6 +28,7 @@ import {
|
||||
clamp,
|
||||
clearIntervalUnthrottled,
|
||||
floorToDivisor,
|
||||
isThenable,
|
||||
last,
|
||||
missingWebCodecsClassMessage,
|
||||
promiseWithResolvers,
|
||||
@@ -426,7 +427,7 @@ class VideoEncoderWrapper {
|
||||
// Apply the user-defined process function, if any
|
||||
if (config.transform?.process) {
|
||||
let processed = config.transform.process(videoSample);
|
||||
if (processed instanceof Promise) {
|
||||
if (isThenable(processed)) {
|
||||
processed = await processed;
|
||||
}
|
||||
|
||||
@@ -1937,7 +1938,7 @@ class AudioEncoderWrapper {
|
||||
if (config.transform?.process) {
|
||||
try {
|
||||
let processed = config.transform.process(audioSample);
|
||||
if (processed instanceof Promise) {
|
||||
if (isThenable(processed)) {
|
||||
processed = await processed;
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -738,6 +738,20 @@ export const missingWebCodecsClassMessage = (className: string) => {
|
||||
*/
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
|
||||
const NativePromiseConstructor = /* #__PURE__ */ (async () => {})().constructor as PromiseConstructor;
|
||||
|
||||
/**
|
||||
* Needed to properly deal with custom Promise implementations and because this is closer to how the JS spec does it.
|
||||
*/
|
||||
export const isThenable = <T>(value: MaybePromise<T>): value is Promise<T> => {
|
||||
if (value instanceof NativePromiseConstructor || value instanceof Promise) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fall back to a crude duck typing check
|
||||
return typeof (value as PromiseLike<T> | null | undefined)?.then === 'function';
|
||||
};
|
||||
|
||||
/** Acts like `??` except the condition is -1 and not null/undefined. */
|
||||
export const coalesceIndex = (a: number, b: number) => {
|
||||
return a !== -1 ? a : b;
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
AsyncMutex,
|
||||
binarySearchExact,
|
||||
binarySearchLessOrEqual,
|
||||
isThenable,
|
||||
toDataView,
|
||||
UNDETERMINED_LANGUAGE,
|
||||
} from '../misc';
|
||||
@@ -102,7 +103,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
// Let's skip all ID3v2 tags at the start of the file
|
||||
while (true) {
|
||||
let slice = this.reader.requestSlice(this.lastLoadedPos, ID3_V2_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
this.lastSampleLoaded = true;
|
||||
@@ -136,7 +137,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
const xingOffset = getXingOffset(header.mpegVersionId, header.channel);
|
||||
|
||||
let slice = this.reader.requestSlice(result.startPos + xingOffset, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (slice) {
|
||||
const word = readU32Be(slice);
|
||||
const isXing = word === XING || word === INFO;
|
||||
@@ -151,7 +152,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
|
||||
if (!this.xingData) {
|
||||
let xingDataSlice = this.reader.requestSlice(result.startPos + xingOffset + 4, 12);
|
||||
if (xingDataSlice instanceof Promise) xingDataSlice = await xingDataSlice;
|
||||
if (isThenable(xingDataSlice)) xingDataSlice = await xingDataSlice;
|
||||
if (xingDataSlice) {
|
||||
const xingData = readBytes(xingDataSlice, 12);
|
||||
const view = toDataView(xingData);
|
||||
@@ -216,7 +217,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
|
||||
while (true) {
|
||||
let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
if (!headerSlice) break;
|
||||
|
||||
const id3V2Header = readId3V2Header(headerSlice);
|
||||
@@ -227,7 +228,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
id3V2HeaderFound = true;
|
||||
|
||||
let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
|
||||
if (contentSlice instanceof Promise) contentSlice = await contentSlice;
|
||||
if (isThenable(contentSlice)) contentSlice = await contentSlice;
|
||||
if (!contentSlice) break;
|
||||
|
||||
parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
|
||||
@@ -238,7 +239,7 @@ export class Mp3Demuxer extends Demuxer {
|
||||
if (!id3V2HeaderFound && this.reader.fileSize !== null && this.reader.fileSize >= ID3_V1_TAG_SIZE) {
|
||||
// Try reading an ID3v1 tag at the end of the file
|
||||
let slice = this.reader.requestSlice(this.reader.fileSize - ID3_V1_TAG_SIZE, ID3_V1_TAG_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
assert(slice);
|
||||
|
||||
const tag = readAscii(slice, 3);
|
||||
@@ -388,7 +389,7 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
|
||||
data = PLACEHOLDER_DATA;
|
||||
} else {
|
||||
let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null; // Data didn't fit into the rest of the file
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { MP3_FRAME_HEADER_SIZE, getMp3ChannelCount, Mp3FrameHeader, readMp3FrameHeader } from '../../shared/mp3-misc';
|
||||
import { isThenable } from '../misc';
|
||||
import { Reader, readU32Be } from '../reader';
|
||||
|
||||
export const readNextMp3FrameHeader = async (
|
||||
@@ -27,7 +28,7 @@ export const readNextMp3FrameHeader = async (
|
||||
: CHUNK_SIZE;
|
||||
|
||||
let slice = reader.requestSliceRange(currentPos, MP3_FRAME_HEADER_SIZE, maxLength);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice || slice.length < MP3_FRAME_HEADER_SIZE) break;
|
||||
|
||||
while (slice.remainingLength >= MP3_FRAME_HEADER_SIZE) {
|
||||
|
||||
@@ -63,6 +63,7 @@ import {
|
||||
COLOR_PRIMARIES_MAP_INVERSE,
|
||||
findLastIndex,
|
||||
floorToMultiple,
|
||||
isThenable,
|
||||
last,
|
||||
MATRIX_COEFFICIENTS_MAP_INVERSE,
|
||||
readExpGolomb,
|
||||
@@ -190,7 +191,7 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
return this.metadataPromise ??= (async () => {
|
||||
const lengthToCheck = TS_PACKET_SIZE + 16 + 1;
|
||||
let startingSlice = this.reader.requestSlice(0, lengthToCheck);
|
||||
if (startingSlice instanceof Promise) startingSlice = await startingSlice;
|
||||
if (isThenable(startingSlice)) startingSlice = await startingSlice;
|
||||
assert(startingSlice);
|
||||
|
||||
const startingBytes = readBytes(startingSlice, lengthToCheck);
|
||||
@@ -951,7 +952,7 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
|
||||
async readPacketHeader(pos: number): Promise<TsPacketHeader | null> {
|
||||
let slice = this.reader.requestSlice(pos, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null;
|
||||
@@ -987,7 +988,7 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
async readPacket(pos: number): Promise<TsPacket | null> {
|
||||
// Code in here is duplicated from readPacketHeader for performance reasons
|
||||
let slice = this.reader.requestSlice(pos, TS_PACKET_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null;
|
||||
@@ -2099,7 +2100,7 @@ class PacketReadingContext {
|
||||
|
||||
while (true) {
|
||||
let remaining = this.ensureBuffered(CHUNK_SIZE);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining === 0) {
|
||||
break;
|
||||
@@ -2253,7 +2254,7 @@ class PacketReadingContext {
|
||||
|
||||
while (true) {
|
||||
let remaining = this.ensureBuffered(CHUNK_SIZE);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
const startPos = this.currentPos;
|
||||
|
||||
@@ -2269,7 +2270,7 @@ class PacketReadingContext {
|
||||
const possibleHeaderStartPos = this.currentPos;
|
||||
|
||||
let remaining = this.ensureBuffered(MAX_ADTS_FRAME_HEADER_SIZE);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < MAX_ADTS_FRAME_HEADER_SIZE) {
|
||||
return;
|
||||
@@ -2282,7 +2283,7 @@ class PacketReadingContext {
|
||||
this.seekTo(possibleHeaderStartPos);
|
||||
|
||||
let remaining = this.ensureBuffered(header.frameLength);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
return this.supplyPacket(
|
||||
remaining,
|
||||
@@ -2300,7 +2301,7 @@ class PacketReadingContext {
|
||||
const possibleHeaderStartPos = this.currentPos;
|
||||
|
||||
let remaining = this.ensureBuffered(MP3_FRAME_HEADER_SIZE);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < MP3_FRAME_HEADER_SIZE) {
|
||||
return;
|
||||
@@ -2314,7 +2315,7 @@ class PacketReadingContext {
|
||||
this.seekTo(possibleHeaderStartPos);
|
||||
|
||||
let remaining = this.ensureBuffered(result.header.totalSize);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
const duration = result.header.audioSamplesInFrame * TIMESCALE
|
||||
/ elementaryStream.info.sampleRate;
|
||||
@@ -2332,7 +2333,7 @@ class PacketReadingContext {
|
||||
|
||||
// Need at least 5 bytes for sync word + CRC + fscod/frmsizecod
|
||||
let remaining = this.ensureBuffered(5);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < 5) {
|
||||
return;
|
||||
@@ -2361,7 +2362,7 @@ class PacketReadingContext {
|
||||
this.seekTo(possibleSyncPos);
|
||||
|
||||
remaining = this.ensureBuffered(frameSize);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
const duration = Math.round(
|
||||
AC3_SAMPLES_PER_FRAME * TIMESCALE / elementaryStream.info.sampleRate,
|
||||
@@ -2377,7 +2378,7 @@ class PacketReadingContext {
|
||||
|
||||
// Need at least 5 bytes for E-AC-3 header parsing (sync word + frmsiz + fscod/numblkscod)
|
||||
let remaining = this.ensureBuffered(5);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < 5) {
|
||||
return;
|
||||
@@ -2399,7 +2400,7 @@ class PacketReadingContext {
|
||||
this.seekTo(possibleSyncPos);
|
||||
|
||||
remaining = this.ensureBuffered(frameSize);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
// Duration = numblks * 256 samples per block
|
||||
const samplesPerFrame = numblks * 256;
|
||||
@@ -2416,7 +2417,7 @@ class PacketReadingContext {
|
||||
const possibleSyncPos = this.currentPos;
|
||||
|
||||
let remaining = this.ensureBuffered(DTS_CORE_FRAME_HEADER_SIZE);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < DTS_CORE_FRAME_HEADER_SIZE) {
|
||||
return;
|
||||
@@ -2438,7 +2439,7 @@ class PacketReadingContext {
|
||||
|
||||
const headerBound = Math.min(leadingExss.frameSize, DTS_EXSS_MAX_HEADER_SIZE);
|
||||
let remaining = this.ensureBuffered(headerBound);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
leadingExss = parseDtsExssHeader(this.readBytes(remaining)) ?? leadingExss;
|
||||
}
|
||||
@@ -2456,7 +2457,7 @@ class PacketReadingContext {
|
||||
|
||||
const neededBytes = nextSubstreamPos + DTS_EXSS_HEADER_PREFIX_SIZE;
|
||||
let remaining = this.ensureBuffered(neededBytes);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
if (remaining < neededBytes) {
|
||||
break;
|
||||
@@ -2484,7 +2485,7 @@ class PacketReadingContext {
|
||||
this.seekTo(possibleSyncPos);
|
||||
|
||||
remaining = this.ensureBuffered(frameSize);
|
||||
if (remaining instanceof Promise) remaining = await remaining;
|
||||
if (isThenable(remaining)) remaining = await remaining;
|
||||
|
||||
const duration = Math.round(
|
||||
sampleCount * TIMESCALE / elementaryStream.info.sampleRate,
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
AsyncMutex,
|
||||
binarySearchLessOrEqual,
|
||||
findLast,
|
||||
isThenable,
|
||||
last,
|
||||
roundIfAlmostInteger,
|
||||
toDataView,
|
||||
@@ -72,7 +73,7 @@ export class OggDemuxer extends Demuxer {
|
||||
|
||||
while (true) {
|
||||
let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const page = readPageHeader(slice);
|
||||
@@ -274,7 +275,7 @@ export class OggDemuxer extends Demuxer {
|
||||
while (true) {
|
||||
// Load the entire page data
|
||||
let pageSlice = this.reader.requestSlice(currentPage.dataStartPos, currentPage.dataSize);
|
||||
if (pageSlice instanceof Promise) pageSlice = await pageSlice;
|
||||
if (isThenable(pageSlice)) pageSlice = await pageSlice;
|
||||
assert(pageSlice);
|
||||
const pageData = readBytes(pageSlice, currentPage.dataSize);
|
||||
|
||||
@@ -299,7 +300,7 @@ export class OggDemuxer extends Demuxer {
|
||||
let currentPos = currentPage.headerStartPos + currentPage.totalSize;
|
||||
while (true) {
|
||||
let headerSlice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
if (!headerSlice) {
|
||||
return null;
|
||||
}
|
||||
@@ -358,7 +359,7 @@ export class OggDemuxer extends Demuxer {
|
||||
let currentPos = lastPacket.endPage.headerStartPos + lastPacket.endPage.totalSize;
|
||||
while (true) {
|
||||
let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) {
|
||||
return null;
|
||||
}
|
||||
@@ -658,7 +659,7 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
||||
);
|
||||
|
||||
let searchSlice = this.demuxer.reader.requestSlice(searchStartPos, until - searchStartPos);
|
||||
if (searchSlice instanceof Promise) searchSlice = await searchSlice;
|
||||
if (isThenable(searchSlice)) searchSlice = await searchSlice;
|
||||
assert(searchSlice);
|
||||
|
||||
const found = findNextPageHeader(searchSlice, until);
|
||||
@@ -672,7 +673,7 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
||||
MIN_PAGE_HEADER_SIZE,
|
||||
MAX_PAGE_HEADER_SIZE,
|
||||
);
|
||||
if (headerSlice instanceof Promise) headerSlice = await headerSlice;
|
||||
if (isThenable(headerSlice)) headerSlice = await headerSlice;
|
||||
assert(headerSlice);
|
||||
|
||||
const page = readPageHeader(headerSlice);
|
||||
@@ -685,7 +686,7 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
||||
pageValid = true;
|
||||
} else {
|
||||
let pageSlice = this.demuxer.reader.requestSlice(page.headerStartPos, page.totalSize);
|
||||
if (pageSlice instanceof Promise) pageSlice = await pageSlice;
|
||||
if (isThenable(pageSlice)) pageSlice = await pageSlice;
|
||||
assert(pageSlice);
|
||||
|
||||
// Validate the page by checking checksum
|
||||
@@ -759,7 +760,7 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
||||
|
||||
const nextPos = currentPage.headerStartPos + currentPage.totalSize;
|
||||
let slice = this.demuxer.reader.requestSliceRange(nextPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
assert(slice);
|
||||
|
||||
const nextPage = readPageHeader(slice);
|
||||
|
||||
+13
-4
@@ -6,7 +6,16 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { assert, AsyncMutex, EventEmitter, isIso639Dash2LanguageCode, MaybePromise, Rotation, toArray } from './misc';
|
||||
import {
|
||||
assert,
|
||||
AsyncMutex,
|
||||
EventEmitter,
|
||||
isIso639Dash2LanguageCode,
|
||||
isThenable,
|
||||
MaybePromise,
|
||||
Rotation,
|
||||
toArray,
|
||||
} from './misc';
|
||||
import { MetadataTags, TrackDisposition, validateMetadataTags, validateTrackDisposition } from './metadata';
|
||||
import { Muxer } from './muxer';
|
||||
import { OutputFormat } from './output-format';
|
||||
@@ -451,7 +460,7 @@ export class Output<
|
||||
}
|
||||
|
||||
const rootTargetResult = this._getRootTarget();
|
||||
if (rootTargetResult instanceof Promise) {
|
||||
if (isThenable(rootTargetResult)) {
|
||||
throw new TypeError(errorMessage);
|
||||
}
|
||||
|
||||
@@ -516,7 +525,7 @@ export class Output<
|
||||
return result;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(handleResult);
|
||||
} else {
|
||||
return handleResult(result);
|
||||
@@ -604,7 +613,7 @@ export class Output<
|
||||
return target;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return this._rootTargetPromise = result.then(handleResult);
|
||||
} else {
|
||||
return handleResult(result);
|
||||
|
||||
+4
-4
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { InputDisposedError } from './input';
|
||||
import { assert, clamp, getUint24, MaybePromise, textDecoder, toDataView } from './misc';
|
||||
import { assert, clamp, getUint24, isThenable, MaybePromise, textDecoder, toDataView } from './misc';
|
||||
import { DEFAULT_MAX_READ_POSITION, DEFAULT_MIN_READ_POSITION, Source } from './source';
|
||||
|
||||
export class Reader {
|
||||
@@ -47,7 +47,7 @@ export class Reader {
|
||||
const end = start + length;
|
||||
const result = this.source._read(start, end, DEFAULT_MIN_READ_POSITION, DEFAULT_MAX_READ_POSITION);
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then((x) => {
|
||||
if (!x) {
|
||||
return null;
|
||||
@@ -95,7 +95,7 @@ export class Reader {
|
||||
);
|
||||
};
|
||||
|
||||
if (promisedAttempt instanceof Promise) {
|
||||
if (isThenable(promisedAttempt)) {
|
||||
return promisedAttempt.then(handleAttempt);
|
||||
} else {
|
||||
return handleAttempt(promisedAttempt);
|
||||
@@ -121,7 +121,7 @@ export class Reader {
|
||||
}
|
||||
|
||||
let slice = this.requestSliceRange(currentSize, 0, CHUNK_SIZE);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice || slice.length === 0) {
|
||||
break;
|
||||
|
||||
+4
-3
@@ -11,6 +11,7 @@ import {
|
||||
clamp,
|
||||
COLOR_PRIMARIES_MAP,
|
||||
isAllowSharedBufferSource,
|
||||
isThenable,
|
||||
MATRIX_COEFFICIENTS_MAP,
|
||||
Rotation,
|
||||
SECOND_TO_MICROSECOND_FACTOR,
|
||||
@@ -864,7 +865,7 @@ export class VideoSample implements Disposable {
|
||||
|
||||
if (this._data instanceof VideoSampleResource) {
|
||||
let result = this._data.getDataPlanes();
|
||||
if (result instanceof Promise) result = await result;
|
||||
if (isThenable(result)) result = await result;
|
||||
|
||||
if (
|
||||
!Array.isArray(result)
|
||||
@@ -1022,7 +1023,7 @@ export class VideoSample implements Disposable {
|
||||
}
|
||||
|
||||
const planes = this._data.getDataPlanes();
|
||||
if (planes instanceof Promise) {
|
||||
if (isThenable(planes)) {
|
||||
throw new Error(
|
||||
'Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if getDataPlanes() returns'
|
||||
+ ' a promise.',
|
||||
@@ -1586,7 +1587,7 @@ export class VideoSample implements Disposable {
|
||||
// Description's finalized; let's see if a registered transformer wants to handle it
|
||||
for (const transformer of registeredVideoSampleTransformers) {
|
||||
let result = transformer(this, description);
|
||||
if (result instanceof Promise) result = await result;
|
||||
if (isThenable(result)) result = await result;
|
||||
|
||||
if (result !== null) {
|
||||
return result;
|
||||
|
||||
+8
-7
@@ -14,6 +14,7 @@ import {
|
||||
closedIntervalsOverlap,
|
||||
FilePath,
|
||||
isNumber,
|
||||
isThenable,
|
||||
isWebKit,
|
||||
MaybePromise,
|
||||
mergeRequestInit,
|
||||
@@ -328,7 +329,7 @@ export abstract class PathedSource extends Source {
|
||||
return ref;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(handle);
|
||||
} else {
|
||||
return handle(result);
|
||||
@@ -387,7 +388,7 @@ export class CustomPathedSource extends PathedSource {
|
||||
return ref;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
this._rootRequest = result.then(handle);
|
||||
} else {
|
||||
handle(result);
|
||||
@@ -894,7 +895,7 @@ export class UrlSource extends PathedSource {
|
||||
return result;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(processResult);
|
||||
} else {
|
||||
return processResult(result);
|
||||
@@ -1198,7 +1199,7 @@ export class UrlSource extends PathedSource {
|
||||
for (const slice of uniqueSlices) {
|
||||
const result = backing._read(slice.start, slice.start + slice.bytes.length);
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
result.then((readResult) => {
|
||||
if (readResult) {
|
||||
// The backing's cache is empty at this point, so the read is guaranteed to produce
|
||||
@@ -1459,7 +1460,7 @@ export class CustomSource extends Source {
|
||||
|
||||
const result = this._options.getSize();
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then((size) => {
|
||||
if (!Number.isInteger(size) || size < 0) {
|
||||
throw new TypeError('options.getSize must return or resolve to a non-negative integer.');
|
||||
@@ -1485,7 +1486,7 @@ export class CustomSource extends Source {
|
||||
const originalTargetPos = worker.targetPos;
|
||||
|
||||
let data = this._options.read(worker.currentPos, originalTargetPos);
|
||||
if (data instanceof Promise) data = await data;
|
||||
if (isThenable(data)) data = await data;
|
||||
|
||||
if (worker.aborted) {
|
||||
break;
|
||||
@@ -2706,7 +2707,7 @@ export class RangedSource extends Source {
|
||||
return result;
|
||||
};
|
||||
|
||||
if (result instanceof Promise) {
|
||||
if (isThenable(result)) {
|
||||
return result.then(processResult);
|
||||
} else {
|
||||
return processResult(result);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Input } from '../input';
|
||||
import { InputAudioTrackBacking } from '../input-track';
|
||||
import { PacketRetrievalOptions } from '../media-sink';
|
||||
import { DEFAULT_TRACK_DISPOSITION, MetadataTags } from '../metadata';
|
||||
import { assert, UNDETERMINED_LANGUAGE } from '../misc';
|
||||
import { assert, isThenable, UNDETERMINED_LANGUAGE } from '../misc';
|
||||
import { EncodedPacket, PLACEHOLDER_DATA } from '../packet';
|
||||
import { readAscii, readBytes, Reader, readU16, readU32, readU64 } from '../reader';
|
||||
import { ID3_V2_HEADER_SIZE, parseId3V2Tag, readId3V2Header } from '../id3';
|
||||
@@ -52,7 +52,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
async readMetadata() {
|
||||
return this.metadataPromise ??= (async () => {
|
||||
let slice = this.reader.requestSlice(0, 12);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
assert(slice);
|
||||
|
||||
const riffType = readAscii(slice, 4);
|
||||
@@ -77,7 +77,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
|
||||
while (totalFileSize === null || currentPos < totalFileSize) {
|
||||
let slice = this.reader.requestSlice(currentPos, 8);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) break;
|
||||
|
||||
const chunkId = readAscii(slice, 4);
|
||||
@@ -103,7 +103,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
// File and data chunk sizes are defined in here instead
|
||||
|
||||
let ds64Slice = this.reader.requestSlice(startPos, chunkSize);
|
||||
if (ds64Slice instanceof Promise) ds64Slice = await ds64Slice;
|
||||
if (isThenable(ds64Slice)) ds64Slice = await ds64Slice;
|
||||
if (!ds64Slice) break;
|
||||
|
||||
const riffChunkSize = readU64(ds64Slice, littleEndian);
|
||||
@@ -136,7 +136,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
|
||||
private async parseFmtChunk(startPos: number, size: number, littleEndian: boolean) {
|
||||
let slice = this.reader.requestSlice(startPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return; // File too short
|
||||
|
||||
let formatTag = readU16(slice, littleEndian);
|
||||
@@ -206,7 +206,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
|
||||
private async parseListChunk(startPos: number, size: number, littleEndian: boolean) {
|
||||
let slice = this.reader.requestSlice(startPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return; // File too short
|
||||
|
||||
const infoType = readAscii(slice, 4);
|
||||
@@ -303,7 +303,7 @@ export class WaveDemuxer extends Demuxer {
|
||||
private async parseId3Chunk(startPos: number, size: number) {
|
||||
// Parse ID3 tag embedded in WAV file (non-default, but used a lot in practice anyway)
|
||||
let slice = this.reader.requestSlice(startPos, size);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
if (!slice) return; // File too short
|
||||
|
||||
const id3V2Header = readId3V2Header(slice);
|
||||
@@ -489,7 +489,7 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
||||
// requested slice actually exists.
|
||||
|
||||
let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
|
||||
if (!slice) {
|
||||
return null;
|
||||
@@ -501,7 +501,7 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
||||
data = PLACEHOLDER_DATA;
|
||||
} else {
|
||||
let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (isThenable(slice)) slice = await slice;
|
||||
assert(slice);
|
||||
|
||||
data = readBytes(slice, sizeInBytes);
|
||||
|
||||
Reference in New Issue
Block a user