diff --git a/dev/demux.html b/dev/demux.html
index 8391087..3bfb4db 100644
--- a/dev/demux.html
+++ b/dev/demux.html
@@ -22,7 +22,7 @@
for await (const packet of sink.packets()) {
console.log(packet);
- if (packet.timestamp > 135) break;
+ //if (packet.timestamp > 135) break;
}
/*
diff --git a/package-lock.json b/package-lock.json
index ed9eeb2..f07e527 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "mediabunny",
- "version": "1.9.2",
+ "version": "1.9.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mediabunny",
- "version": "1.9.2",
+ "version": "1.9.3",
"license": "MPL-2.0",
"workspaces": [
"packages/*"
@@ -5900,9 +5900,9 @@
}
},
"node_modules/mediabunny": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.9.1.tgz",
- "integrity": "sha512-DghqcYW2s8LsZ9kErFeZdm6308BEABYs8SkY1z3Y7v3LWgPNvBmkXk7Yt+EKcpEGEFjGgDGoTapOjrrrNh7dQA==",
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.9.2.tgz",
+ "integrity": "sha512-U3RKZVvU2O7vXVtPf6Q+4XNulkV6fdVOVYMm7V2YTr6PqyqrvUl1eUCTtcrmQESgRi9sFZeXkUR8ln5TS48M2g==",
"license": "MPL-2.0",
"peer": true,
"workspaces": [
@@ -9017,7 +9017,7 @@
},
"packages/mp3-encoder": {
"name": "@mediabunny/mp3-encoder",
- "version": "1.9.2",
+ "version": "1.9.3",
"license": "MPL-2.0",
"devDependencies": {
"@types/emscripten": "^1.40.1"
diff --git a/package.json b/package.json
index b49df22..d0541fb 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "mediabunny",
"author": "Vanilagy",
- "version": "1.9.2",
+ "version": "1.9.3",
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
"type": "module",
"workspaces": [
diff --git a/packages/mp3-encoder/package.json b/packages/mp3-encoder/package.json
index f2de19e..883ca3c 100644
--- a/packages/mp3-encoder/package.json
+++ b/packages/mp3-encoder/package.json
@@ -1,7 +1,7 @@
{
"name": "@mediabunny/mp3-encoder",
"author": "Vanilagy",
- "version": "1.9.2",
+ "version": "1.9.3",
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts
index 0f6c7cb..9a88c43 100644
--- a/src/isobmff/isobmff-demuxer.ts
+++ b/src/isobmff/isobmff-demuxer.ts
@@ -257,6 +257,9 @@ export class IsobmffDemuxer extends Demuxer {
);
const startPos = this.metadataReader.pos;
const boxInfo = this.metadataReader.readBoxHeader();
+ if (!boxInfo) {
+ break;
+ }
if (boxInfo.name === 'ftyp') {
const majorBrand = this.metadataReader.readAscii(4);
@@ -298,7 +301,7 @@ export class IsobmffDemuxer extends Demuxer {
this.metadataReader.pos = potentialMfraPos;
const boxInfo = this.metadataReader.readBoxHeader();
- if (boxInfo.name === 'mfra') {
+ if (boxInfo && boxInfo.name === 'mfra') {
// We found the mfra box, allowing for much better random access. Let's parse it.
await this.metadataReader.reader.loadRange(
@@ -462,7 +465,7 @@ export class IsobmffDemuxer extends Demuxer {
);
const moofBoxInfo = this.metadataReader.readBoxHeader();
- assert(moofBoxInfo.name === 'moof');
+ assert(moofBoxInfo?.name === 'moof');
const contentStart = this.metadataReader.pos;
await this.metadataReader.reader.loadRange(contentStart, contentStart + moofBoxInfo.contentSize);
@@ -508,7 +511,7 @@ export class IsobmffDemuxer extends Demuxer {
let nextFragmentIsFirstFragment = this.metadataReader.pos === 0;
- while (this.metadataReader.pos < startPos) {
+ while (this.metadataReader.pos <= startPos - MIN_BOX_HEADER_SIZE) {
if (currentFragment?.nextFragment) {
currentFragment = currentFragment.nextFragment;
this.metadataReader.pos = currentFragment.moofOffset + currentFragment.moofSize;
@@ -519,6 +522,9 @@ export class IsobmffDemuxer extends Demuxer {
);
const startPos = this.metadataReader.pos;
const boxInfo = this.metadataReader.readBoxHeader();
+ if (!boxInfo) {
+ break;
+ }
if (boxInfo.name === 'moof') {
const index = binarySearchExact(this.fragments, startPos, x => x.moofOffset);
@@ -568,13 +574,21 @@ export class IsobmffDemuxer extends Demuxer {
const startIndex = this.metadataReader.pos;
while (this.metadataReader.pos - startIndex <= totalSize - MIN_BOX_HEADER_SIZE) {
- this.traverseBox();
+ const foundBox = this.traverseBox();
+
+ if (!foundBox) {
+ break;
+ }
}
}
traverseBox() {
const startPos = this.metadataReader.pos;
const boxInfo = this.metadataReader.readBoxHeader();
+ if (!boxInfo) {
+ return false;
+ }
+
const boxEndPos = startPos + boxInfo.totalSize;
switch (boxInfo.name) {
@@ -825,6 +839,10 @@ export class IsobmffDemuxer extends Demuxer {
for (let i = 0; i < entries; i++) {
const startPos = this.metadataReader.pos;
const sampleBoxInfo = this.metadataReader.readBoxHeader();
+ if (!sampleBoxInfo) {
+ break;
+ }
+
const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();
if (track.info.type === 'video') {
@@ -1904,6 +1922,7 @@ export class IsobmffDemuxer extends Demuxer {
}
this.metadataReader.pos = boxEndPos;
+ return true;
}
}
@@ -2324,8 +2343,12 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
/** Looks for a packet in the fragments while trying to load as few fragments as possible to retrieve it. */
private async performFragmentedLookup(
+ // This function returns the best-matching sample that is currently loaded. Based on this information, we know
+ // which fragments we need to load to find the actual match.
getBestMatch: () => { fragmentIndex: number; sampleIndex: number; correctSampleFound: boolean },
+ // The timestamp with which we can search the lookup table
searchTimestamp: number,
+ // The timestamp for which we know the correct sample will not come after it
latestTimestamp: number,
options: PacketRetrievalOptions,
): Promise {
@@ -2397,6 +2420,9 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
await metadataReader.reader.loadRange(metadataReader.pos, metadataReader.pos + MAX_BOX_HEADER_SIZE);
const startPos = metadataReader.pos;
const boxInfo = metadataReader.readBoxHeader();
+ if (!boxInfo) {
+ break;
+ }
if (boxInfo.name === 'moof') {
const index = binarySearchExact(demuxer.fragments, startPos, x => x.moofOffset);
diff --git a/src/isobmff/isobmff-reader.ts b/src/isobmff/isobmff-reader.ts
index 425059b..bbcd541 100644
--- a/src/isobmff/isobmff-reader.ts
+++ b/src/isobmff/isobmff-reader.ts
@@ -132,6 +132,11 @@ export class IsobmffReader {
headerSize = 16;
}
- return { name, totalSize, headerSize, contentSize: totalSize - headerSize };
+ const contentSize = totalSize - headerSize;
+ if (contentSize < 0) {
+ return null; // Hardly a box is it
+ }
+
+ return { name, totalSize, headerSize, contentSize };
}
}
diff --git a/src/matroska/matroska-demuxer.ts b/src/matroska/matroska-demuxer.ts
index bb6f7ae..46632cd 100644
--- a/src/matroska/matroska-demuxer.ts
+++ b/src/matroska/matroska-demuxer.ts
@@ -760,6 +760,7 @@ export class MatroskaDemuxer extends Demuxer {
while (reader.pos - startIndex <= totalSize - MIN_HEADER_SIZE) {
const foundElement = this.traverseElement(reader);
+
if (!foundElement) {
break;
}