CodecMedia is a pure Node.js port of the CodecMedia Java engine. It provides synchronous media probing, validation, metadata sidecar persistence, limited embedded metadata reads, dry-run playback workflow support, and lightweight conversion routing.
The package is still a work in progress. It aims to mirror codecmedia-java where Java behavior can be reasonably implemented in npm without native dependencies or external binaries.
- Current npm package version:
1.1.5 - Runtime: Node.js 18+
- Core implementation: pure JavaScript, no required native dependencies
- Default engine:
CodecMedia.createDefault()returnsStubCodecMediaEnginewithDefaultConversionHubwired by default - Test status in this working tree:
175tests passing withnpm test
probe(input) and get(input) return technical media information for these formats:
| Format | Current behavior |
|---|---|
| MP3 | Frame parser, duration estimate, bitrate mode, sample rate, channels |
| WAV | RIFF/RIFX/RF64 parser, PCM stream info, duration, bitrate |
| AIFF/AIF/AIFC | COMM chunk parser, PCM stream info, duration, bitrate |
| FLAC | STREAMINFO parser, duration, sample rate, channels, bits per sample |
| PNG | IHDR parser, width, height, bit depth, color type |
| JPEG/JPG | SOF parser, width, height, bit precision, channel count |
| WebP | VP8, VP8L, and VP8X dimension parser |
| BMP | DIB header parser, width, height, bits per pixel |
| TIFF/TIF | IFD parser for width, height, and first bits-per-sample value |
| HEIC/HEIF/AVIF | Basic BMFF brand parser plus ispe dimensions and pixi bit depth when present |
| MP4/M4A | Basic ISO BMFF parser for duration, video/audio streams, codecs, bitrate hints |
| MOV | Basic QuickTime/BMFF parsing through the MP4-family parser path |
| WebM | EBML/WebM parser for video/audio stream information |
Unknown formats still return a probe result based on extension when possible, with application/octet-stream and UNKNOWN media type as fallback.
validate(input, options) checks:
- null/missing input
- regular file existence
maxBytes- strict parser checks when
strict: trueand a parser is registered
Strict validation currently performs real parser checks for:
mp3, wav, aif, aiff, aifc, flac, png, jpg, jpeg, webp, bmp, tif, tiff, heic, heif, avif, mp4, m4a, and webm.
Important: ogg is still extension/sniff fallback only in the default npm engine, so strict validation for OGG is not Java-equivalent yet.
readMetadata(input) returns:
- derived probe fields:
mimeType,extension,mediaType - embedded metadata currently supported for:
- AIFF text chunks:
title,artist,copyright,comment - FLAC Vorbis comments:
title,artist,album,comment,genre,date
- AIFF text chunks:
- sidecar metadata from
<input>.codecmedia.properties
Sidecar keys do not override core probe fields or embedded fields.
writeMetadata(input, metadata) currently validates entries and writes sidecar metadata. Unlike codecmedia-java, this npm package does not yet write embedded WAV/AIFF/MP3 metadata back into the media file.
extractAudio(input, outputDir, options) is a limited workflow:
- accepts audio inputs only
- creates the output directory
- copies the source audio file to
<basename>_audio.<format> - requires
targetFormatto match the source format - does not transcode
convert(input, output, options) uses DefaultConversionHub by default.
Implemented routes:
- same-extension copy through
SameFormatCopyConverter wav <-> pcmbyte-copy stub- image-to-image route through
ImageTranscodeConverter - PNG codec registration is available for
png -> png
Guardrails:
ConversionOptions.targetFormatis required- output extension must match
targetFormat overwrite: falseblocks overwriting existing files
Unsupported routes throw CodecMediaException, including:
- real audio transcode such as
mp3 -> ogg video -> audiovideo -> videoaudio -> imageimage -> audio
play(input, options) supports:
dryRun: true- optional system default app launch when
allowExternalApp: true
Unlike Java, npm does not provide an internal Java sampled playback backend.
- OGG Vorbis/Opus detailed parser is not ported yet.
- MOV parsing is basic BMFF-style parsing, not a full separate Java
MovParserport. - Embedded metadata writes for WAV, AIFF, and MP3 are not ported; npm writes sidecar metadata instead.
- MP3 ID3 metadata reading/writing is not Java-equivalent yet.
- WAV INFO metadata read/write is not Java-equivalent yet.
- OGG/FLAC comment writing is not implemented.
- Real transcoding is not implemented without injecting external behavior.
- Internal playback is not equivalent to Java sampled playback.
- Optional
enableFfprobeEnhancementis documented as an option, but the default pure JS path does not require or executeffprobe.
npm install codecmediaimport { CodecMedia } from "codecmedia";
const engine = CodecMedia.createDefault();
const input = "./media/sample.mp4";
const probe = engine.probe(input);
console.log("Probe:", probe);
const validation = engine.validate(input, {
strict: true,
maxBytes: 500 * 1024 * 1024,
});
console.log("Validation:", validation);
const metadata = engine.readMetadata(input);
console.log("Metadata:", metadata);
engine.writeMetadata(input, {
entries: {
title: "Demo Title",
artist: "CodecMedia",
},
});
const playback = engine.play(input, {
dryRun: true,
allowExternalApp: false,
});
console.log("Playback:", playback);CodecMedia.createDefault(options?): create the default engine.get(input): alias ofprobe(input).probe(input): inspect technical media/container information.readMetadata(input): read probe-derived fields, limited embedded metadata, and sidecar metadata.writeMetadata(input, metadata): write sidecar metadata.extractAudio(input, outputDir, options): copy same-format audio into an output directory.convert(input, output, options): run limited conversion routing.play(input, options): dry-run playback or optionally open with the system app.validate(input, options): validate existence, size, and registered strict parsers.
npm testLatest local result:
> codecmedia@1.1.5 test
> node --test ./test/*.test.js
tests 175
suites 52
pass 175
fail 0
cancelled 0
skipped 0
todo 0
Run only conversion tests:
node --test ./test/convert.test.jsThis project is licensed under the Apache License 2.0.
by TamKungZ_
