Skip to content

mustneerar7/react-native-ffmpeg-lib

react-native-ffmpeg-lib

Full FFmpeg CLI parity for React Native on iOS and Android. Wraps the vendored FFmpegKit full-gpl 6.0.2 binaries behind a clean TurboModule and a small TypeScript surface.

⚠️ GPL-3.0. This package bundles full-gpl ffmpeg builds (x264, x265, libvidstab, xvid, etc.) which inherit the GPLv3 license. Apps that ship this library must comply with GPLv3 — including providing source on request. If you need a permissive variant, vendor the full (LGPL) builds yourself; the native API is the same.

Requirements

  • React Native ≥ 0.79 with the new architecture enabled (default in 0.79+, mandatory in 0.82+)
  • iOS 12.1+
  • Android API 24+
  • Node 18+ at install time (postinstall script runs on npm install)

Install

npm install react-native-ffmpeg-lib
# or
yarn add react-native-ffmpeg-lib

A postinstall script fetches the FFmpegKit binaries (~210MB) from this package's own GitHub Release and verifies sha256 before unpacking. Override the source with FFMPEG_LIB_BINARIES_BASE_URL if you mirror them.

Then on iOS:

cd ios && pod install

Usage

import { FFmpeg, FFprobe, FFmpegPaths, FFmpegExport } from 'react-native-ffmpeg-lib';

const { cache } = FFmpegPaths.getDirectories();
const out = `${cache}/out.mp4`;

// Async — almost always what you want. Runs ffmpeg on a background thread.
const result = await FFmpeg.execute(
  `-y -f lavfi -i testsrc=duration=3:size=640x480:rate=30 -c:v mpeg4 ${out}`
);
console.log(result.returnCode, `${result.durationMs}ms`);

// ffprobe → media info JSON
const info = await FFprobe.getMediaInfo(out);

// Native share sheet
await FFmpegExport.share(out);

Sync execution

executeSync exists for parity with the FFmpegKit synchronous API. It blocks the JS thread for the entire ffmpeg run — no UI updates, no other JS, no timers. Use it only for sub-second operations:

import { FFmpeg } from 'react-native-ffmpeg-lib';

// OK: quick remux / metadata read — finishes in < 100ms.
const r = FFmpeg.executeSync(`-y -i in.mp4 -c copy out.mp4`);

// NOT OK: real transcoding will freeze the app for seconds.
//   FFmpeg.executeSync(`-i big.mov -c:v libx264 out.mp4`);  ← don't

For anything that takes more than a frame, use FFmpeg.execute(...) instead.

API

Symbol Sync? Description
FFmpeg.execute(cmd) no Returns Promise<ExecuteResult>. Runs on a background queue.
FFmpeg.executeSync(cmd) yes Returns ExecuteResult directly. Blocks the JS thread.
FFmpeg.cancel(sessionId) yes Cancels a running async session.
FFprobe.getMediaInfo<T>(path) no Promise<T> of parsed ffprobe JSON.
FFmpegPaths.getDirectories() yes { temp, cache, document } — instant, just returns platform constants.
FFmpegExport.share(path) no Presents the native share sheet (iOS) / chooser (Android). Promise<bool>.

ExecuteResult

{
  sessionId: number;   // pass to cancel()
  returnCode: number;  // 0 = success, non-zero = ffmpeg error
  output: string;      // combined stdout + stderr from ffmpeg
  durationMs: number;
}

Troubleshooting

fmt consteval errors on Xcode 26+ / RN 0.79–0.85

If pod install && xcodebuild fails with errors like:

fmt/include/fmt/format-inl.h:59:24: error: call to consteval function ... is not a constant expression

…add this patch to your app's ios/Podfile post_install block:

post_install do |installer|
  # ... your existing react_native_post_install call ...

  base_h = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h')
  if File.exist?(base_h)
    contents = File.read(base_h)
    unless contents.include?('FMT_USE_CONSTEVAL 0  /* patched */')
      File.chmod(0644, base_h)
      patched = contents.gsub(
        /^(\s*#\s*define\s+FMT_USE_CONSTEVAL)\s+1\b/,
        '\\1 0  /* patched */'
      )
      File.write(base_h, patched)
    end
  end
end

This is a workaround until React Native bumps fmt to 11.1+, which fixes the consteval evaluation under newer Apple Clang.

npm install couldn't reach the binary host

Set FFMPEG_LIB_BINARIES_BASE_URL to a mirror (corporate proxy, internal artifact store), then reinstall:

FFMPEG_LIB_BINARIES_BASE_URL=https://mirror.example.com/ffmpeg-lib npm install

Air-gapped CI

Drop the artifacts in place before running install and the postinstall will detect them and skip:

ios/Frameworks/ffmpegkit.xcframework/...
android/libs/ffmpeg-kit-full-gpl-6.0.aar

Credits

License

GPL-3.0. See LICENSE.

About

A new architecture based wrapper library for ffmpeg.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors