rt-alpha-video turns a folder of PNG frames with alpha into:
folder-name.webm(VP9 + alpha)folder-name-hevc.mov(HEVC + alpha, taggedhvc1for Safari)folder-name.txt(ready-to-paste HTML + JS snippet that auto-detects WebM/HEVC at runtime)
Perfect for replacing heavy PNG image sequences with lightweight transparent video on the web.
Platform: macOS only
Input: PNG frames with alpha (RGBA)
Output: WebM + optional HEVC + snippet
Launch Web Helper
Use the browser-based helper to drag and drop your PNG frames, auto-detect the pattern and FPS, verify alpha, preview the loop, and generate a ready-to-runrt-alpha-videocommand.
Read more about the helper in Web helper.
- macOS (Apple Silicon or Intel)
- Node.js ≥ 16
Check Node:
node -vYour FFmpeg build must include:
libvpx-vp9hevc_videotoolbox(for HEVC + alpha via VideoToolbox)
Check:
ffmpeg -versionIf FFmpeg is missing but Homebrew exists, the CLI will offer to install FFmpeg automatically via:
brew install ffmpegIf Homebrew is not available, you’ll need to install FFmpeg manually.
Given a PNG sequence, rt-alpha-video will:
-
Detect the file pattern and start index Finds a common prefix/suffix between first and last filenames and infers the numeric run (e.g.
Frame_%05d.png+ starting index). -
Encode transparent video outputs
.webm(VP9 + alpha,yuva420p).mov(HEVC + alpha viahevc_videotoolbox, taggedhvc1), unless--no-hevcis provided or the encoder is unavailable.
-
Generate an HTML snippet (
.txt) A ready-to-paste snippet that auto-selects WebM vs HEVC at runtime based on codec support (Safari / iOS vs others). -
Print detailed stats Frame count, total PNG size, animation duration, final WebM/HEVC sizes, and per-encode times.
Install globally and use the rt-alpha-video command:
npm install -g @rethink-js/alpha-video-cliRun once without installing globally:
npx @rethink-js/alpha-video-cli --input ./frames --fps 50rt-alpha-video --input ./frames --fps 50Output folder:
frames/dist/
frames.webm
frames-hevc.mov
frames.txt
- The output folder defaults to
<input>/dist. - The base name defaults to the input folder name (normalized).
| Flag | Description |
|---|---|
--input <folder> |
Directory containing PNG frames |
--fps <number> |
Playback framerate |
| Flag | Description |
|---|---|
--output <folder> |
Custom output directory (default: <input>/dist) |
--pattern <pattern> |
Frame pattern e.g. Frame_%05d.png (otherwise inferred from filenames) |
--start <number> |
First frame index for the pattern (-start_number in FFmpeg). Defaults from detection |
--end <number> |
Last frame index to include (inclusive). Limits encoding to this range |
--width <number> |
Resize video width; if height is omitted, a square output is produced |
--height <number> |
Resize video height; if width is omitted, a square output is produced |
--name <basename> |
Base name for output files (default: input folder name, lowercased, spaces → dashes) |
--webm-quality <1-100> |
Logical WebM quality (maps to CRF internally; default: 50) |
--hevc-quality <1-100> |
Logical HEVC alpha quality (maps to -alpha_quality internally; default: 90) |
--no-hevc |
Disable HEVC .mov encoding (WebM only) |
--quiet |
Suppress progress bars and extra logs (FFmpeg still runs, but with minimal console output) |
--help, -h |
Help menu |
Notes:
- If you pass only width or only height, the CLI produces a square output and warns if you upscale above the source PNG dimensions.
--enddoes not change pattern detection; it only clamps how many frames are actually encoded.
- Logical default: 50 (
--webm-quality 50) - Internally mapped to: CRF ≈ 28
- CRF range used: 18 → 38 (Lower CRF = higher quality, larger files.)
- Logical default: 90 (
--hevc-quality 90) - Internally mapped to:
-alpha_quality 0.9 - Range: 0.1 → 1.0 (Higher = better alpha quality, larger files.)
Your PNG frames should:
- Include an alpha channel (RGBA)
- Follow consistent numbering (with a stable prefix/suffix)
- Use a detectable pattern, e.g.
Frame_00001.png → Frame_00350.png - Or you explicitly provide the pattern with
--pattern
Example:
Frame_00000.png
Frame_00001.png
Frame_00002.png
...
Frame_00349.png
The CLI:
- Reads the first and last PNG filenames,
- Finds the shared prefix and suffix,
- Detects the numeric run in the middle,
- Builds a pattern like
Frame_%05d.png, - And infers the starting index (e.g.
0).
If multiple numeric segments exist, it picks the first segment that actually changes between the first and last filenames.
A .txt file is generated alongside your video encodes. This file contains:
-
A minimal HTML document
-
A
<video>element with a<source>child -
A small script that:
- Detects Safari / iOS vs other browsers
- Checks actual codec support
- Picks the best between WebM (VP9) and HEVC (hvc1) at runtime
- Attempts to autoplay safely
Example excerpt (simplified):
<video id="rt-alpha-video" muted autoplay loop playsinline poster="">
<source src="" type="" />
</video>
<script>
(function () {
var video = document.getElementById("rt-alpha-video");
if (!video) return;
var sourceEl = video.querySelector("source");
if (!sourceEl) return;
var webmSrc = "my-animation.webm";
var hevcSrc = "my-animation-hevc.mov";
var ua = navigator.userAgent || "";
var isIOS = /iPad|iPhone|iPod/.test(ua);
var isSafariDesktop = /^((?!chrome|android).)*safari/i.test(ua);
var isSafariEngine = isIOS || isSafariDesktop;
var canPlayHevc = video.canPlayType('video/mp4; codecs="hvc1"');
var canPlayWebm =
video.canPlayType('video/webm; codecs="vp9"') ||
video.canPlayType("video/webm");
var finalSrc = webmSrc;
var finalType = 'video/webm; codecs="vp9"';
if (isSafariEngine && canPlayHevc) {
finalSrc = hevcSrc;
finalType = 'video/mp4; codecs="hvc1"';
} else if (!canPlayWebm && canPlayHevc) {
finalSrc = hevcSrc;
finalType = 'video/mp4; codecs="hvc1"';
}
sourceEl.src = finalSrc;
sourceEl.type = finalType;
video.load();
var p = video.play();
if (p && typeof p.then === "function") {
p.catch(function () {});
}
})();
</script>To use:
-
Copy the contents of
your-base-name.txt. -
Paste into your project:
- Either as a full HTML file for testing, or
- Extract just the
<video>+<script>block into your component/template.
-
Update
webmSrc/hevcSrc(andposter, if desired) to match your hosting paths.
Error example:
ffmpeg is not installed and Homebrew is not available.
Fix:
- Install FFmpeg (via Homebrew or manually).
- Re-run
rt-alpha-video.
If you see:
No .png files found in input directory: <path>
Check:
- The
--inputpath is correct. - The directory actually contains
.pngfiles. - The extension is
.png(not.PNGwith some mismatch — though case-insensitive matching is used).
If automatic pattern detection fails:
Could not infer numeric pattern from files.
First file: Frame_final.png
Fix: specify the pattern manually:
rt-alpha-video \
--input ./frames \
--fps 50 \
--pattern "Frame_%05d.png" \
--start 0Possible reasons:
- You passed
--no-hevc hevc_videotoolboxencoder is not available in your FFmpeg build- Your FFmpeg build is too old or compiled without VideoToolbox
The CLI will still encode WebM and print a message such as:
Skipping HEVC encode: hevc_videotoolbox encoder not available in ffmpeg on this system.
Minimal:
rt-alpha-video \
--input "/path/to/frames" \
--fps 50Full-options example:
rt-alpha-video \
--input "/path/to/frames" \
--output "/path/to/output" \
--fps 50 \
--pattern "Frame_%05d.png" \
--start 0 \
--end 349 \
--width 500 \
--height 500 \
--name "frame-preview" \
--webm-quality 72 \
--hevc-quality 95Then:
- Drop the
.webmand.movfiles into your preferred hosting (CDN, static folder, etc.). - Copy HTML/JS from the generated
.txtfile into your site.
A visual companion tool for rt-alpha-video
(no installation required — runs entirely in your browser).
https://rethink-js.github.io/alpha-video-cli-web-helper
https://github.com/Rethink-JS/alpha-video-cli-web-helper
The web helper provides:
-
Drag and drop folder analysis Detects sequences directly from your PNG files.
-
Pattern detection Automatically identifies patterns (for example
%05d), start frames, and end frames using the same logic as the CLI. -
FPS auto-detection Attempts to estimate the most likely frame rate (24, 25, 30, 48, 50, 60) from total frame count.
-
Transparency verification Checks the alpha channel of your frames so you don’t accidentally encode opaque videos.
-
Live canvas preview Loops the sequence so you can confirm smoothness and transitions before encoding.
-
Smart defaults Mirrors CLI defaults (FPS, quality settings, naming).
-
One-click command generation Outputs a full, ready-to-run terminal command string for
rt-alpha-video.
- 100% client-side.
- No files ever uploaded.
- Uses browser memory only.
- No external servers or third-party processing.
Due to browser security, the helper cannot read absolute paths (such as /Users/username/Desktop/project/frames). It only sees relative folder names (for example frames).
- The helper will suggest a relative path like
./frames. - If you run the command from the parent directory of your frames folder, this works as-is.
- Otherwise, replace
--inputwith your actual absolute path.
Tip for macOS: drag a folder from Finder into Terminal to paste its absolute path.
-
Improved pattern detection logic:
- Uses a shared prefix/mid/suffix comparison between first and last frames
- Handles multiple numeric segments more robustly
-
Added explicit
--widthand--heightflags with square-output behaviour when only one dimension is set -
Added a warning when requested resize dimensions upscale beyond the source PNG size
-
Extended summary output with:
- Total PNG size
- Per-encode duration for WebM and HEVC
-
Updated HTML preview snippet to:
- Use
<source>with runtime codec selection - Prefer HEVC (
hvc1) on Safari / iOS when supported, otherwise WebM
- Use
-
Minor improvements to progress output and quiet mode handling
-
Added
--end(frame end index) -
Updated defaults:
- Defaults now map exactly to previous internal quality
-
Added full Web Helper documentation
- Stable public release
- Pattern detection
- WebM + HEVC encoding
- Snippet generation
- Stronger errors
- Initial preview
- Basic encoding pipeline
MIT License
Package: @rethink-js/alpha-video-cli
GitHub: https://github.com/Rethink-JS/alpha-video-cli
by Rethink JS https://github.com/Rethink-JS