Merge main into release for tag v1.24.2

This commit is contained in:
github-actions[bot]
2025-10-21 14:30:15 +00:00
6 changed files with 57 additions and 47 deletions
+2 -2
View File
@@ -200,7 +200,7 @@ npm run lint # ESLint
npm run docs:generate # Generates API docs npm run docs:generate # Generates API docs
npm run docs:dev # Start docs development server npm run docs:dev # Start docs development server
npm run dev # Start examples development server npm run dev # Start examples development server, will run at http://localhost:5173/examples/[name]/
npm run docs:build # Build docs and examples npm run docs:build # Build docs and examples
``` ```
+6 -6
View File
@@ -1,12 +1,12 @@
{ {
"name": "mediabunny", "name": "mediabunny",
"version": "1.24.1", "version": "1.24.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mediabunny", "name": "mediabunny",
"version": "1.24.1", "version": "1.24.2",
"license": "MPL-2.0", "license": "MPL-2.0",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
@@ -7749,9 +7749,9 @@
} }
}, },
"node_modules/mediabunny": { "node_modules/mediabunny": {
"version": "1.24.0", "version": "1.24.1",
"resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.24.0.tgz", "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.24.1.tgz",
"integrity": "sha512-9fQfAYlnuVSHMfbJtKK0pAgDlfwGDoyLQZ7gbOCug9jHPfjdi0XYQwvi/kaOFFMD70ouPkXzvKRc3AMPwkSK6Q==", "integrity": "sha512-k7ki4KGgFE7F4XaUn0sDpPzdB8Hgms5Hq3QonzXyVSMh75oRuyjNhuAWJtAAlzs45gUerlIHZCvHd6/5H7duow==",
"license": "MPL-2.0", "license": "MPL-2.0",
"peer": true, "peer": true,
"workspaces": [ "workspaces": [
@@ -12242,7 +12242,7 @@
}, },
"packages/mp3-encoder": { "packages/mp3-encoder": {
"name": "@mediabunny/mp3-encoder", "name": "@mediabunny/mp3-encoder",
"version": "1.24.1", "version": "1.24.2",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@types/emscripten": "^1.40.1" "@types/emscripten": "^1.40.1"
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "mediabunny", "name": "mediabunny",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.24.1", "version": "1.24.2",
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.", "description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
"type": "module", "type": "module",
"workspaces": [ "workspaces": [
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@mediabunny/mp3-encoder", "name": "@mediabunny/mp3-encoder",
"author": "Vanilagy", "author": "Vanilagy",
"version": "1.24.1", "version": "1.24.2",
"description": "MP3 encoder extension for Mediabunny, based on LAME.", "description": "MP3 encoder extension for Mediabunny, based on LAME.",
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs", "main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs", "module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
+5
View File
@@ -70,6 +70,11 @@ export const readDataBox = (slice: FileSlice) => {
return null; return null;
} }
if (slice.remainingLength < 8) {
// Box is too small
return null;
}
const typeIndicator = readU32Be(slice); const typeIndicator = readU32Be(slice);
slice.skip(4); // Locale indicator slice.skip(4); // Locale indicator
const data = readBytes(slice, header.contentSize - 8); const data = readBytes(slice, header.contentSize - 8);
+42 -37
View File
@@ -637,7 +637,10 @@ export class MatroskaDemuxer extends Demuxer {
this.currentCluster = cluster; this.currentCluster = cluster;
if (dataSlice) { if (dataSlice) {
this.readContiguousElements(dataSlice); // Read the children of the cluster, stopping early at level 0 or 1 EBML elements. We do this because some
// clusters have incorrect sizes that are too large
const endPos = this.readContiguousElements(dataSlice, LEVEL_0_AND_1_EBML_IDS);
cluster.elementEndPos = endPos;
} }
for (const [, trackData] of cluster.trackData) { for (const [, trackData] of cluster.trackData) {
@@ -913,24 +916,31 @@ export class MatroskaDemuxer extends Demuxer {
} }
} }
readContiguousElements(slice: FileSlice) { readContiguousElements(slice: FileSlice, stopIds?: number[]) {
const startIndex = slice.filePos; const startIndex = slice.filePos;
while (slice.filePos - startIndex <= slice.length - MIN_HEADER_SIZE) { while (slice.filePos - startIndex <= slice.length - MIN_HEADER_SIZE) {
const foundElement = this.traverseElement(slice); const startPos = slice.filePos;
const foundElement = this.traverseElement(slice, stopIds);
if (!foundElement) { if (!foundElement) {
break; return startPos;
} }
} }
return slice.filePos;
} }
traverseElement(slice: FileSlice): boolean { traverseElement(slice: FileSlice, stopIds?: number[]): boolean {
const header = readElementHeader(slice); const header = readElementHeader(slice);
if (!header) { if (!header) {
return false; return false;
} }
if (stopIds && stopIds.includes(header.id)) {
return false;
}
const { id, size } = header; const { id, size } = header;
const dataStartPos = slice.filePos; const dataStartPos = slice.filePos;
assertDefinedSize(size); assertDefinedSize(size);
@@ -2174,6 +2184,8 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
if (id === EBMLId.Cluster) { if (id === EBMLId.Cluster) {
currentCluster = await demuxer.readCluster(elementStartPos, segment); currentCluster = await demuxer.readCluster(elementStartPos, segment);
// readCluster computes the proper size even if it's undefined in the header, so let's use that instead
size = currentCluster.elementEndPos - dataStartPos;
const { blockIndex, correctBlockFound } = getMatchInCluster(currentCluster); const { blockIndex, correctBlockFound } = getMatchInCluster(currentCluster);
if (correctBlockFound) { if (correctBlockFound) {
@@ -2190,44 +2202,37 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
// Undefined element size (can happen in livestreamed files). In this case, we need to do some // Undefined element size (can happen in livestreamed files). In this case, we need to do some
// searching to determine the actual size of the element. // searching to determine the actual size of the element.
if (id === EBMLId.Cluster) { assert(id !== EBMLId.Cluster); // Undefined cluster sizes are fixed further up
// The cluster should have already computed its length, we can just copy that result
assert(currentCluster);
size = currentCluster.elementEndPos - dataStartPos;
} else {
// Search for the next element at level 0 or 1
const nextElementPos = await searchForNextElementId(
demuxer.reader,
dataStartPos,
LEVEL_0_AND_1_EBML_IDS,
segment.elementEndPos,
);
size = nextElementPos.pos - dataStartPos; // Search for the next element at level 0 or 1
} const nextElementPos = await searchForNextElementId(
demuxer.reader,
dataStartPos,
LEVEL_0_AND_1_EBML_IDS,
segment.elementEndPos,
);
const endPos = dataStartPos + size; size = nextElementPos.pos - dataStartPos;
if (segment.elementEndPos !== null && endPos > segment.elementEndPos - MIN_HEADER_SIZE) { }
// No more elements fit in this segment
const endPos = dataStartPos + size;
if (segment.elementEndPos === null) {
// Check the next element. If it's a new segment, we know this segment ends here. The new
// segment is just ignored, since we're likely in a livestreamed file and thus only care about
// the first segment.
let slice = demuxer.reader.requestSliceRange(endPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
if (slice instanceof Promise) slice = await slice;
if (!slice) break;
const elementId = readElementId(slice);
if (elementId === EBMLId.Segment) {
segment.elementEndPos = endPos; // We now know the segment's size
break; break;
} else {
// Check the next element. If it's a new segment, we know this segment ends here. The new
// segment is just ignored, since we're likely in a livestreamed file and thus only care about
// the first segment.
let slice = demuxer.reader.requestSliceRange(endPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
if (slice instanceof Promise) slice = await slice;
if (!slice) break;
const elementId = readElementId(slice);
if (elementId === EBMLId.Segment) {
segment.elementEndPos = endPos;
break;
}
} }
} }
currentPos = dataStartPos + size; currentPos = endPos;
} }
// Catch faulty cue points // Catch faulty cue points