diff --git a/README.md b/README.md
index f4833e5..064d3ad 100644
--- a/README.md
+++ b/README.md
@@ -34,15 +34,15 @@ Mediabunny is a JavaScript library for reading, writing, and converting media fi
+
+
+
+
### Silver sponsors
-
-
diff --git a/docs/index.md b/docs/index.md
index 6ded5c5..7922f13 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -95,9 +95,9 @@ const sponsors = {
{ image: '/sponsors/gling.svg', name: 'Gling AI', url: 'https://www.gling.ai/' },
{ image: '/sponsors/diffusionstudio.png', name: 'Diffusion Studio', url: 'https://diffusion.studio/' },
{ image: '/sponsors/kino.jpg', name: 'Kino', url: 'https://kino.ai/' },
+ { image: '/sponsors/screen-studio.webp', name: 'Screen Studio', url: 'https://screen.studio/' },
],
silver: [
- { image: '/sponsors/pintura-labs.png', name: 'Pintura Labs', url: 'https://pqina.nl/pintura/' },
{ image: '/sponsors/ponder.png', name: 'Ponder', url: 'https://ponder.ai/' },
],
bronze: [
@@ -107,6 +107,7 @@ const sponsors = {
{ image: '/sponsors/jellypod.png', name: 'Jellypod', url: 'https://jellypod.ai/' },
],
individual: [
+ { image: '/sponsors/pintura-labs.png', name: 'Pintura Labs', url: 'https://pqina.nl/pintura/' },
{ image: 'https://avatars.githubusercontent.com/u/82552321', name: 'Polotno', url: 'https://github.com/polotno-project' },
{ image: 'https://avatars.githubusercontent.com/u/489051', name: 'Roman Rädle', url: 'https://github.com/raedle' },
{ image: 'https://avatars.githubusercontent.com/u/197597', name: 'Christopher Chedeau', url: 'https://github.com/vjeux' },
diff --git a/docs/public/sponsors/screen-studio.webp b/docs/public/sponsors/screen-studio.webp
new file mode 100644
index 0000000..dc6c20e
Binary files /dev/null and b/docs/public/sponsors/screen-studio.webp differ
diff --git a/examples/file-compression/file-compression.ts b/examples/file-compression/file-compression.ts
index 975dfa6..ff52ea4 100644
--- a/examples/file-compression/file-compression.ts
+++ b/examples/file-compression/file-compression.ts
@@ -143,7 +143,7 @@ loadUrlButton.addEventListener('click', () => {
const url = prompt(
'Please enter a URL of a media file. Note that it must be HTTPS and support cross-origin requests, so have the'
+ ' right CORS headers set.',
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
+ 'https://remotion.media/BigBuckBunny.mp4',
);
if (!url) {
return;
diff --git a/examples/media-player/media-player.ts b/examples/media-player/media-player.ts
index d87098c..4de5ba4 100644
--- a/examples/media-player/media-player.ts
+++ b/examples/media-player/media-player.ts
@@ -712,7 +712,7 @@ loadUrlButton.addEventListener('click', () => {
const url = prompt(
'Please enter a URL of a media file. Note that it must be HTTPS and support cross-origin requests, so have the'
+ ' right CORS headers set.',
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
+ 'https://remotion.media/BigBuckBunny.mp4',
);
if (!url) {
return;
diff --git a/examples/metadata-extraction/metadata-extraction.ts b/examples/metadata-extraction/metadata-extraction.ts
index fe81c1b..61cf332 100644
--- a/examples/metadata-extraction/metadata-extraction.ts
+++ b/examples/metadata-extraction/metadata-extraction.ts
@@ -221,7 +221,7 @@ loadUrlButton.addEventListener('click', () => {
const url = prompt(
'Please enter a URL of a media file. Note that it must be HTTPS and support cross-origin requests, so have the'
+ ' right CORS headers set.',
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
+ 'https://remotion.media/BigBuckBunny.mp4',
);
if (!url) {
return;
diff --git a/examples/thumbnail-generation/thumbnail-generation.ts b/examples/thumbnail-generation/thumbnail-generation.ts
index 28eeede..a62ad6f 100644
--- a/examples/thumbnail-generation/thumbnail-generation.ts
+++ b/examples/thumbnail-generation/thumbnail-generation.ts
@@ -137,7 +137,7 @@ loadUrlButton.addEventListener('click', () => {
const url = prompt(
'Please enter a URL of a media file. Note that it must be HTTPS and support cross-origin requests, so have the'
+ ' right CORS headers set.',
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
+ 'https://remotion.media/BigBuckBunny.mp4',
);
if (!url) {
return;
diff --git a/package-lock.json b/package-lock.json
index a075aa1..e146134 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "mediabunny",
- "version": "1.34.2",
+ "version": "1.34.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mediabunny",
- "version": "1.34.2",
+ "version": "1.34.4",
"license": "MPL-2.0",
"workspaces": [
"packages/*"
@@ -7743,9 +7743,9 @@
}
},
"node_modules/mediabunny": {
- "version": "1.34.0",
- "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.34.0.tgz",
- "integrity": "sha512-mjn/7QVEPbPEakuNKD8OIPDhaoe2NlgWVyyqftuLVWvsgLol7g2MQzXWCjx523CP8Y9jE2H09hbYCuTwSI7pSQ==",
+ "version": "1.34.3",
+ "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.34.3.tgz",
+ "integrity": "sha512-Jb0x3jyvadGVpo8aZSn53NZduPbPdbx9foQsAGOmKBz7Hai9B38Kf+7eXbxXFcXoXxcTyNaZeDhoA0agoBQldA==",
"license": "MPL-2.0",
"peer": true,
"workspaces": [
@@ -12069,7 +12069,7 @@
},
"packages/ac3": {
"name": "@mediabunny/ac3",
- "version": "1.34.2",
+ "version": "1.34.4",
"license": "MPL-2.0",
"devDependencies": {
"@types/emscripten": "^1.40.1"
@@ -12084,7 +12084,7 @@
},
"packages/mp3-encoder": {
"name": "@mediabunny/mp3-encoder",
- "version": "1.34.2",
+ "version": "1.34.4",
"license": "MPL-2.0",
"devDependencies": {
"@types/emscripten": "^1.40.1"
diff --git a/package.json b/package.json
index b1213d2..6700376 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "mediabunny",
"author": "Vanilagy",
- "version": "1.34.2",
+ "version": "1.34.4",
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
"type": "module",
"workspaces": [
diff --git a/packages/ac3/package.json b/packages/ac3/package.json
index 6e3eda5..225fc05 100644
--- a/packages/ac3/package.json
+++ b/packages/ac3/package.json
@@ -1,7 +1,7 @@
{
"name": "@mediabunny/ac3",
"author": "Vanilagy",
- "version": "1.34.2",
+ "version": "1.34.4",
"description": "AC-3 and E-AC-3 (Dolby Digital) decoder and encoder extension for Mediabunny, based on FFmpeg.",
"main": "./dist/bundles/mediabunny-ac3.mjs",
"module": "./dist/bundles/mediabunny-ac3.mjs",
diff --git a/packages/ac3/src/decoder.ts b/packages/ac3/src/decoder.ts
index 73cc9fe..a676073 100644
--- a/packages/ac3/src/decoder.ts
+++ b/packages/ac3/src/decoder.ts
@@ -13,7 +13,7 @@ import {
EncodedPacket,
registerDecoder,
} from 'mediabunny';
-import { sendCommand } from './worker-client';
+import { sendCommand, refWorker, unrefWorker } from './worker-client';
class Ac3Decoder extends CustomAudioDecoder {
private ctx = 0;
@@ -23,6 +23,8 @@ class Ac3Decoder extends CustomAudioDecoder {
}
async init() {
+ await refWorker();
+
const result = await sendCommand({
type: 'init-decoder',
data: { codec: this.codec },
@@ -53,8 +55,9 @@ class Ac3Decoder extends CustomAudioDecoder {
await sendCommand({ type: 'flush-decoder', data: { ctx: this.ctx } });
}
- close() {
+ async close() {
void sendCommand({ type: 'close-decoder', data: { ctx: this.ctx } });
+ await unrefWorker();
}
}
diff --git a/packages/ac3/src/encoder.ts b/packages/ac3/src/encoder.ts
index 1f567a0..2db9dfa 100644
--- a/packages/ac3/src/encoder.ts
+++ b/packages/ac3/src/encoder.ts
@@ -13,7 +13,7 @@ import {
EncodedPacket,
registerEncoder,
} from 'mediabunny';
-import { sendCommand } from './worker-client';
+import { sendCommand, refWorker, unrefWorker } from './worker-client';
import { assert } from './shared';
import { AC3_SAMPLE_RATES, EAC3_REDUCED_SAMPLE_RATES } from '../../../shared/ac3-misc';
@@ -38,11 +38,14 @@ class Ac3Encoder extends CustomAudioEncoder {
return (codec === 'ac3' || codec === 'eac3')
&& config.numberOfChannels >= 1
&& config.numberOfChannels <= 8
- && sampleRates.includes(config.sampleRate);
+ && sampleRates.includes(config.sampleRate)
+ && config.bitrate !== undefined;
}
async init() {
- assert(this.config.bitrate);
+ await refWorker();
+
+ assert(this.config.bitrate !== undefined);
this.sampleRate = this.config.sampleRate;
this.numberOfChannels = this.config.numberOfChannels;
@@ -130,6 +133,7 @@ class Ac3Encoder extends CustomAudioEncoder {
close() {
void sendCommand({ type: 'close-encoder', data: { ctx: this.ctx } });
+ void unrefWorker();
}
private async encodeOneFrame() {
diff --git a/packages/ac3/src/worker-client.ts b/packages/ac3/src/worker-client.ts
index d79e1ae..74a8bab 100644
--- a/packages/ac3/src/worker-client.ts
+++ b/packages/ac3/src/worker-client.ts
@@ -10,13 +10,51 @@ import { assert, type WorkerCommand, type WorkerResponse, type WorkerResponseDat
// @ts-expect-error An esbuild plugin handles this, TypeScript doesn't need to understand
import createWorker from './codec.worker';
-let workerPromise: Promise