Skip to content

ffmpeg-kitFFmpeg, typed.

A fluent TypeScript SDK for FFmpeg — extract, transform, mix, stream, and export with type safety and smart defaults.

Write FFmpeg like TypeScript

Every operation is a typed builder. Autocomplete guides you — no memorizing FFmpeg flags.

typescript
import { ffmpeg } from "ffmpeg-kit";

// Extract a thumbnail at the 5-second mark
const { outputPath, width, height } = await ffmpeg.extract()
  .input("video.mp4")
  .timestamp(5)
  .size({ width: 640 })
  .format("jpg")
  .output("thumb.jpg")
  .execute();

// Scale, trim, and export with a YouTube preset
await ffmpeg.transform()
  .input("raw.mp4")
  .scale({ width: 1920, height: 1080 })
  .trimStart("00:01:00")
  .duration(120)
  .output("clip.mp4")
  .execute();

// Normalize audio loudness
await ffmpeg.audio()
  .input("podcast.wav")
  .normalize({ targetLUFS: -16 })
  .fadeIn({ duration: 0.5 })
  .fadeOut({ duration: 1 })
  .output("normalized.wav")
  .execute();

Result types, not just exceptions

typescript
// Traditional try/catch
try {
  await ffmpeg.extract().input("video.mp4")
    .timestamp(5).output("frame.png").execute();
} catch (e) {
  if (e instanceof FFmpegError) {
    console.log(e.code);   // FFmpegErrorCode.INPUT_NOT_FOUND
    console.log(e.stderr);
  }
}

// Or use Result types — no try/catch needed
const result = await ffmpeg.extract()
  .input("video.mp4")
  .timestamp(5)
  .output("frame.png")
  .tryExecute();

if (!result.success) {
  console.error(result.error.code);
}

One-liners for common tasks

typescript
await ffmpeg.remux("input.mp4", "output.mkv");
await ffmpeg.compress("input.mp4", "small.mp4", { crf: 28 });
await ffmpeg.extractAudio("video.mp4", "audio.mp3");
await ffmpeg.resize("input.mp4", "720p.mp4", { width: 1280 });

Released under the MIT License.