node-lame
Version:
LAME MP3 encoder for Node.js
321 lines (314 loc) • 9.51 kB
text/typescript
import { EventEmitter } from 'events';
import { Duplex } from 'node:stream';
/**
* Runtime status information emitted by encoder/decoder progress updates.
*/
interface LameStatus {
started: boolean;
finished: boolean;
progress: number;
eta?: string;
}
/**
* Structured option bag accepted by the encoder.
*/
interface LameOptionsBag {
output: string | "buffer" | "stream";
raw?: boolean;
"swap-bytes"?: boolean;
"swap-channel"?: boolean;
gain?: number;
sfreq?: SampleFrequency;
bitwidth?: BitWidth;
signed?: boolean;
unsigned?: boolean;
"little-endian"?: boolean;
"big-endian"?: boolean;
mp1Input?: boolean;
mp2Input?: boolean;
mp3Input?: boolean;
mode?: ChannelMode;
"to-mono"?: boolean;
"channel-different-block-sizes"?: boolean;
freeformat?: boolean;
"disable-info-tag"?: boolean;
comp?: number;
scale?: number;
"scale-l"?: number;
"scale-r"?: number;
"replaygain-fast"?: boolean;
"replaygain-accurate"?: boolean;
"no-replaygain"?: boolean;
"clip-detect"?: boolean;
preset?: PresetProfile;
noasm?: NoAsm;
quality?: QualityLevel;
"quality-high"?: boolean;
"fast-encoding"?: boolean;
bitrate?: BitRate;
"max-bitrate"?: BitRate;
"force-bitrate"?: boolean;
cbr?: boolean;
abr?: number;
vbr?: boolean;
"vbr-quality"?: number;
"vbr-old"?: boolean;
"vbr-new"?: boolean;
"ignore-noise-in-sfb21"?: boolean;
emp?: Emphasis;
"mark-as-copyrighted"?: boolean;
"mark-as-copy"?: boolean;
"crc-error-protection"?: boolean;
nores?: boolean;
"strictly-enforce-ISO"?: boolean;
lowpass?: number;
"lowpass-width"?: number;
highpass?: number;
"highpass-width"?: number;
resample?: SampleFrequency;
"decode-mp3delay"?: number;
"nogap"?: string[];
"nogapout"?: string;
"nogaptags"?: boolean;
"out-dir"?: string;
priority?: PriorityLevel;
disptime?: number | false;
silent?: boolean;
quiet?: boolean;
verbose?: boolean;
help?: boolean | HelpTopic;
usage?: boolean | HelpTopic;
longhelp?: boolean;
version?: boolean;
license?: boolean;
"no-histogram"?: boolean;
meta?: MetaOptions;
}
type LameStreamMode = "encode" | "decode";
type LameStreamOptions = Omit<LameOptionsBag, "output"> & {
output?: "stream";
mode: LameStreamMode;
};
type SampleFrequency = 8 | 11.025 | 12 | 16 | 22.05 | 24 | 32 | 44.1 | 48;
type BitWidth = 8 | 16 | 24 | 32;
type ChannelMode = "s" | "j" | "f" | "d" | "m" | "l" | "r" | "a";
type PriorityLevel = 0 | 1 | 2 | 3 | 4;
type HelpTopic = "id3" | "dev";
type PresetProfile = string | number;
type NoAsm = "mmx" | "3dnow" | "sse";
type QualityLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type BitRate = 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 | 80 | 96 | 112 | 128 | 144 | 160 | 192 | 224 | 256 | 320;
type Emphasis = "n" | 5 | "c";
type CustomFrameRecord = Record<string, string | number | boolean> | Array<string | [string, string | number | boolean] | {
id: string;
value: string | number | boolean;
}>;
interface MetaOptions {
title?: string;
artist?: string;
album?: string;
year?: string;
comment?: string;
track?: string;
genre?: string;
"add-id3v2"?: boolean;
"id3v1-only"?: boolean;
"id3v2-only"?: boolean;
"id3v2-latin1"?: boolean;
"id3v2-utf16"?: boolean;
"space-id3v1"?: boolean;
"pad-id3v2"?: boolean;
"pad-id3v2-size"?: number;
"genre-list"?: string;
"ignore-tag-errors"?: boolean;
custom?: CustomFrameRecord;
}
interface LameProgressEmitter extends EventEmitter {
on(event: "progress", listener: (status: [number, string?]) => void): this;
on(event: "finish", listener: () => void): this;
on(event: "error", listener: (error: Error) => void): this;
once(event: "progress", listener: (status: [number, string?]) => void): this;
once(event: "finish", listener: () => void): this;
once(event: "error", listener: (error: Error) => void): this;
}
/**
* Translates option objects into the argument list expected by the LAME CLI.
*/
declare class LameOptions {
private readonly args;
private useDefaultDisptime;
/**
* Validate all options and build argument array for binary
* @param {Object} options
*/
constructor(options: LameOptionsBag);
/**
* Get all arguments for binary
*/
getArguments(): string[];
shouldUseDefaultDisptime(): boolean;
private raw;
private swapBytes;
private swapChannel;
private gain;
private sfreq;
private bitwidth;
private signed;
private unsigned;
private littleEndian;
private bigEndian;
private mp1Input;
private mp2Input;
private mp3Input;
private mode;
private toMono;
private channelDifferentBlockSize;
private freeformat;
private disableInfoTag;
private nogap;
private nogapout;
private nogaptags;
private outDir;
private comp;
private scale;
private scaleL;
private scaleR;
private replaygainFast;
private replaygainAccurate;
private noreplaygain;
private clipDetect;
private preset;
private invalidPreset;
private noasm;
private quality;
private qualityHigh;
private fastEncoding;
private bitrate;
private maxBitrate;
private forceBitrate;
private cbr;
private abr;
private vbr;
private vbrQuality;
private vbrOld;
private vbrNew;
private ignoreNoiseInSfb21;
private emp;
private markAsCopyrighted;
private markAsCopy;
private crcErrorProtection;
private nores;
private strictlyEnforceIso;
private lowpass;
private lowpassWidth;
private highpass;
private highpassWidth;
private resample;
private decodeMp3Delay;
private priority;
private disptime;
private silent;
private quiet;
private verbose;
private help;
private usage;
private longHelp;
private version;
private license;
private noHistogram;
private helpLike;
private meta;
private appendCustomFrames;
}
/**
* Thin wrapper around the LAME CLI that manages temp files, progress events,
* and output handling while delegating the heavy lifting to the binary.
*/
declare class Lame {
private status;
private readonly emitter;
private readonly options;
private readonly builder;
private filePath?;
private fileBuffer?;
private fileBufferTempFilePath?;
private progressedFilePath?;
private progressedBuffer?;
private progressedBufferTempFilePath?;
private lamePath;
private tempPath;
constructor(options: LameOptionsBag);
setFile(path: string): this;
setBuffer(file: Buffer | ArrayBuffer | ArrayBufferView): this;
setLamePath(path: string): this;
setTempPath(path: string): this;
getFile(): string;
getBuffer(): Buffer;
getEmitter(): LameProgressEmitter;
getStatus(): LameStatus;
encode(): Promise<this>;
decode(): Promise<this>;
/**
* Executes the CLI for the provided conversion type, handling buffers, files,
* and cleanup in case of errors.
*/
private executeConversion;
/**
* Spawns the LAME process and listens to progress updates, resolving once complete.
*/
private spawnLameAndTrackProgress;
private normalizeInputBuffer;
private convertArrayViewToBuffer;
private convertFloatArrayToBuffer;
private shouldUseBigEndian;
private isSignedForBitwidth;
private clampSample;
private scaleToSignedInteger;
private scaleToUnsignedInteger;
private persistInputBufferToTempFile;
private toUint8Array;
private prepareOutputTarget;
private ensureOutputDirectoryExists;
private generateTempFilePath;
private removeTempArtifacts;
}
type LameStreamConfig = Omit<LameStreamOptions, "output"> & {
binaryPath?: string;
};
declare class LameStream extends Duplex {
private readonly emitter;
private readonly status;
private readonly builder;
private readonly binaryPath?;
private readonly kind;
private child?;
private isStdoutPaused;
private hasErrored;
private finished;
constructor(options: LameStreamConfig);
getEmitter(): LameProgressEmitter;
getStatus(): LameStatus;
_read(): void;
_write(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
_final(callback: (error?: Error | null) => void): void;
_destroy(error: Error | null, callback: (error?: Error | null) => void): void;
private initialize;
private forwardStdout;
private handleSuccessfulClose;
private emitStreamError;
private cleanupChildListeners;
}
/**
* Attempt to resolve the absolute path to a bundled LAME binary.
* Returns null when no bundled binary could be found.
*/
declare function resolveBundledLameBinary(): string | null;
declare function resolveBundledLibraryDirectory(): string | null;
/**
* Resolve the binary to use. Preference order:
* 1. `LAME_BINARY` environment variable.
* 2. Bundled prebuilt binary located in `vendor/lame/<platform>-<arch>/`.
* 3. Fallback to the `lame` executable on PATH.
*/
declare function resolveLameBinary(): string;
export { Lame, LameOptions, type LameOptionsBag, type LameProgressEmitter, type LameStatus, LameStream, type LameStreamOptions, resolveBundledLameBinary, resolveBundledLibraryDirectory, resolveLameBinary };