{"id":11222,"library":"lamejs","title":"lamejs","description":"lamejs is a pure JavaScript MP3 encoder library, initially a rewrite of jump3r-code which itself was based on libmp3lame. It enables client-side and server-side (Node.js) encoding of raw PCM audio data (specifically Int16Array samples) into MP3 format. The project highlights its performance, claiming to be significantly faster than real-time on various machines and environments (browser and Node.js). The current stable version is 1.2.1, released after a considerable hiatus, primarily to address a TypeScript compatibility issue. Its release cadence is slow, suggesting a maintenance rather than actively developed status. Key differentiators include its pure JavaScript implementation, making it suitable for browser-based audio processing without WASM, and its reported high encoding speed. It's particularly useful for scenarios requiring on-the-fly MP3 generation from Web Audio API outputs or other PCM sources.","status":"maintenance","version":"1.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/zhuker/lamejs","tags":["javascript","mp3","encoder","audio","webaudio"],"install":[{"cmd":"npm install lamejs","lang":"bash","label":"npm"},{"cmd":"yarn add lamejs","lang":"bash","label":"yarn"},{"cmd":"pnpm add lamejs","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"When using ESM or TypeScript, import all exports as a namespace 'lamejs' to access `Mp3Encoder`. A default import is incorrect as 'lamejs' does not provide a default export.","wrong":"import lamejs from 'lamejs';","symbol":"lamejs","correct":"import * as lamejs from 'lamejs';"},{"note":"The primary class for encoding is `Mp3Encoder`. Ensure it's imported as a named export from the library, especially in TypeScript or modern JavaScript.","wrong":"import { LamejsMp3Encoder } from 'lamejs';","symbol":"Mp3Encoder","correct":"import { Mp3Encoder } from 'lamejs';"},{"note":"For CommonJS environments (like older Node.js scripts), use `require('lamejs')` to get the module object, then access `lamejs.Mp3Encoder`. Destructuring directly like `{ Mp3Encoder }` from `require('lamejs')` does not work as the module exports the full object.","wrong":"const { Mp3Encoder } = require('lamejs');","symbol":"lamejs","correct":"const lamejs = require('lamejs');"},{"note":"In browser environments using the bundled `lame.all.js` script, the `lamejs` object is exposed globally.","symbol":"Global Access","correct":"<script src='lame.all.js'></script>\n<script>\n  const encoder = new lamejs.Mp3Encoder(...);\n</script>"}],"quickstart":{"code":"import { Mp3Encoder } from 'lamejs';\n\nconst channels = 1; // 1 for mono, 2 for stereo\nconst sampleRate = 44100; // 44.1khz (normal mp3 samplerate)\nconst kbps = 128; // encode 128kbps mp3\n\n// Create a new MP3 encoder instance\nconst mp3encoder = new Mp3Encoder(channels, sampleRate, kbps);\n\n// Create some dummy audio samples (one second of silence in Int16Array)\nconst samples = new Int16Array(sampleRate * channels);\n\nconst sampleBlockSize = 1152; // Can be anything, but multiple of 576 is efficient\nconst mp3Data = [];\n\n// Process audio samples in chunks\nfor (let i = 0; i < samples.length; i += sampleBlockSize) {\n  const sampleChunk = samples.subarray(i, i + sampleBlockSize);\n  const mp3buf = mp3encoder.encodeBuffer(sampleChunk);\n  if (mp3buf.length > 0) {\n    mp3Data.push(mp3buf);\n  }\n}\n\n// Flush the encoder to get any remaining data\nconst mp3buf = mp3encoder.flush();\nif (mp3buf.length > 0) {\n    mp3Data.push(new Int8Array(mp3buf)); // Ensure it's Int8Array for Blob creation\n}\n\n// For browser environments, you can create a Blob and a URL\n// const blob = new Blob(mp3Data, { type: 'audio/mp3' });\n// const url = window.URL.createObjectURL(blob);\n// console.log('Generated MP3 URL:', url);\n\n// In Node.js, you might write to a file system\n// import { writeFileSync } from 'fs';\n// writeFileSync('output.mp3', Buffer.concat(mp3Data.map(arr => Buffer.from(arr))));\n\nconsole.log('MP3 encoding complete. Total buffers:', mp3Data.length);\nconsole.log('First buffer length:', mp3Data[0]?.length || 0);\n","lang":"typescript","description":"This quickstart demonstrates how to initialize the Mp3Encoder, feed it audio samples in chunks, and then flush the buffer to finalize the MP3 data. It covers both mono encoding and the necessary steps to collect the encoded segments."},"warnings":[{"fix":"Ensure all audio input data is converted to `Int16Array` format before passing it to `encodeBuffer`. For Web Audio API `AudioBuffer`s, multiply by `32767` and `Math.min(1, Math.max(-1, value))` to clamp, then cast to `Int16Array`.","message":"lamejs expects audio samples as `Int16Array`. Providing `Float32Array` (common from Web Audio API) or other formats will lead to incorrect or silent output without explicit errors, requiring manual conversion.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For TypeScript, use `import * as lamejs from 'lamejs';` or `import { Mp3Encoder } from 'lamejs';` for proper type inference and module resolution. Update `tsconfig.json` if needed to ensure correct `moduleResolution` (e.g., `NodeNext`).","message":"When migrating from older versions of lamejs (e.g., pre-1.2.1) to 1.2.1+ in a TypeScript project, direct `require` statements or global `lamejs` access might conflict with improved type definitions, leading to compilation errors or incorrect module resolution.","severity":"breaking","affected_versions":">=1.2.1"},{"fix":"Always call `mp3encoder.flush()` once all `encodeBuffer()` calls are complete and append the returned `Int8Array` to your collected MP3 data.","message":"It is crucial to call `mp3encoder.flush()` after all audio samples have been processed. Failing to flush will result in an incomplete or corrupted MP3 file, as the encoder might hold remaining buffered data internally.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When segmenting your audio samples, try to use a `sampleBlockSize` of 1152 for stereo (2*576) or 576 for mono, or at least a multiple of 576 where possible.","message":"lamejs typically expects a `sampleBlockSize` that is a multiple of 576 for optimal performance and encoding efficiency, especially for stereo. While other sizes work, non-multiples can lead to less efficient processing.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For CommonJS, use `const lamejs = require('lamejs');`. For ESM/TypeScript, use `import * as lamejs from 'lamejs';` or `import { Mp3Encoder } from 'lamejs';`.","cause":"Attempting to access `lamejs.Mp3Encoder` from an incorrectly imported or required `lamejs` module in CommonJS or ESM.","error":"TypeError: Cannot read properties of undefined (reading 'Mp3Encoder')"},{"fix":"Convert `Float32Array` samples to `Int16Array` before passing them to `encodeBuffer`. Example: `const int16Samples = new Int16Array(float32Samples.length); for (let i = 0; i < float32Samples.length; i++) { int16Samples[i] = Math.max(-1, Math.min(1, float32Samples[i])) * 0x7FFF; }`","cause":"TypeScript compilation error when passing Web Audio API `Float32Array` buffers directly to `encodeBuffer`.","error":"Argument of type 'Float32Array' is not assignable to parameter of type 'Int16Array'."},{"fix":"Ensure `mp3encoder.flush()` is called after all `encodeBuffer` calls, and its `Int8Array` result is included in the final MP3 data array.","cause":"The `flush()` method was not called, or its output was not appended to the final MP3 data.","error":"Encoded MP3 file is truncated or silent after playback starts."}],"ecosystem":"npm"}