Skip to content

mediaforge v0.2.0

Choose a tag to compare

@github-actions github-actions released this 14 Apr 12:19
· 3 commits to main since this release

Breaking Changes

buildWaveformFilterdraw 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.hasCodec returned false for encoder namesffmpeg -codecs lists codec family names (h264, mp3) while users pass individual encoder names (libx264, h264_nvenc, libmp3lame) to -c:v/-c:a. The guardCodec function calls hasCodec first; when it returned false, canEncode was never reached and every encoder-named codec was marked unavailable. Fixed by: (1) parsing the (encoders: libx264 h264_nvenc ...) parenthetical from ffmpeg -codecs output into an encoder name set, and (2) making hasCodec check both the codec-family map and the encoder-name set. selectVideoCodec/selectBestCodec now correctly resolve libx264 and all other encoder-named codecs. This also fixes checkCodec('libx264', 'encode') returning available: false.

  • streamToFile — added -fflags +genpts alongside -analyzeduration 100M -probesize 100M for better frame timestamp recovery when piping non-faststart MP4 files

  • adaptiveHls — now calls mkdirSync on each variant subdirectory before running FFmpeg; FFmpeg silently fails if output dirs do not exist

  • dashPackage — removed min_buffer_time, use_template, use_timeline; all removed from FFmpeg DASH muxer in v7.x

  • parseFrameRate — return type changed from ParsedFrameRate | null ({num,den,value} object) to number | null. ParsedFrameRate is now a type alias for number (breaking: code accessing .value/.num/.den must use the value directly)

  • selectBestCodec — now returns the last no-featureKey candidate as software fallback instead of null, so selectVideoCodec always 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/CropOptions accept w/h shorthand

  • volume, loudnorm, equalizer, atempo — standalone call form added: loudnorm({i:-16,lra:11,tp:-1.5}) returns serialized string

  • FFmpegBuilder.videoFilter / .audioFilter — accept string | 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 mirroring battle.test.mjs, imports from lib/ TypeScript sources. Run: deno task battle
  • deno task battle in deno.json

Fixed (carried forward from 0.1.x patch series)

  • streamToFile — no longer routes through pipeThrough(), which incorrectly appended pipe:1 alongside the file path output, causing FFmpeg to error with Unable 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 with No such filter: ''
  • generateWaveformbgcolor and draw parameters removed entirely; FFmpeg 7.x+ removed both from showwavespic. The backgroundColor and mode options 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 like 8.1 (FFmpeg 8.x), fixing major returning 0 which broke all version-gated features
  • hlsPackage / adaptiveHls-hls_version flag removed; FFmpeg 8.x removed this option entirely
  • twoPassEncode — pass 1 output changed from -f null /dev/null to a temporary MKV file, fixing ratecontrol_init: can't open stats file on ARM Linux (both Android Termux FFmpeg 8.x and Ubuntu ARM FFmpeg 7.x)
  • dashPackagemin_buffer_time, use_template, use_timeline flags removed; all were dropped from the DASH muxer in FFmpeg 8.x