Convert Figma logo to code with AI

Kagami logoffmpeg.js

Port of FFmpeg with Emscripten

3,281
332
3,281
81

Top Related Projects

A fluent API to FFMPEG (http://www.ffmpeg.org)

12,323

Video editing with Python

4,722

Slick, declarative command line video editing & API

2,723

GPAC Ultramedia OSS for Video Streaming & Next-Gen Multimedia Transcoding, Packaging & Delivery

Quick Overview

FFmpeg.js is a JavaScript port of FFmpeg, a powerful multimedia framework for handling audio and video. It allows developers to use FFmpeg functionality directly in web browsers or Node.js environments, enabling client-side audio and video processing without the need for server-side operations.

Pros

  • Enables client-side audio and video processing in web applications
  • Eliminates the need for server-side FFmpeg installations
  • Supports a wide range of FFmpeg features and codecs
  • Can be used in both browser and Node.js environments

Cons

  • May have performance limitations compared to native FFmpeg
  • Large file size due to the complexity of FFmpeg
  • Limited documentation and examples compared to the original FFmpeg
  • Potential compatibility issues with some browsers or devices

Code Examples

  1. Converting video format:
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });

(async () => {
  await ffmpeg.load();
  await ffmpeg.write('input.mp4', await fetchFile('input.mp4'));
  await ffmpeg.run('-i input.mp4 output.webm');
  const data = ffmpeg.read('output.webm');
  // Use the converted video data
})();
  1. Extracting audio from video:
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });

(async () => {
  await ffmpeg.load();
  await ffmpeg.write('input.mp4', await fetchFile('input.mp4'));
  await ffmpeg.run('-i input.mp4 -vn -acodec libmp3lame output.mp3');
  const data = ffmpeg.read('output.mp3');
  // Use the extracted audio data
})();
  1. Applying a video filter:
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });

(async () => {
  await ffmpeg.load();
  await ffmpeg.write('input.mp4', await fetchFile('input.mp4'));
  await ffmpeg.run('-i input.mp4 -vf "boxblur=2:1" output.mp4');
  const data = ffmpeg.read('output.mp4');
  // Use the filtered video data
})();

Getting Started

To use FFmpeg.js in your project, follow these steps:

  1. Install the package:

    npm install @ffmpeg/ffmpeg @ffmpeg/core
    
  2. Import and initialize FFmpeg.js in your code:

    import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
    const ffmpeg = createFFmpeg({ log: true });
    
    (async () => {
      await ffmpeg.load();
      // Your FFmpeg.js code here
    })();
    
  3. Use FFmpeg.js functions to process audio and video as needed.

Competitor Comparisons

