
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@shelby-protocol/media-prepare
Advanced tools
FFmpeg presets and a declarative builder for CMAF + HLS: multi‑rung ladders, multi‑audio, trickplay, safe segment sizing, and clean `var_stream_map`. The library produces FFmpeg argument arrays only — no manual folder or manifest creation — and works in b
FFmpeg presets and a declarative builder for CMAF + HLS: multi‑rung ladders, multi‑audio, trickplay, safe segment sizing, and clean var_stream_map. The library produces FFmpeg argument arrays only — no manual folder or manifest creation — and works in both Node (native FFmpeg) and the browser (FFmpeg.wasm).
We use CMAF + HLS for broad device/DRM support: HLS provides the playlists and CMAF provides fragmented MP4 media segments (.m4s).
Subpath exports
@shelby-protocol/media-prepare/core — platform-agnostic utilities and Zod schemas@shelby-protocol/media-prepare/node — Node helpers (ffmpeg executor, system checks, media probe)@shelby-protocol/media-prepare/browser — Browser helpers (FFmpeg.wasm executor, probe)Key points
z.infer.withLadder, withAudio, withTrickplay, withSegments.This package uses tsup for builds and Biome for lint/format.
# Install dependencies
pnpm install
# Build the package
pnpm run build
# Run linting
pnpm run lint
# Auto-fix linting issues
pnpm run fmt
# Run tests (core + browser shim)
pnpm test
# Run local system tests (requires FFmpeg installed)
pnpm test:local
# Run browser tests with Playwright
pnpm test:browser
pnpm test — Fast unit tests (core logic, HLS+CMAF builder), CI‑safepnpm test:browser — Browser tests using Playwright; runs FFmpeg.wasm in real browserpnpm test:local — System integration tests that execute your local FFmpeg (requires FFmpeg installed)Local tests expect FFmpeg v7+ with encoders like libx264/libx265/libaom; they're excluded from CI.
The browser tests validate that the generated args are compatible with FFmpeg.wasm and can produce actual HLS+CMAF output.
import { planHlsCmaf, x264, aac, presets } from "@shelby-protocol/media-prepare/core/hls-cmaf";
import { execFfmpeg } from "@shelby-protocol/media-prepare/node";
import * as fs from "node:fs/promises";
const plan = planHlsCmaf()
.input("input.mp4")
.outputDir("out")
.withLadder(presets.vodHd_1080p)
.withVideoEncoder(x264())
.withAudio(aac(), { language: "eng", bitrateBps: 128_000, default: true })
.withSegments({ mode: "auto", maxBlobBytes: 10 * 1024 * 1024, safety: 0.9, minSeconds: 1, align: 1 })
.hlsCmaf()
.render.ffmpegArgs();
// Execute ffmpeg
await fs.rm(plan.outputDir, { recursive: true, force: true });
await execFfmpeg(plan.args, { precreate: plan.variantNames.map(name => `${plan.outputDir}/${name}`) });
import { planHlsCmaf } from "@shelby-protocol/media-prepare/core/hls-cmaf";
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { toBlobURL, fetchFile } from "@ffmpeg/util";
const plan = planHlsCmaf()
.input("input.mp4")
.outputDir("/out")
.withLadder([{ width: 854, height: 480, bitrateBps: 1_000_000, name: "480p" }])
.withVideoEncoder({ kind: "copy" }) // copy‑mode recommended in wasm
.withSegments({ mode: "fixed", segmentSeconds: 4 })
.hlsCmaf()
.render.ffmpegArgs();
const ffmpeg = new FFmpeg();
const baseURL = "https://unpkg.com/@ffmpeg/core@0.12.9/dist/esm";
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, "application/wasm"),
});
await ffmpeg.writeFile("input.mp4", await fetchFile(file));
// Create output directories
for (const variant of plan.variantNames) {
await ffmpeg.createDir(`/out/${variant}`);
}
await ffmpeg.exec(plan.args);
For Node.js usage, ensure you have:
Install on macOS:
brew install ffmpeg
For Shaka Packager, download from https://github.com/shaka-project/shaka-packager. Get it from the Releases page https://github.com/shaka-project/shaka-packager/releases
The SystemChecker utility will validate your system setup and provide installation guidance for your platform.
Common Misconception: "WebAssembly runs everywhere, so @ffmpeg/ffmpeg should work in Node.js"
Reality: While WebAssembly itself can run in Node.js, the @ffmpeg/ffmpeg and @ffmpeg/core packages are specifically designed for browser environments and will fail in Node.js.
// ❌ This fails in Node.js
import { FFmpeg } from '@ffmpeg/ffmpeg';
const ffmpeg = new FFmpeg();
await ffmpeg.load(); // Error: "does not support nodejs"
Why it fails:
SharedArrayBuffer and MessagePort// ❌ This also fails in Node.js
import createFFmpegCore from '@ffmpeg/core';
const Module = await createFFmpegCore({}); // ReferenceError: self is not defined
Why it fails:
self, window, document| Environment | Recommended Solution | Performance | Use Case |
|---|---|---|---|
| Node.js Server | Native FFmpeg (args + spawn) | ⚡ Excellent | Server-side processing |
| Browser Client | @ffmpeg/ffmpeg (WebAssembly) | ✅ Good | Client-side processing |
| Edge/Serverless | Native FFmpeg binary | ⚡ Excellent | Serverless functions |
import { planHlsCmaf, x264, aac } from "@shelby-protocol/media-prepare/core/hls-cmaf";
import { execFfmpeg } from "@shelby-protocol/media-prepare/node";
import * as fs from "node:fs/promises";
const plan = planHlsCmaf()
.input("/path/to/video.mp4")
.outputDir("/path/to/output")
.withLadder([
{ width: 1920, height: 1080, bitrateBps: 5_000_000, name: "1080p" },
{ width: 1280, height: 720, bitrateBps: 3_000_000, name: "720p" },
])
.withVideoEncoder(x264())
.withAudio(aac(), { language: "eng", bitrateBps: 128_000, default: true })
.withSegments({ mode: "auto", maxBlobBytes: 10 * 1024 * 1024, safety: 0.9, minSeconds: 1, align: 1 })
.hlsCmaf()
.render.ffmpegArgs();
await fs.rm(plan.outputDir, { recursive: true, force: true });
await execFfmpeg(plan.args, { precreate: plan.variantNames.map(name => `${plan.outputDir}/${name}`) });
Advantages:
import { planHlsCmaf } from "@shelby-protocol/media-prepare/core/hls-cmaf";
import { FFmpeg } from "@ffmpeg/ffmpeg"; // peer dependency
import { fetchFile } from "@ffmpeg/util";
const plan = planHlsCmaf()
.input("input.mp4")
.outputDir("/out")
.withLadder([{ width: 854, height: 480, bitrateBps: 1_000_000, name: "480p" }])
.withVideoEncoder({ kind: "copy" }) // copy mode recommended in wasm
.withSegments({ mode: "fixed", segmentSeconds: 4 })
.hlsCmaf()
.render.ffmpegArgs();
const ffmpeg = new FFmpeg();
await ffmpeg.load();
await ffmpeg.writeFile("input.mp4", await fetchFile(file));
await ffmpeg.exec(plan.args);
Advantages:
Limitations:
For browser WebAssembly integration, install the optional peer dependencies:
# Browser WebAssembly FFmpeg
npm install @ffmpeg/ffmpeg @ffmpeg/util @ffmpeg/core
Note: These are optional peer dependencies since Node.js applications use native FFmpeg binaries instead.
FAQs
FFmpeg presets and a declarative builder for CMAF + HLS: multi‑rung ladders, multi‑audio, trickplay, safe segment sizing, and clean `var_stream_map`. The library produces FFmpeg argument arrays only — no manual folder or manifest creation — and works in b
The npm package @shelby-protocol/media-prepare receives a total of 5 weekly downloads. As such, @shelby-protocol/media-prepare popularity was classified as not popular.
We found that @shelby-protocol/media-prepare demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.