mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 13:23:51 +02:00
Merge main into release for tag v1.24.2
This commit is contained in:
@@ -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
|
||||||
```
|
```
|
||||||
Generated
+6
-6
@@ -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
@@ -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,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",
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user