A fluent API to FFMPEG (http://www.ffmpeg.org)

Pros of node-fluent-ffmpeg

  • More comprehensive API with a wide range of FFmpeg functionality
  • Supports both FFmpeg and FFprobe operations
  • Active development and community support

Cons of node-fluent-ffmpeg

  • Requires FFmpeg to be installed on the system
  • Heavier resource usage due to spawning FFmpeg processes
  • Limited browser compatibility (primarily for Node.js environments)

Code Comparison

ffmpeg.js:

const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
await ffmpeg.run('-i', 'input.mp4', 'output.mp4');

node-fluent-ffmpeg:

const ffmpeg = require('fluent-ffmpeg');
ffmpeg('input.mp4')
  .output('output.mp4')
  .on('end', () => console.log('Finished'))
  .run();

Summary

ffmpeg.js is a lightweight, browser-compatible solution that runs FFmpeg in WebAssembly, while node-fluent-ffmpeg offers a more feature-rich API for Node.js environments with direct access to system-installed FFmpeg. The choice between them depends on the specific use case, with ffmpeg.js being more suitable for browser-based applications and node-fluent-ffmpeg excelling in server-side scenarios with complex FFmpeg operations.

12,323

Video editing with Python

Pros of moviepy

  • Pure Python implementation, making it easier to integrate with Python projects
  • Higher-level API for video editing tasks, simplifying common operations
  • Extensive documentation and examples for various use cases

Cons of moviepy

  • Generally slower performance compared to ffmpeg.js, especially for complex operations
  • Limited support for advanced video processing features available in FFmpeg
  • Dependency on external libraries for certain functionalities

Code Comparison

moviepy:

from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip

video = VideoFileClip("input.mp4")
text = TextClip("Hello World", fontsize=70, color='white')
result = CompositeVideoClip([video, text.set_pos('center')])
result.write_videofile("output.mp4")

ffmpeg.js:

const ffmpeg = require('ffmpeg.js');
const fs = require('fs');

const inputData = fs.readFileSync('input.mp4');
const result = ffmpeg({
  MEMFS: [{ name: "input.mp4", data: inputData }],
  arguments: ["-i", "input.mp4", "-vf", "drawtext=text='Hello World':fontsize=70:fontcolor=white:x=(w-tw)/2:y=(h-th)/2", "output.mp4"],
});
fs.writeFileSync('output.mp4', Buffer.from(result.MEMFS[0].data));

Both examples demonstrate adding text to a video, showcasing the difference in API complexity and language-specific approaches.

4,722

Slick, declarative command line video editing & API

Pros of editly

  • Higher-level API for video editing tasks
  • Built-in support for transitions, titles, and effects
  • Easier to use for non-programmers with CLI interface

Cons of editly

  • Less flexible than ffmpeg.js for low-level video manipulation
  • Smaller community and fewer resources compared to ffmpeg.js
  • Limited to specific video editing tasks

Code Comparison

editly:

const editly = require('editly');

editly({
  outPath: './output.mp4',
  clips: [
    { duration: 2, layers: [{ type: 'title', text: 'Hello World' }] },
    { duration: 3, layers: [{ type: 'video', path: './video.mp4' }] },
  ],
}).then(() => console.log('Video created!'));

ffmpeg.js:

const ffmpeg = require('ffmpeg.js');

const result = ffmpeg({
  MEMFS: [{ name: "test.mp4", data: testData }],
  arguments: ["-i", "test.mp4", "-c:v", "libx264", "out.mp4"],
  print: function(data) { console.log(data); },
  printErr: function(data) { console.error(data); },
});

const out = result.MEMFS.filter(file => file.name === "out.mp4")[0];

Both libraries serve different purposes within the video processing ecosystem. editly focuses on simplifying video editing tasks with a high-level API, while ffmpeg.js provides more granular control over video manipulation at a lower level.

2,723

GPAC Ultramedia OSS for Video Streaming & Next-Gen Multimedia Transcoding, Packaging & Delivery

Pros of gpac

  • More comprehensive multimedia framework with broader functionality
  • Native implementation, potentially offering better performance
  • Actively maintained with regular updates and improvements

Cons of gpac

  • Larger codebase and more complex to integrate
  • Requires compilation and installation, not as easily portable
  • Steeper learning curve for developers

Code Comparison

gpac:

GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 brand, u32 minVersion)
{
    if (!movie) return GF_BAD_PARAM;
    movie->brand = brand;
    movie->minor_brand_version = minVersion;
    return GF_OK;
}

ffmpeg.js:

var ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
await ffmpeg.run('-i', 'input.mp4', 'output.mp4');
var data = ffmpeg.FS('readFile', 'output.mp4');

Key Differences

  • gpac is a native C implementation, while ffmpeg.js is a JavaScript port of FFmpeg
  • gpac offers a wider range of multimedia tools and features
  • ffmpeg.js is more focused on providing FFmpeg functionality in web environments
  • gpac requires compilation and installation, ffmpeg.js can be easily integrated into web projects
  • ffmpeg.js has a simpler API for basic operations, while gpac offers more fine-grained control

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

ffmpeg.js

NPM

This library provides FFmpeg builds ported to JavaScript using Emscripten project. Builds are optimized for in-browser use: minimal size for faster loading, asm.js, performance tunings, etc. Though they work in Node as well.

Builds

Currently available builds (additional builds may be added in future):

  • ffmpeg-webm.js - WebM encoding (VP8 & Opus encoders, popular decoders).
  • ffmpeg-worker-webm.js - Web Worker version of ffmpeg-webm.js.
  • ffmpeg-mp4.js - MP4 encoding (H.264 & AAC & MP3 encoders, popular decoders).
  • ffmpeg-worker-mp4.js - Web Worker version of ffmpeg-mp4.js.

Note: only NPM releases contain abovementioned files.

Version scheme

ffmpeg.js uses the following version pattern: major.minor.9ddd, where:

  • major - FFmpeg's major version number used in the builds.
  • minor - FFmpeg's minor version.
  • ddd - ffmpeg.js own patch version. Should not be confused with FFmpeg's patch version number.

Example: 2.7.9005

Usage

See documentation on Module object for the list of options that you can pass.

Sync run

ffmpeg.js provides common module API, ffmpeg-webm.js is the default module. Add its name after the slash if you need another build, e.g. require("ffmpeg.js/ffmpeg-mp4.js").

const ffmpeg = require("ffmpeg.js");
let stdout = "";
let stderr = "";
// Print FFmpeg's version.
ffmpeg({
  arguments: ["-version"],
  print: function(data) { stdout += data + "\n"; },
  printErr: function(data) { stderr += data + "\n"; },
  onExit: function(code) {
    console.log("Process exited with code " + code);
    console.log(stdout);
    console.log(stderr);
  },
});

Use e.g. browserify in case of Browser.

Via Web Worker

