From a15283eaa33db90a7895e4a9e8a7f4bed6cbdd8d Mon Sep 17 00:00:00 2001
From: Vanilagy <1696106+Vanilagy@users.noreply.github.com>
Date: Wed, 4 Mar 2026 21:21:52 +0100
Subject: [PATCH 1/3] Add @mediabunny/flac-encoder extension, clean up some
other code, fix incorrect top-level tsconfig
---
.gitignore | 3 +-
docs/.vitepress/config.mts | 1 +
docs/api-config.json | 3 +-
docs/guide/extensions/flac-encoder.md | 81 +++++
eslint.config.mjs | 2 +
package-lock.json | 19 ++
package.json | 2 +-
packages/aac-encoder/src/encode.worker.ts | 12 +-
packages/aac-encoder/src/encoder.ts | 5 +-
packages/aac-encoder/src/shared.ts | 25 +-
packages/flac-encoder/.gitattributes | 1 +
packages/flac-encoder/LICENSE | 373 +++++++++++++++++++++
packages/flac-encoder/README.md | 140 ++++++++
packages/flac-encoder/api-extractor.json | 37 ++
packages/flac-encoder/build/flac.js | Bin 0 -> 202256 bytes
packages/flac-encoder/package.json | 54 +++
packages/flac-encoder/src/bridge.c | 255 ++++++++++++++
packages/flac-encoder/src/encode.worker.ts | 193 +++++++++++
packages/flac-encoder/src/encoder.ts | 200 +++++++++++
packages/flac-encoder/src/index.ts | 20 ++
packages/flac-encoder/src/shared.ts | 54 +++
packages/flac-encoder/tsconfig.json | 24 ++
packages/flac-encoder/tsdoc.json | 4 +
scripts/build.sh | 8 +-
scripts/bundle.ts | 32 ++
scripts/check.sh | 3 +
src/conversion.ts | 6 +
src/flac/flac-muxer.ts | 20 +-
test/node/flac-encoder-extension.test.ts | 83 +++++
test/node/mp3-encoder-extension.test.ts | 83 +++++
tsconfig.json | 1 +
tsconfig.vite.json | 1 +
tsconfig.vitest.json | 10 +-
vite.config.ts | 2 +
vitest.config.ts | 4 +
35 files changed, 1713 insertions(+), 48 deletions(-)
create mode 100644 docs/guide/extensions/flac-encoder.md
create mode 100644 packages/flac-encoder/.gitattributes
create mode 100644 packages/flac-encoder/LICENSE
create mode 100644 packages/flac-encoder/README.md
create mode 100644 packages/flac-encoder/api-extractor.json
create mode 100644 packages/flac-encoder/build/flac.js
create mode 100644 packages/flac-encoder/package.json
create mode 100644 packages/flac-encoder/src/bridge.c
create mode 100644 packages/flac-encoder/src/encode.worker.ts
create mode 100644 packages/flac-encoder/src/encoder.ts
create mode 100644 packages/flac-encoder/src/index.ts
create mode 100644 packages/flac-encoder/src/shared.ts
create mode 100644 packages/flac-encoder/tsconfig.json
create mode 100644 packages/flac-encoder/tsdoc.json
create mode 100644 test/node/flac-encoder-extension.test.ts
create mode 100644 test/node/mp3-encoder-extension.test.ts
diff --git a/.gitignore b/.gitignore
index e4b72d3..3c8896f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,5 @@ node_modules
packages/mp3-encoder/dist
packages/ac3/dist
-packages/aac-encoder/dist
\ No newline at end of file
+packages/aac-encoder/dist
+packages/flac-encoder/dist
\ No newline at end of file
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index a050b49..68e6167 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -95,6 +95,7 @@ export default withMermaid({
{ text: 'mp3-encoder', link: '/guide/extensions/mp3-encoder' },
{ text: 'aac-encoder', link: '/guide/extensions/aac-encoder' },
{ text: 'ac3', link: '/guide/extensions/ac3' },
+ { text: 'flac-encoder', link: '/guide/extensions/flac-encoder' },
],
},
],
diff --git a/docs/api-config.json b/docs/api-config.json
index 53ba487..a17dc62 100644
--- a/docs/api-config.json
+++ b/docs/api-config.json
@@ -21,5 +21,6 @@
"@mediabunny/mp3-encoder": "Adds MP3 encoder support to Mediabunny.",
"@mediabunny/ac3": "Adds AC-3/E-AC-3 decoder and encoder support to Mediabunny.",
- "@mediabunny/aac-encoder": "Adds AAC encoder support to Mediabunny."
+ "@mediabunny/aac-encoder": "Polyfills AAC encoder support to Mediabunny.",
+ "@mediabunny/flac-encoder": "Adds FLAC encoder support to Mediabunny."
}
diff --git a/docs/guide/extensions/flac-encoder.md b/docs/guide/extensions/flac-encoder.md
new file mode 100644
index 0000000..c2f2ee9
--- /dev/null
+++ b/docs/guide/extensions/flac-encoder.md
@@ -0,0 +1,81 @@
+# @mediabunny/flac-encoder
+
+No browser currently supports FLAC encoding in their WebCodecs implementations. This extension package provides a reliable FLAC encoder for use with Mediabunny. It is implemented using Mediabunny's [custom coder API](../supported-formats-and-codecs#custom-coders) and uses a fast, size-optimized WASM build of [libFLAC](https://github.com/xiph/flac) (the reference FLAC encoder) under the hood.
+
+
+ GitHub page
+
+
+
+## Installation
+
+This library peer-depends on Mediabunny. Install both using npm:
+```bash
+npm install mediabunny @mediabunny/flac-encoder
+```
+
+Alternatively, directly include them using a script tag:
+```html
+
+
+```
+
+This will expose the global objects `Mediabunny` and `MediabunnyFlacEncoder`. Use `mediabunny-flac-encoder.d.ts` to provide types for these globals. You can download the built distribution files from the [releases page](https://github.com/Vanilagy/mediabunny/releases).
+
+## Usage
+
+```ts
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+registerFlacEncoder();
+```
+That's it - Mediabunny now uses the registered FLAC encoder automatically.
+
+If you want to be more correct, check for native browser support first:
+```ts
+import { canEncodeAudio } from 'mediabunny';
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+if (!(await canEncodeAudio('flac'))) {
+ registerFlacEncoder();
+}
+```
+
+## Example
+
+Here, we convert an input file to a FLAC file:
+
+```ts
+import {
+ Input,
+ ALL_FORMATS,
+ BlobSource,
+ Output,
+ BufferTarget,
+ FlacOutputFormat,
+ canEncodeAudio,
+ Conversion,
+} from 'mediabunny';
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+if (!(await canEncodeAudio('flac'))) {
+ registerFlacEncoder();
+}
+
+const input = new Input({
+ source: new BlobSource(file), // From a file picker, for example
+ formats: ALL_FORMATS,
+});
+const output = new Output({
+ format: new FlacOutputFormat(),
+ target: new BufferTarget(),
+});
+
+const conversion = await Conversion.init({
+ input,
+ output,
+});
+await conversion.execute();
+
+output.target.buffer; // => ArrayBuffer containing the FLAC file
+```
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 95f80b1..e80f29c 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -42,6 +42,8 @@ export default tseslint.config(
'packages/ac3/build',
'packages/aac-encoder/dist',
'packages/aac-encoder/build',
+ 'packages/flac-encoder/dist',
+ 'packages/flac-encoder/build',
'eslint.config.mjs',
'docs/.vitepress/cache',
'test/public',
diff --git a/package-lock.json b/package-lock.json
index d7365a1..62b1cd0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1421,6 +1421,10 @@
"resolved": "packages/ac3",
"link": true
},
+ "node_modules/@mediabunny/flac-encoder": {
+ "resolved": "packages/flac-encoder",
+ "link": true
+ },
"node_modules/@mediabunny/mp3-encoder": {
"resolved": "packages/mp3-encoder",
"link": true
@@ -12101,6 +12105,21 @@
"mediabunny": "^1.0.0"
}
},
+ "packages/flac-encoder": {
+ "name": "@mediabunny/flac-encoder",
+ "version": "1.36.0",
+ "license": "MPL-2.0",
+ "devDependencies": {
+ "@types/emscripten": "^1.40.1"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://github.com/sponsors/Vanilagy"
+ },
+ "peerDependencies": {
+ "mediabunny": "^1.0.0"
+ }
+ },
"packages/mp3-encoder": {
"name": "@mediabunny/mp3-encoder",
"version": "1.36.0",
diff --git a/package.json b/package.json
index 503fdb6..0a533fb 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
"docs:dev": "vitepress dev docs",
"docs:build": "npm run build && npm run docs:generate && vitepress build docs && npm run examples:build && cp dist/mediabunny.d.ts dist-docs/",
"docs:preview": "vitepress preview docs",
- "docs:generate": "tsx scripts/generate-api-docs.ts src/index.ts packages/mp3-encoder/src/index.ts packages/ac3/src/index.ts packages/aac-encoder/src/index.ts docs/api-config.json",
+ "docs:generate": "tsx scripts/generate-api-docs.ts src/index.ts packages/mp3-encoder/src/index.ts packages/ac3/src/index.ts packages/aac-encoder/src/index.ts packages/flac-encoder/src/index.ts docs/api-config.json",
"dev": "vite",
"examples:build": "vite build",
"fix-build-import-paths": "tsx scripts/add-import-extensions.ts",
diff --git a/packages/aac-encoder/src/encode.worker.ts b/packages/aac-encoder/src/encode.worker.ts
index d109920..0023d49 100644
--- a/packages/aac-encoder/src/encode.worker.ts
+++ b/packages/aac-encoder/src/encode.worker.ts
@@ -7,7 +7,7 @@
*/
import createModule from '../build/aac';
-import type { WorkerCommand, WorkerResponse, WorkerResponseData } from './shared';
+import type { PacketInfo, WorkerCommand, WorkerResponse, WorkerResponseData } from './shared';
type ExtendedEmscriptenModule = EmscriptenModule & {
cwrap: typeof cwrap;
@@ -28,8 +28,6 @@ let resetEncoderFn: (ctx: number) => void;
let getEncodedData: (ctx: number) => number;
let getEncodedPts: (ctx: number) => number;
let getEncodedDuration: (ctx: number) => number;
-let closeEncoderFn: (ctx: number) => void;
-
const ensureModule = async () => {
if (!module) {
if (modulePromise) {
@@ -52,7 +50,6 @@ const ensureModule = async () => {
getEncodedData = module.cwrap('get_encoded_data', 'number', ['number']);
getEncodedPts = module.cwrap('get_encoded_pts', 'number', ['number']);
getEncodedDuration = module.cwrap('get_encoded_duration', 'number', ['number']);
- closeEncoderFn = module.cwrap('close_encoder', null, ['number']);
}
};
@@ -77,8 +74,6 @@ const initEncoder = async (
return { ctx, frameSize, extradata };
};
-type PacketInfo = { encodedData: ArrayBuffer; pts: number; duration: number };
-
const drainPackets = (ctx: number) => {
const packets: PacketInfo[] = [];
@@ -151,11 +146,6 @@ const onMessage = (data: { id: number; command: WorkerCommand }) => {
resetEncoderFn(command.data.ctx);
result = { type: command.type, packets };
}; break;
-
- case 'close': {
- closeEncoderFn(command.data.ctx);
- result = { type: command.type };
- }; break;
}
const response: WorkerResponse = {
diff --git a/packages/aac-encoder/src/encoder.ts b/packages/aac-encoder/src/encoder.ts
index 6f2d681..61421fd 100644
--- a/packages/aac-encoder/src/encoder.ts
+++ b/packages/aac-encoder/src/encoder.ts
@@ -19,7 +19,7 @@ import {
EncodedPacket,
registerEncoder,
} from 'mediabunny';
-import type { WorkerCommand, WorkerResponse, WorkerResponseData } from './shared';
+import type { PacketInfo, WorkerCommand, WorkerResponse, WorkerResponseData } from './shared';
// @ts-expect-error An esbuild plugin handles this, TypeScript doesn't need to understand
import createWorker from './encode.worker';
@@ -184,7 +184,6 @@ class AacEncoder extends CustomAudioEncoder {
}
close() {
- void this.sendCommand({ type: 'close', data: { ctx: this.ctx } });
this.worker?.terminate();
}
@@ -219,7 +218,7 @@ class AacEncoder extends CustomAudioEncoder {
this.emitPackets(result.packets);
}
- private emitPackets(packets: Array<{ encodedData: ArrayBuffer; pts: number; duration: number }>) {
+ private emitPackets(packets: PacketInfo[]) {
assert(this.nextPacketTimestampInSamples !== null);
for (const p of packets) {
diff --git a/packages/aac-encoder/src/shared.ts b/packages/aac-encoder/src/shared.ts
index ce5513d..9f08589 100644
--- a/packages/aac-encoder/src/shared.ts
+++ b/packages/aac-encoder/src/shared.ts
@@ -25,11 +25,12 @@ export type WorkerCommand = {
data: {
ctx: number;
};
-} | {
- type: 'close';
- data: {
- ctx: number;
- };
+};
+
+export type PacketInfo = {
+ encodedData: ArrayBuffer;
+ pts: number;
+ duration: number;
};
export type WorkerResponseData = {
@@ -39,20 +40,10 @@ export type WorkerResponseData = {
extradata: ArrayBuffer;
} | {
type: 'encode';
- packets: Array<{
- encodedData: ArrayBuffer;
- pts: number;
- duration: number;
- }>;
+ packets: PacketInfo[];
} | {
type: 'flush';
- packets: Array<{
- encodedData: ArrayBuffer;
- pts: number;
- duration: number;
- }>;
-} | {
- type: 'close';
+ packets: PacketInfo[];
};
export type WorkerResponse = {
diff --git a/packages/flac-encoder/.gitattributes b/packages/flac-encoder/.gitattributes
new file mode 100644
index 0000000..72ef19a
--- /dev/null
+++ b/packages/flac-encoder/.gitattributes
@@ -0,0 +1 @@
+build/* linguist-generated
diff --git a/packages/flac-encoder/LICENSE b/packages/flac-encoder/LICENSE
new file mode 100644
index 0000000..d0a1fa1
--- /dev/null
+++ b/packages/flac-encoder/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ 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/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/packages/flac-encoder/README.md b/packages/flac-encoder/README.md
new file mode 100644
index 0000000..86cc470
--- /dev/null
+++ b/packages/flac-encoder/README.md
@@ -0,0 +1,140 @@
+# @mediabunny/flac-encoder
+
+[](https://www.npmjs.com/package/@mediabunny/flac-encoder)
+[](https://bundlephobia.com/package/@mediabunny/flac-encoder)
+[](https://www.npmjs.com/package/@mediabunny/flac-encoder)
+[](https://discord.gg/hmpkyYuS4U)
+
+
+

+
+
+No browser currently supports FLAC encoding in their WebCodecs implementations. This extension package provides a reliable FLAC encoder for use with [Mediabunny](https://github.com/Vanilagy/mediabunny). It is implemented using Mediabunny's [custom coder API](https://mediabunny.dev/guide/supported-formats-and-codecs#custom-coders) and uses a fast, size-optimized WASM build of [libFLAC](https://github.com/xiph/flac) under the hood.
+
+> This package, like the rest of Mediabunny, is enabled by its [sponsors](https://mediabunny.dev/#sponsors) and their donations. If you've derived value from this package, please consider [leaving a donation](https://github.com/sponsors/Vanilagy)! 💘
+
+## Installation
+
+This library peer-depends on Mediabunny. Install both using npm:
+```bash
+npm install mediabunny @mediabunny/flac-encoder
+```
+
+Alternatively, directly include them using a script tag:
+```html
+
+
+```
+
+This will expose the global objects `Mediabunny` and `MediabunnyFlacEncoder`. Use `mediabunny-flac-encoder.d.ts` to provide types for these globals. You can download the built distribution files from the [releases page](https://github.com/Vanilagy/mediabunny/releases).
+
+## Usage
+
+```ts
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+registerFlacEncoder();
+```
+That's it - Mediabunny now uses the registered FLAC encoder automatically.
+
+If you want to be more correct, check for native browser support first:
+```ts
+import { canEncodeAudio } from 'mediabunny';
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+if (!(await canEncodeAudio('flac'))) {
+ registerFlacEncoder();
+}
+```
+
+## Example
+
+Here, we convert an input file to a FLAC file:
+
+```ts
+import {
+ Input,
+ ALL_FORMATS,
+ BlobSource,
+ Output,
+ BufferTarget,
+ FlacOutputFormat,
+ canEncodeAudio,
+ Conversion,
+} from 'mediabunny';
+import { registerFlacEncoder } from '@mediabunny/flac-encoder';
+
+if (!(await canEncodeAudio('flac'))) {
+ registerFlacEncoder();
+}
+
+const input = new Input({
+ source: new BlobSource(file), // From a file picker, for example
+ formats: ALL_FORMATS,
+});
+const output = new Output({
+ format: new FlacOutputFormat(),
+ target: new BufferTarget(),
+});
+
+const conversion = await Conversion.init({
+ input,
+ output,
+});
+await conversion.execute();
+
+output.target.buffer; // => ArrayBuffer containing the FLAC file
+```
+
+For more ways of using Mediabunny, refer to its [guide](https://mediabunny.dev/guide/introduction).
+
+## Building and development
+
+For simplicity, all built WASM artifacts are included in the repo, since these rarely change. However, here are the instructions for building them from scratch:
+
+[Install Emscripten](https://emscripten.org/docs/getting_started/downloads.html), install CMake, and clone [libFLAC](https://github.com/xiph/flac). Then, from the Mediabunny root and with Emscripten sourced in:
+
+```bash
+export FLAC_PATH=/path/to/flac
+export MEDIABUNNY_ROOT=$PWD
+
+cd $FLAC_PATH
+mkdir -p build && cd build
+emcmake cmake .. \
+ -DBUILD_PROGRAMS=OFF \
+ -DBUILD_CXXLIBS=OFF \
+ -DBUILD_EXAMPLES=OFF \
+ -DBUILD_TESTING=OFF \
+ -DWITH_OGG=OFF \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DENABLE_MULTITHREADING=OFF \
+ -DINSTALL_MANPAGES=OFF \
+ -DCMAKE_C_FLAGS="-DNDEBUG -Oz -flto -msimd128"
+emmake make
+
+# Compile the bridge between JavaScript and libFLAC's API
+cd $MEDIABUNNY_ROOT/packages/flac-encoder
+emcc src/bridge.c \
+ $FLAC_PATH/build/src/libFLAC/libFLAC.a \
+ -I$FLAC_PATH/include \
+ -s MODULARIZE=1 \
+ -s EXPORT_ES6=1 \
+ -s SINGLE_FILE=1 \
+ -s ALLOW_MEMORY_GROWTH=1 \
+ -s ENVIRONMENT=web,worker \
+ -s FILESYSTEM=0 \
+ -s MALLOC=emmalloc \
+ -s SUPPORT_LONGJMP=0 \
+ -s EXPORTED_RUNTIME_METHODS=cwrap,HEAPU8 \
+ -s EXPORTED_FUNCTIONS=_malloc,_free \
+ -msimd128 \
+ -flto \
+ -Oz \
+ -o build/flac.js
+```
+
+This generates `build/flac.js`, which contains both the JavaScript "glue code" as well as the compiled WASM inlined.
+
+### Building the package
+
+Then, the complete JavaScript package can be built alongside the rest of Mediabunny by running `npm run build` in Mediabunny's root.
diff --git a/packages/flac-encoder/api-extractor.json b/packages/flac-encoder/api-extractor.json
new file mode 100644
index 0000000..fafe3a5
--- /dev/null
+++ b/packages/flac-encoder/api-extractor.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
+ "mainEntryPointFilePath": "dist/modules/src/index.d.ts",
+ "bundledPackages": [],
+ "compiler": {},
+ "apiReport": {
+ "enabled": false
+ },
+ "docModel": {
+ "enabled": false
+ },
+ "dtsRollup": {
+ "enabled": true,
+ "untrimmedFilePath": "dist/mediabunny-flac-encoder.d.ts"
+ },
+ "tsdocMetadata": {
+ "enabled": false
+ },
+ "messages": {
+ "compilerMessageReporting": {
+ "default": {
+ "logLevel": "warning"
+ }
+ },
+ "extractorMessageReporting": {
+ "default": {
+ "logLevel": "warning"
+ }
+ },
+ "tsdocMessageReporting": {
+ "default": {
+ "logLevel": "warning"
+ }
+ }
+ },
+ "newlineKind": "lf"
+}
diff --git a/packages/flac-encoder/build/flac.js b/packages/flac-encoder/build/flac.js
new file mode 100644
index 0000000000000000000000000000000000000000..da7014481e996fa95e46f93bf3fb4765bcafea98
GIT binary patch
literal 202256
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 OJnZ
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