Releases: GlobalTechInfo/mediaforge
mediaforge v0.3.0
Added
New analysis helpers (src/helpers/normalize.ts)
| Helper | Description |
|---|---|
detectSilence(opts) |
Parse silencedetect filter output into structured timestamp arrays |
detectScenes(opts) |
Scene change detection using select filter + showinfo metadata |
cropDetect(opts) |
Letterbox/pillarbox detection helper; returns crop detection results |
burnTimecode(opts) |
Draw timecode using drawtext with timecode expression |
parseLoudnorm(opts) |
Parse EBU R128 loudnorm output with integrated/loudness/dynamic metadata |
New export helpers (src/helpers/screenshots.ts)
| Helper | Description |
|---|---|
extractFrames(opts) |
Export all frames as images with fps control and filename templating |
New concat features (src/helpers/concat.ts)
| Helper | Description |
|---|---|
concatWithTransitions(opts) |
Concatenate video clips with crossfade/xfade transitions between them |
New metadata helpers (src/helpers/metadata.ts)
| Helper | Description |
|---|---|
addChapters(opts) |
Convenience wrapper over writeMetadata for chapter timestamps |
New video filters (src/filters/video/index.ts)
| Filter | FFmpeg filter | Notes |
|---|---|---|
drawbox(chain, opts?) |
drawbox |
Draw colored boxes/frames on video |
drawgrid(chain, opts?) |
drawgrid |
Draw a grid overlay |
vignette(chain, opts?) |
vignette |
Apply vignette effect |
vaguedenoiser(chain, opts?) |
vaguedenoiser |
Wavelet-based denoising |
New audio filters (src/filters/audio/index.ts)
| Filter | FFmpeg filter | Notes |
|---|---|---|
headphones(chain, opts?) |
headphones |
Virtual headphone Surround sound from stereo |
sofalizer(chain, opts?) |
sofalizer |
SOFA file-based 3D audio virtualization |
FFmpegBuilder improvements
FFmpegBuilder.dry()- Return CLI arguments without executing (for debugging/preview)FFmpegBuilder.dryCommand()- Return CLI string without executing
Battle test additions
- Section 28: New helpers (extractFrames, concatWithTransitions, detectSilence, detectScenes, cropDetect, burnTimecode, parseLoudnorm)
- Section 29: New video filters (drawbox, drawgrid, vignette, vaguedenoiser)
- Section 30: New audio filters (headphones, sofalizer)
- Section 31: FFmpegBuilder.dry() and dryCommand()
Not implemented (deferred to future releases)
- Browser/edge runtime compatibility — fetch-based ffprobe, no child_process. Requires significant refactoring of process spawning layer.
- Plugin/middleware system — for custom filters. Requires design work for safe extensibility.
Fixed
- Lint warning: unused
formatVersionvariable in FFmpegBuilder cropDetect—cropdetectfilter used invalid optionreset_count(removed in FFmpeg 7+). Filter is nowcropdetect=limit=24:round=2which works on FFmpeg 6, 7, and 8.concatWithTransitions—scale=iwis not a valid FFmpeg filter size when no resolution specified. Changed toscale=iw:ih(no-op passthrough) whenresolutionoption is omitted.aacToArgs— added missingprofileoption (-profile:a) toAacOptionsinterface (aac_low,aac_he,aac_he_v2,aac_ld,aac_eld).vp9ToArgs— added missingdeadlineoption (-deadline) toVp9Optionsinterface (best,good,realtime).truehdToArgs—profileoption was incorrectly inserted intoTruehdOptions(TypeScript error: property does not exist). Removed.- README —
detectScenesdocs referenced non-existentminFramesoption andscenes.timestampsproperty. Fixed to match actual API:SceneChange[]with{timestamp, sceneNumber}. - README —
detectSilencedocs usedminDurationwhich does not exist; correct option isduration. - README — filter count corrected from 54 to 75 (49 video + 26 audio).
- README —
drawbox,drawgrid,vignette,vaguedenoiserincorrectly documented as chain-only (❌ standalone); all four have standalone overloads (✅). - Battle tests — comprehensive real-FFmpeg test suite covering all 286 exports (559 Node.js tests, 422 Deno tests). Previous tests only verified exports existed.
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
mediaforge v0.1.0
See CHANGELOG.md for details.
v0.0.1
Full Changelog: https://github.com/GlobalTechInfo/mediaforge/commits/v0.0.1