ffmpeg.js also provides wrapper for main function with Web Worker interface to offload the work to a different process. Worker sends the following messages:

  • {type: "ready"} - Worker loaded and ready to accept commands.
  • {type: "run"} - Worker started the job.
  • {type: "stdout", data: "<line>"} - FFmpeg printed to stdout.
  • {type: "stderr", data: "<line>"} - FFmpeg printed to stderr.
  • {type: "exit", data: "<code>"} - FFmpeg exited.
  • {type: "done", data: "<result>"} - Job finished with some result.
  • {type: "error", data: "<error description>"} - Error occurred.
  • {type: "abort", data: "<abort reason>"} - FFmpeg terminated abnormally (e.g. out of memory, wasm error).

You can send the following messages to the worker:

  • {type: "run", ...opts} - Start new job with provided options.
const worker = new Worker("ffmpeg-worker-webm.js");
worker.onmessage = function(e) {
  const msg = e.data;
  switch (msg.type) {
  case "ready":
    worker.postMessage({type: "run", arguments: ["-version"]});
    break;
  case "stdout":
    console.log(msg.data);
    break;
  case "stderr":
    console.log(msg.data);
    break;
  case "done":
    console.log(msg.data);
    break;
  }
};

You can use worker_threads module in case of Node.

Files

Empscripten supports several types of file systems. ffmpeg.js uses MEMFS to store the input/output files in FFmpeg's working directory. You need to pass Array of Object to MEMFS option with the following keys:

  • name (String) - File name, can't contain slashes.
  • data (ArrayBuffer/ArrayBufferView/Array) - File data.

ffmpeg.js resulting object has MEMFS option with the same structure and contains files which weren't passed to the input, i.e. new files created by FFmpeg.

const ffmpeg = require("ffmpeg.js");
const fs = require("fs");
const testData = new Uint8Array(fs.readFileSync("test.webm"));
// Encode test video to VP8.
const result = ffmpeg({
  MEMFS: [{name: "test.webm", data: testData}],
  arguments: ["-i", "test.webm", "-c:v", "libvpx", "-an", "out.webm"],
});
// Write out.webm to disk.
const out = result.MEMFS[0];
fs.writeFileSync(out.name, Buffer(out.data));

You can also mount other FS by passing Array of Object to mounts option with the following keys:

  • type (String) - Name of the file system.
  • opts (Object) - Underlying file system options.
  • mountpoint (String) - Mount path, must start with a slash, must not contain other slashes and also the following paths are blacklisted: /tmp, /home, /dev, /work. Mount directory will be created automatically before mount.

See documentation of FS.mount for more details.

const ffmpeg = require("ffmpeg.js");
ffmpeg({
  // Mount /data inside application to the current directory.
  mounts: [{type: "NODEFS", opts: {root: "."}, mountpoint: "/data"}],
  arguments: ["-i", "/data/test.webm", "-c:v", "libvpx", "-an", "-y", "/data/out.webm"],
});
// out.webm was written to the current directory.

Build instructions

It's recommended to use Docker to build ffmpeg.js.

  1. Clone ffmpeg.js repository with submodules:

    git clone https://github.com/Kagami/ffmpeg.js.git --recurse-submodules
    
  2. Modify Makefile and/or patches if you wish to make a custom build.

  3. Build everything:

    docker run --rm -it -v /path/to/ffmpeg.js:/mnt -w /opt kagamihi/ffmpeg.js
    # cp -a /mnt/{.git,build,Makefile} . && source /root/emsdk/emsdk_env.sh && make && cp ffmpeg*.js /mnt
    

That's it. ffmpeg.js modules should appear in your repository clone.

Build without Docker

Ubuntu example:

sudo apt-get update
sudo apt-get install -y git python build-essential automake libtool pkg-config

cd ~
git clone https://github.com/emscripten-core/emsdk.git && cd emsdk
./emsdk install latest
./emsdk activate latest
source emsdk_env.sh

cd ~
git clone https://github.com/Kagami/ffmpeg.js.git --recurse-submodules && cd ffmpeg.js
make

Credits

Thanks to videoconverter.js for inspiration. And of course to all great projects which made this library possible: FFmpeg, Emscripten, asm.js, node.js and many others.

License

Own library code licensed under LGPL 2.1 or later.

WebM build

This build uses LGPL version of FFmpeg and thus available under LGPL 2.1 or later. See here for more details and FFmpeg's license information.

Included libraries:

See LICENSE.WEBM for the full text of software licenses used in this build.

MP4 build

This build uses GPL version of FFmpeg and thus available under GPL 2.0. It also includes patent encumbered H.264, AAC and MP3 encoders. Make sure to contact lawyer before using it in your country.

Included libraries:

See LICENSE.MP4 for the full text of software licenses used in this build.

NPM DownloadsLast 30 Days