mediaforge v0.2.0
Breaking Changes
buildWaveformFilter — draw and backgroundColor parameters are now no-ops
Affects: buildWaveformFilter(width, height, color, scale, mode, streamIndex, backgroundColor?) and generateWaveform({ mode, backgroundColor }).
FFmpeg 7.x completely removed the bgcolor and draw options from showwavespic. Passing them causes an immediate error. Both parameters are now silently ignored — the mode argument and backgroundColor option are accepted for API compatibility but have no effect on the generated filter string.
If your code relied on draw=point or draw=p2p modes for waveform rendering, you will need to use the showwaves filter (which still supports these modes) via ffmpeg().complexFilter() directly.
Tests that asserted f.includes('draw=p2p') have been updated to assert !f.includes('draw=').
Typed codec serializers — video (8 new helpers)
Previously the library had typed helpers for only 4 video encoders (libx264, libx265, libsvtav1, libvpx-vp9).
Both FFmpeg v7 and v8 ship all of the following on every tested platform.
| Helper | Encoder string | Use case |
|---|---|---|
proResToArgs(opts?, encoder?) |
prores_ks, prores_aw, prores |
Apple ProRes — professional mastering |
dnxhdToArgs(opts?) |
dnxhd |
Avid DNxHD/DNxHR — Avid workflows |
mjpegToArgs(opts?) |
mjpeg |
Motion JPEG — frame editing, surveillance |
mpeg2ToArgs(opts?) |
mpeg2video |
MPEG-2 — broadcast/DVD/Blu-ray |
mpeg4ToArgs(opts?, encoder?) |
mpeg4, libxvid |
MPEG-4 Part 2 — legacy wide compat |
vp8ToArgs(opts?) |
libvpx |
VP8 — WebM, WebRTC |
theoraToArgs(opts?) |
libtheora |
Ogg Theora — patent-free |
ffv1ToArgs(opts?) |
ffv1 |
FFV1 — lossless archival |
All functions are exported from the top-level package and fully documented with TypeDoc.
Typed codec serializers — audio (7 new helpers)
| Helper | Encoder string | Use case |
|---|---|---|
alacToArgs(opts?) |
alac |
Apple Lossless — Apple ecosystem |
eac3ToArgs(opts?) |
eac3 |
Dolby Digital Plus — Netflix/Amazon |
truehdToArgs(opts?) |
truehd |
Dolby TrueHD — Blu-ray lossless |
vorbisToArgs(opts?) |
libvorbis |
Ogg Vorbis — open/patent-free |
wavpackToArgs(opts?) |
wavpack |
WavPack — hybrid lossless |
pcmToArgs(format, opts?) |
pcm_s16le, pcm_s24le, pcm_f32le, … |
Raw PCM — WAV masters, 16 variants |
mp2ToArgs(opts?) |
mp2 |
MPEG Audio Layer 2 — DVB broadcast |
Typed codec serializers — hardware (2 new helpers)
| Helper | Codec strings | Platform |
|---|---|---|
mediacodecVideoToArgs(opts, codec?) |
h264_mediacodec, hevc_mediacodec, av1_mediacodec, mpeg4_mediacodec, vp8_mediacodec, vp9_mediacodec |
Android (FFmpeg v8 / Termux) |
vulkanVideoToArgs(opts, codec?) |
h264_vulkan, hevc_vulkan, av1_vulkan, ffv1_vulkan, prores_ks_vulkan |
Linux + Android Vulkan |
Battle test suite (battle.test.mjs)
The external battle test that covers every documented export has been incorporated into the repository root. Run with npm run battle. The suite also covers all 22 new codec helpers added in this release.
Coverage tests
Unit test coverage added for all 17 new codec serializers in tests/unit/codecs/codecs.serializers.test.ts.
Fixed (runtime — discovered during battle test)
-
CapabilityRegistry.hasCodecreturned false for encoder names —ffmpeg -codecslists codec family names (h264,mp3) while users pass individual encoder names (libx264,h264_nvenc,libmp3lame) to-c:v/-c:a. TheguardCodecfunction callshasCodecfirst; when it returned false,canEncodewas never reached and every encoder-named codec was marked unavailable. Fixed by: (1) parsing the(encoders: libx264 h264_nvenc ...)parenthetical fromffmpeg -codecsoutput into an encoder name set, and (2) makinghasCodeccheck both the codec-family map and the encoder-name set.selectVideoCodec/selectBestCodecnow correctly resolvelibx264and all other encoder-named codecs. This also fixescheckCodec('libx264', 'encode')returningavailable: false. -
streamToFile— added-fflags +genptsalongside-analyzeduration 100M -probesize 100Mfor better frame timestamp recovery when piping non-faststart MP4 files -
adaptiveHls— now callsmkdirSyncon each variant subdirectory before running FFmpeg; FFmpeg silently fails if output dirs do not exist -
dashPackage— removedmin_buffer_time,use_template,use_timeline; all removed from FFmpeg DASH muxer in v7.x -
parseFrameRate— return type changed fromParsedFrameRate | null({num,den,value}object) tonumber | null.ParsedFrameRateis now atypealias fornumber(breaking: code accessing.value/.num/.denmust use the value directly) -
selectBestCodec— now returns the last no-featureKeycandidate as software fallback instead ofnull, soselectVideoCodecalways resolves to a string on any machine -
mapStream(fileIndex, type, streamIndex?)— new three-argument overload returning a plain string; original single-argument tuple form unchanged -
scale,crop,overlay,drawtext,fade— standalone call form added:scale({w:320,h:180})returns a serialized string.ScaleOptions/CropOptionsacceptw/hshorthand -
volume,loudnorm,equalizer,atempo— standalone call form added:loudnorm({i:-16,lra:11,tp:-1.5})returns serialized string -
FFmpegBuilder.videoFilter/.audioFilter— acceptstring | FilterChain | {toString()}so standalone filter results pass directly:.videoFilter(scale({w:320,h:180}))
Added (testing)
deno-tests/battle.test.ts— full Deno battle test mirroringbattle.test.mjs, imports fromlib/TypeScript sources. Run:deno task battledeno task battleindeno.json
Fixed (carried forward from 0.1.x patch series)
streamToFile— no longer routes throughpipeThrough(), which incorrectly appendedpipe:1alongside the file path output, causing FFmpeg to error withUnable to choose an output format for 'pipe:1'addWatermark— fixed trailing-comma bug in filter chain builder that produced an empty filter name'', rejected by FFmpeg 8.x withNo such filter: ''generateWaveform—bgcoloranddrawparameters removed entirely; FFmpeg 7.x+ removed both fromshowwavespic. ThebackgroundColorandmodeoptions are kept in the interface for API compatibility but are now deprecated no-ops- Version parser (
parseVersionOutput) — regex updated to handle 2-component version strings like8.1(FFmpeg 8.x), fixingmajorreturning0which broke all version-gated features hlsPackage/adaptiveHls—-hls_versionflag removed; FFmpeg 8.x removed this option entirelytwoPassEncode— pass 1 output changed from-f null /dev/nullto a temporary MKV file, fixingratecontrol_init: can't open stats fileon ARM Linux (both Android Termux FFmpeg 8.x and Ubuntu ARM FFmpeg 7.x)dashPackage—min_buffer_time,use_template,use_timelineflags removed; all were dropped from the DASH muxer in FFmpeg 8.x