From 23181a9ff6f090f000bfbf11777036b74a72b1ff Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 19 Sep 2025 14:07:16 +0200 Subject: [PATCH 1/2] Also run tests in release script --- .github/workflows/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3267201..1cb0d11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,6 +46,9 @@ jobs: - name: Install dependencies run: npm ci + - name: Run tests + run: npm run test + - name: Run build run: npm run build From a46e9ee9ec065551a232309a68c94dcf6cc5c585 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 19 Sep 2025 14:29:41 +0200 Subject: [PATCH 2/2] Fix flaky FLAC metadata reading --- package-lock.json | 12 ++++++------ package.json | 2 +- packages/mp3-encoder/package.json | 2 +- src/flac/flac-demuxer.ts | 22 +++++++++++++--------- src/reader.ts | 7 +++++++ 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index f921d40..0e4a0a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mediabunny", - "version": "1.17.2", + "version": "1.17.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mediabunny", - "version": "1.17.2", + "version": "1.17.3", "license": "MPL-2.0", "workspaces": [ "packages/*" @@ -7749,9 +7749,9 @@ } }, "node_modules/mediabunny": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.17.1.tgz", - "integrity": "sha512-2kLYbcv2NufwZ05AQXKjik54h4LUBQ1XBNoaVCOXU49pGXZzDq0krhJI77c4056QLH3QDPZ9DgYXosi92iEA1g==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.17.2.tgz", + "integrity": "sha512-I7l/WDv7howETh0Vhc9J8Y0XZ1Z1qUpUEcud05Eqf/MeaaOT8FGb744sTXN6U4Rk5ZxFYRz7g3JHcA1XvsFkWg==", "license": "MPL-2.0", "peer": true, "workspaces": [ @@ -12242,7 +12242,7 @@ }, "packages/mp3-encoder": { "name": "@mediabunny/mp3-encoder", - "version": "1.17.2", + "version": "1.17.3", "license": "MPL-2.0", "devDependencies": { "@types/emscripten": "^1.40.1" diff --git a/package.json b/package.json index 4ac7d29..127eba2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mediabunny", "author": "Vanilagy", - "version": "1.17.2", + "version": "1.17.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 7c95336..f7281e2 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.17.2", + "version": "1.17.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/flac/flac-demuxer.ts b/src/flac/flac-demuxer.ts index e5b8fcd..f42bafe 100644 --- a/src/flac/flac-demuxer.ts +++ b/src/flac/flac-demuxer.ts @@ -115,7 +115,8 @@ export class FlacDemuxer extends Demuxer { this.reader.fileSize === null || currentPos < this.reader.fileSize ) { - const sizeSlice = await this.reader.requestSlice(currentPos, 4); + let sizeSlice = this.reader.requestSlice(currentPos, 4); + if (sizeSlice instanceof Promise) sizeSlice = await sizeSlice; currentPos += 4; if (sizeSlice === null) { @@ -135,10 +136,12 @@ export class FlacDemuxer extends Demuxer { case FlacBlockType.STREAMINFO: { // Parse streaminfo block // https://www.rfc-editor.org/rfc/rfc9639.html#section-8.2 - const streamInfoBlock = await this.reader.requestSlice( + let streamInfoBlock = this.reader.requestSlice( currentPos, size, ); + if (streamInfoBlock instanceof Promise) streamInfoBlock = await streamInfoBlock; + assert(streamInfoBlock); if (streamInfoBlock === null) { throw new Error( @@ -192,17 +195,16 @@ export class FlacDemuxer extends Demuxer { case FlacBlockType.VORBIS_COMMENT: { // Parse vorbis comment block // https://www.rfc-editor.org/rfc/rfc9639.html#name-vorbis-comment - const vorbisCommentBlock = await this.reader.requestSlice( + let vorbisCommentBlock = this.reader.requestSlice( currentPos, size, ); + if (vorbisCommentBlock instanceof Promise) vorbisCommentBlock = await vorbisCommentBlock; + assert(vorbisCommentBlock); readVorbisComments( - vorbisCommentBlock.bytes.subarray( - vorbisCommentBlock.start, - vorbisCommentBlock.end, - ), + readBytes(vorbisCommentBlock, size), this.metadataTags, ); @@ -211,10 +213,11 @@ export class FlacDemuxer extends Demuxer { case FlacBlockType.PICTURE: { // Parse picture block // https://www.rfc-editor.org/rfc/rfc9639.html#name-picture - const pictureBlock = await this.reader.requestSlice( + let pictureBlock = this.reader.requestSlice( currentPos, size, ); + if (pictureBlock instanceof Promise) pictureBlock = await pictureBlock; assert(pictureBlock); const pictureType = readU32Be(pictureBlock); @@ -654,10 +657,11 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking { if (options.metadataOnly) { data = PLACEHOLDER_DATA; } else { - const slice = await this.demuxer.reader.requestSlice( + let slice = this.demuxer.reader.requestSlice( rawSample.byteOffset, rawSample.byteSize, ); + if (slice instanceof Promise) slice = await slice; if (!slice) { return null; // Data didn't fit into the rest of the file diff --git a/src/reader.ts b/src/reader.ts index 687e9bc..2cb5c00 100644 --- a/src/reader.ts +++ b/src/reader.ts @@ -80,13 +80,19 @@ export class Reader { } export class FileSlice { + /** The current position in the backing buffer. Do not modify directly, prefer `.skip()` instead. */ bufferPos: number; constructor( + /** The underlying bytes backing this slice. Avoid using this directly and prefer reader functions instead. */ public readonly bytes: Uint8Array, + /** A view into the bytes backing this slice. Avoid using this directly and prefer reader functions instead. */ public readonly view: DataView, + /** The offset in "file bytes" at which `bytes` begins in the file. */ private readonly offset: number, + /** The offset in "file bytes" where this slice begins. */ public readonly start: number, + /** The offset in "file bytes" where this slice ends (exclusive). */ public readonly end: number, ) { this.bufferPos = start - offset; @@ -118,6 +124,7 @@ export class FileSlice { this.bufferPos += byteCount; } + /** Creates a new subslice of this slice whose byte range must be contained within this slice. */ slice(filePos: number, length = this.end - filePos) { if (filePos < this.start || filePos + length > this.end) { throw new RangeError('Slicing outside of original slice.');