From 1534eb4c40b0ca7e4569f41d68905ef9440d7a40 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:26:52 +0200 Subject: [PATCH 1/9] Lint --- scripts/generate-api-docs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/generate-api-docs.ts b/scripts/generate-api-docs.ts index 14ee916..47f776f 100644 --- a/scripts/generate-api-docs.ts +++ b/scripts/generate-api-docs.ts @@ -1622,16 +1622,16 @@ const generateDocs = (entryFiles: string[], apiConfigFile: string, dry = false) const main = () => { const args = process.argv.slice(2); - + // Check for --dry flag const dryIndex = args.indexOf('--dry'); const dry = dryIndex !== -1; - + // Remove --dry flag from args if (dry) { args.splice(dryIndex, 1); } - + if (args.length < 2) { console.error('Usage: npm run generate-docs [--dry] [entry-file2 ...] '); console.error(' --dry: Check if docs are generatable without writing files'); From d313a850533fdca6fa4d51ac8e1f9239df6163fb Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:30:31 +0200 Subject: [PATCH 2/9] Document cropping in more places --- README.md | 2 +- docs/guide/converting-media-files.md | 1 + docs/guide/introduction.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b268e2..60b7b48 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Core features include: - **Wide format support**: Read and write MP4, MOV, WebM, MKV, WAVE, MP3, Ogg, ADTS - **Built-in encoding & decoding**: Supports 25+ video, audio, and subtitle codecs, hardware-accelerated using the WebCodecs API - **High precision**: Fine-grained, microsecond-accurate reading and writing operations -- **Conversion API**: Easy-to-use API with features such as transmuxing, transcoding, resizing, rotation, resampling, trimming, and more +- **Conversion API**: Easy-to-use API with features such as transmuxing, transcoding, resizing, rotation, cropping, resampling, trimming, and more - **Streaming I/O**: Handle reading & writing files of any size with memory-efficient streaming - **Tree-shakable**: Only bundle what you use (as small as 5 kB gzipped) - **Zero dependencies**: Implemented in highly performant TypeScript diff --git a/docs/guide/converting-media-files.md b/docs/guide/converting-media-files.md index 76f4296..91a3aae 100644 --- a/docs/guide/converting-media-files.md +++ b/docs/guide/converting-media-files.md @@ -11,6 +11,7 @@ It has the following features: - Trimming - Video resizing & fitting - Video rotation +- Video cropping - Video frame rate adjustment - Audio resampling - Audio up/downmixing diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md index 4a63c35..db03b55 100644 --- a/docs/guide/introduction.md +++ b/docs/guide/introduction.md @@ -17,7 +17,7 @@ Here's a long list of stuff this library does: - Lazy, optimized, on-demand file reading - Input and output streaming, arbitrary file size support - File location independence (memory, disk, network, ...) -- Utilities for compression, resizing, rotation, resampling, trimming +- Utilities for compression, resizing, rotation, cropping, resampling, trimming - Transmuxing and transcoding - Microsecond-accurate reading and writing precision - Efficient seeking through time From 7efb092ff5bf31256c5050cb5ffe17bb8863e135 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:46:27 +0200 Subject: [PATCH 3/9] Add parsing of 'track' metadata key for ISOBMFF --- src/isobmff/isobmff-demuxer.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index 84fce37..8222348 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -2306,6 +2306,21 @@ export class IsobmffDemuxer extends Demuxer { } }; break; + case 'track': { + if (typeof data === 'string') { + const parts = data.split('/'); + const trackNum = Number.parseInt(parts[0]!, 10); + const tracksTotal = parts[1] && Number.parseInt(parts[1], 10); + + if (Number.isInteger(trackNum) && trackNum > 0) { + this.metadataTags.trackNumber ??= trackNum; + } + if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) { + this.metadataTags.tracksTotal ??= tracksTotal; + } + } + }; break; + case 'trkn': { if (data instanceof Uint8Array) { const view = toDataView(data); From fcec67645aae2e1b2b4bdb87f0c8f65fb4ef6372 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:10:16 +0200 Subject: [PATCH 4/9] Allow object for `tags` field in conversion --- dev/convert.html | 54 ++++++++++++++-------------- dev/demux.html | 7 +--- docs/guide/converting-media-files.md | 10 +++--- src/conversion.ts | 31 +++++++++++----- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/dev/convert.html b/dev/convert.html index 7824830..ea8de68 100644 --- a/dev/convert.html +++ b/dev/convert.html @@ -47,23 +47,6 @@ format: outputFormat, target }); - output.setMetadataTags({ - title: 'Bigggy', - artist: 'Buck Bunny', - images: [{ - data: blobData, - kind: 'coverFront', - mimeType: 'image/jpeg' - }], - trackNumber: 4, - tracksTotal: 10, - discNumber: 5, - discNumberMax: 8, - lyrics: "There's no way\nThat it's not going there", - raw: { - 'ENCODER': 'Mediabunny epic own encoder' - } - }); const conversion = await Mediabunny.Conversion.init({ input: new Mediabunny.Input({ @@ -109,16 +92,16 @@ */ video: () => ({ //discard: true, - crop: { - left: 0, - top: 0, - width: 500, - height: 500, - }, - rotate: 90, - width: 200, - height: 500, - fit: 'contain', + //crop: { + // left: 0, + // top: 0, + // width: 500, + // height: 500, + //}, + //rotate: 90, + //width: 200, + //height: 500, + //fit: 'contain', //forceTranscode: true, //codec: 'avc', //fit: 'contain', @@ -141,6 +124,23 @@ //width: 200, //height: 100, }), + tags: { + title: 'Bigggy', + artist: 'Buck Bunny', + images: [{ + data: blobData, + kind: 'coverFront', + mimeType: 'image/jpeg' + }], + trackNumber: 4, + tracksTotal: 10, + discNumber: 5, + discsTotal: 8, + lyrics: "There's no way\nThat it's not going there", + raw: { + 'AIGC': 'Mediabunny epic own encoder' + } + }, trim: { start: 10, end: 20 diff --git a/dev/demux.html b/dev/demux.html index b844f7d..7df202b 100644 --- a/dev/demux.html +++ b/dev/demux.html @@ -14,12 +14,7 @@ source: new Mediabunny.BlobSource(file), }); - const audioTrack = await input.getPrimaryAudioTrack(); - const sink = new Mediabunny.EncodedPacketSink(audioTrack); - - for await (const packet of sink.packets()) { - console.log(packet); - } + console.log(await input.getMetadataTags()) /* const sink = new Mediabunny.EncodedPacketSink(videoTrack); diff --git a/docs/guide/converting-media-files.md b/docs/guide/converting-media-files.md index 91a3aae..164963d 100644 --- a/docs/guide/converting-media-files.md +++ b/docs/guide/converting-media-files.md @@ -49,7 +49,7 @@ await conversion.execute(); That's it! A `Conversion` simply takes an instance of `Input` and `Output`, then reads the data from the input and writes it to the output. If you're unfamiliar with [`Input`](./reading-media-files) and [`Output`](./writing-media-files), check out their respective guides. ::: info -The `Output` passed to the `Conversion` must be *fresh*; that is, it must have no added tracks and be in the `'pending'` state (not started yet). +The `Output` passed to the `Conversion` must be *fresh*; that is, it must have no added tracks or metadata tags and be in the `'pending'` state (not started yet). ::: Unconfigured, the conversion process handles all the details automatically, such as: @@ -299,17 +299,17 @@ By default, any [descriptive metadata tags](../api/MetadataTags.md) of the input // Set your own metadata: const conversion = await Conversion.init({ // ... - tags: () => ({ + tags: { title: 're:Turning', artist: 'Alexander Panos', - }), + }, // ... }); // Or, augment the input's metadata: const conversion = await Conversion.init({ // ... - tags: inputTags => ({ + tags: (inputTags) => ({ ...inputTags, // Keep the existing metadata images: [{ // And add cover art data: new Uint8Array(...), @@ -324,7 +324,7 @@ const conversion = await Conversion.init({ // Or, remove all metadata const conversion = await Conversion.init({ // ... - tags: () => ({}), + tags: {}, // ... }); ``` diff --git a/src/conversion.ts b/src/conversion.ts index 10eb8f8..066a392 100644 --- a/src/conversion.ts +++ b/src/conversion.ts @@ -89,13 +89,13 @@ export type ConversionOptions = { }; /** - * A callback that returns or resolves to the descriptive metadata tags that should be written to the output file. - * As input, this function will be passed the tags of the input file, allowing you to modify, augment or extend - * them. + * An object or a callback that returns or resolves to an object containing the descriptive metadata tags that + * should be written to the output file. If a function is passed, it will be passed the tags of the input file as + * its first argument, allowing you to modify, augment or extend them. * * If no function is set, the input's metadata tags will be copied to the output. */ - tags?: (inputTags: MetadataTags) => MaybePromise; + tags?: MetadataTags | ((inputTags: MetadataTags) => MaybePromise); }; /** @@ -395,8 +395,12 @@ export class Conversion { if (!(options.output instanceof Output)) { throw new TypeError('options.output must be an Output.'); } - if (options.output._tracks.length > 0 || options.output.state !== 'pending') { - throw new TypeError('options.output must be fresh: no tracks added and not started.'); + if ( + options.output._tracks.length > 0 + || Object.keys(options.output._metadataTags).length > 0 + || options.output.state !== 'pending' + ) { + throw new TypeError('options.output must be fresh: no tracks or metadata tags added and not started.'); } if (typeof options.video !== 'function') { @@ -426,8 +430,15 @@ export class Conversion { && options.trim.start >= options.trim.end) { throw new TypeError('options.trim.start must be less than options.trim.end.'); } - if (options.tags !== undefined && typeof options.tags !== 'function') { - throw new TypeError('options.tags, when provided, must be a function.'); + if ( + options.tags !== undefined + && (typeof options.tags !== 'object' || !options.tags) + && typeof options.tags !== 'function' + ) { + throw new TypeError('options.tags, when provided, must be an object or a function.'); + } + if (typeof options.tags === 'object') { + validateMetadataTags(options.tags); } this._options = options; @@ -519,7 +530,9 @@ export class Conversion { let outputTags: MetadataTags; if (this._options.tags) { - const result = await this._options.tags(inputTags); + const result = typeof this._options.tags === 'function' + ? await this._options.tags(inputTags) + : this._options.tags; validateMetadataTags(result); outputTags = result; From 530ccd7523ac046e42f1ea076afb39d69e0b42ea Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:50:14 +0200 Subject: [PATCH 5/9] Drag 0-duration VideoFrame duration to null (fixes #116) --- dev/mux.html | 7 ++++--- src/sample.ts | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dev/mux.html b/dev/mux.html index ad0eeaf..3df9586 100644 --- a/dev/mux.html +++ b/dev/mux.html @@ -116,9 +116,10 @@ */ let videoSource = new Mediabunny.CanvasSource(canvas, { - codec: 'avc', + codec: 'vp9', //fullCodecString: 'avc1.42001f', - bitrate: 1e6 + bitrate: 1e6, + onEncoderConfig: console.log, }); let audioSource = new Mediabunny.AudioBufferSource({ codec: 'opus', @@ -207,5 +208,5 @@ Testing... <00:17.350>One... <00:18.125>Two... await output.finalize(); console.log(target); - download(new Blob([target.buffer]), 'test' + format.fileExtension); + //download(new Blob([target.buffer]), 'test' + format.fileExtension); \ No newline at end of file diff --git a/src/sample.ts b/src/sample.ts index 285fea2..1f2e074 100644 --- a/src/sample.ts +++ b/src/sample.ts @@ -201,7 +201,8 @@ export class VideoSample { return new VideoSample( new VideoFrame(data, { timestamp: Math.trunc(init.timestamp! * SECOND_TO_MICROSECOND_FACTOR), - duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR), + // Drag 0 to undefined + duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || undefined, }), init, ); @@ -373,13 +374,13 @@ export class VideoSample { codedWidth: this.codedWidth, codedHeight: this.codedHeight, timestamp: this.microsecondTimestamp, - duration: this.microsecondDuration, + duration: this.microsecondDuration || undefined, colorSpace: this.colorSpace, }); } else { return new VideoFrame(this._data, { timestamp: this.microsecondTimestamp, - duration: this.microsecondDuration, + duration: this.microsecondDuration || undefined, }); } } From 1bb3c0e262997f4ef70fff277abb29d1a8ff7607 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:42:23 +0200 Subject: [PATCH 6/9] Avoid opaque canvases in case of Firefox (fixes #117) --- src/media-sink.ts | 13 ++++++++++--- src/media-source.ts | 23 +++++++++++++++++++---- src/misc.ts | 9 +++++++++ src/sample.ts | 8 ++++++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/media-sink.ts b/src/media-sink.ts index 989d9b2..335dfcc 100644 --- a/src/media-sink.ts +++ b/src/media-sink.ts @@ -18,6 +18,7 @@ import { getInt24, getUint24, insertSorted, + isFirefox, isSafari, last, mapAsyncGenerator, @@ -1199,14 +1200,20 @@ export class CanvasSink { this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length; } - const context - = canvas.getContext('2d', { alpha: false }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; + const context = canvas.getContext('2d', { + alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases + }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; assert(context); context.resetTransform(); if (!canvasIsNew) { - context.clearRect(0, 0, this._width, this._height); + if (isFirefox()) { + context.fillStyle = 'black'; + context.fillRect(0, 0, this._width, this._height); + } else { + context.clearRect(0, 0, this._width, this._height); + } } sample.drawWithFit(context, { diff --git a/src/media-source.ts b/src/media-source.ts index b72c791..44a7d42 100644 --- a/src/media-source.ts +++ b/src/media-source.ts @@ -18,7 +18,16 @@ import { VideoCodec, } from './codec'; import { OutputAudioTrack, OutputSubtitleTrack, OutputTrack, OutputVideoTrack } from './output'; -import { assert, assertNever, CallSerializer, clamp, promiseWithResolvers, setInt24, setUint24 } from './misc'; +import { + assert, + assertNever, + CallSerializer, + clamp, + isFirefox, + promiseWithResolvers, + setInt24, + setUint24, +} from './misc'; import { Muxer } from './muxer'; import { SubtitleParser } from './subtitles'; import { toAlaw, toUlaw } from './pcm'; @@ -248,12 +257,18 @@ class VideoEncoderWrapper { canvasIsNew = true; } - const context = this.resizeCanvas.getContext('2d', { alpha: false }) as - CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; + const context = this.resizeCanvas.getContext('2d', { + alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases + }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; assert(context); if (!canvasIsNew) { - context.clearRect(0, 0, this.codedWidth, this.codedHeight); + if (isFirefox()) { + context.fillStyle = 'black'; + context.fillRect(0, 0, this.codedWidth, this.codedHeight); + } else { + context.clearRect(0, 0, this.codedWidth, this.codedHeight); + } } videoSample.drawWithFit(context, { fit: sizeChangeBehavior }); diff --git a/src/misc.ts b/src/misc.ts index 3126f03..1c842f2 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -642,6 +642,15 @@ export const isSafari = () => { return result; }; +let isFirefoxCache: boolean | null = null; +export const isFirefox = () => { + if (isFirefoxCache !== null) { + return isFirefoxCache; + } + + return isFirefoxCache = typeof navigator !== 'undefined' && navigator.userAgent?.includes('Firefox'); +}; + /** * T or a promise that resolves to T. * @group Miscellaneous diff --git a/src/sample.ts b/src/sample.ts index 1f2e074..c713aa8 100644 --- a/src/sample.ts +++ b/src/sample.ts @@ -15,6 +15,7 @@ import { toDataView, toUint8Array, SetRequired, + isFirefox, } from './misc'; /** @@ -228,7 +229,10 @@ export class VideoSample { } const canvas = new OffscreenCanvas(width, height); - const context = canvas.getContext('2d', { alpha: false, willReadFrequently: true }); + const context = canvas.getContext('2d', { + alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases + willReadFrequently: true, + }); assert(context); // Draw it to a canvas @@ -343,7 +347,7 @@ export class VideoSample { dest.set(this._data); } else { const canvas = this._data; - const context = canvas.getContext('2d', { alpha: false }); + const context = canvas.getContext('2d'); assert(context); const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight); From 555006b9c380439ec928144a1cc769e8f9d88256 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:13:32 +0200 Subject: [PATCH 7/9] Add improved logic for loading Node.js module (fixes #118) --- package.json | 4 ++++ scripts/add-import-extensions.ts | 2 +- scripts/bundle.ts | 3 +++ src/node.ts | 11 +++++++++++ src/source.ts | 10 ++++++---- 5 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 src/node.ts diff --git a/package.json b/package.json index ce2e3fe..a1f1445 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,10 @@ "dist", "src" ], + "browser": { + "./dist/modules/src/node.js": false, + "./src/node.ts": false + }, "sideEffects": false, "scripts": { "build": "./build.sh", diff --git a/scripts/add-import-extensions.ts b/scripts/add-import-extensions.ts index ee07742..d5da4b1 100644 --- a/scripts/add-import-extensions.ts +++ b/scripts/add-import-extensions.ts @@ -24,7 +24,7 @@ const walkDir = (dir: string) => { const fixFile = (filePath: string) => { const content = fs.readFileSync(filePath, 'utf8'); const fixed = content.replace( - /(\s+from\s+['"])([^'"]*)(['"])/g, + /(\s+from\s+['"])(\.[^'"]*)(['"])/g, // This only matches relative imports '$1$2.js$3', ); diff --git a/scripts/bundle.ts b/scripts/bundle.ts index 02de9ac..fbe7a91 100644 --- a/scripts/bundle.ts +++ b/scripts/bundle.ts @@ -16,6 +16,9 @@ const createVariants = async ( entryPoints: [entryPoint], bundle: true, logLevel: 'info', + logOverride: { + 'import-is-undefined': 'silent', // Warning caused by the disabled "node.ts" import + }, banner: { js: `/*! * Copyright (c) 2025-present, Vanilagy and contributors diff --git a/src/node.ts b/src/node.ts new file mode 100644 index 0000000..81f2a0d --- /dev/null +++ b/src/node.ts @@ -0,0 +1,11 @@ +/*! + * Copyright (c) 2025-present, Vanilagy and contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// This file contains Node.js-specific code that does not run in a browser. + +export * as fs from 'node:fs/promises'; diff --git a/src/source.ts b/src/source.ts index 54aedae..6e548ce 100644 --- a/src/source.ts +++ b/src/source.ts @@ -18,6 +18,9 @@ import { toDataView, toUint8Array, } from './misc'; +import * as nodeAlias from './node'; + +const node = nodeAlias; // Aliasing it prevents some bundler warnings export type ReadResult = { bytes: Uint8Array; @@ -548,9 +551,7 @@ export class FilePathSource extends Source { // Let's back this source with a StreamSource, makes the implementation very simple this._streamSource = new StreamSource({ getSize: async () => { - const FS_MODULE_NAME = 'node:fs/promises'; - const fs = await import(/* @vite-ignore */ FS_MODULE_NAME) as typeof import('node:fs/promises'); - fileHandle = await fs.open(filePath, 'r'); + fileHandle = await node.fs.open(filePath, 'r'); const stats = await fileHandle.stat(); return stats.size; @@ -558,8 +559,9 @@ export class FilePathSource extends Source { read: async (start, end) => { assert(fileHandle); - const buffer = Buffer.alloc(end - start); + const buffer = new Uint8Array(end - start); await fileHandle.read(buffer, 0, end - start, start); + return buffer; }, maxCacheSize: options.maxCacheSize, From 7a0051bec5527d5a529e1881ec63dcc403426f13 Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 21:27:54 +0200 Subject: [PATCH 8/9] Tag spam --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index a1f1445..d8988c0 100644 --- a/package.json +++ b/package.json @@ -106,11 +106,15 @@ "decoder", "convert", "mp4", + "mov", "fmp4", "webm", + "mkv", "wav", "mp3", "ogg", + "adts", + "flac", "video", "audio", "subtitles", From 7d725d068b8707562ad07cf8e67b6c45895b435d Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Tue, 16 Sep 2025 23:12:51 +0200 Subject: [PATCH 9/9] Bump patch --- package-lock.json | 12 ++++++------ package.json | 4 ++-- packages/mp3-encoder/package.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f86d23..385bbac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mediabunny", - "version": "1.15.1", + "version": "1.15.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mediabunny", - "version": "1.15.1", + "version": "1.15.2", "license": "MPL-2.0", "workspaces": [ "packages/*" @@ -7749,9 +7749,9 @@ } }, "node_modules/mediabunny": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.15.0.tgz", - "integrity": "sha512-yeqr+4sRNzl7QqeHckr+SgPKfaQwSSmhTdVSgKgbenneC+TFlBrk+zCRhF9b7kwLtrm6qziJc/flqYQccX6W/Q==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.15.1.tgz", + "integrity": "sha512-+eRTVzd3E4LuGYZzPSQcPzuGdAIljohSlzYTX358XsfLM2qH1lQIBYa+erx7wzVcGQLRNjdV7x7ZS0EpK04DfA==", "license": "MPL-2.0", "peer": true, "workspaces": [ @@ -12242,7 +12242,7 @@ }, "packages/mp3-encoder": { "name": "@mediabunny/mp3-encoder", - "version": "1.15.1", + "version": "1.15.2", "license": "MPL-2.0", "devDependencies": { "@types/emscripten": "^1.40.1" diff --git a/package.json b/package.json index d8988c0..86e7528 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mediabunny", "author": "Vanilagy", - "version": "1.15.1", + "version": "1.15.2", "description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.", "type": "module", "workspaces": [ @@ -24,7 +24,7 @@ ], "browser": { "./dist/modules/src/node.js": false, - "./src/node.ts": false + "./src/node.ts": false }, "sideEffects": false, "scripts": { diff --git a/packages/mp3-encoder/package.json b/packages/mp3-encoder/package.json index 638e9a7..182dff3 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.15.1", + "version": "1.15.2", "description": "MP3 encoder extension for Mediabunny, based on LAME.", "main": "./dist/bundles/mediabunny-mp3-encoder.mjs", "module": "./dist/bundles/mediabunny-mp3-encoder.mjs",