ffipeg
Easily generate Dart FFI bindings to FFmpeg for use in your project in 3 steps:
- Add a library annotation;
- Run
build_runner
; - Import the generated file, ffi, and go!
Example
(Incomplete; for illustrative purposes only; see ffipeg_muxer
package for full working example.)
ffmpeg.dart
@FFmpegGen(
versionSpec: '>=7.1 <8.0',
excludeAllByDefault: true,
functions: FFInclude({
'av_compare_ts',
'av_interleaved_write_frame',
'av_log_set_level',
'av_packet_alloc',
// ...
'avio_open',
}),
structs: FFInclude({'AVFormatContext', 'AVIOContext', 'AVPacket'}),
enums: FFInclude({'AVMediaType'}),
macros: FFInclude({'AVIO_FLAG_WRITE', 'AV_NOPTS_VALUE', 'AV_LOG_.*'}),
)
library;
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:ffipeg/ffipeg.dart'; // Exports `@FFmpegGen` Annotation
import 'ffmpeg.ffipeg.dart'; // Generated _name_.ffipeg.dart file with FFI bindings
void main() {
final dylib = DynamicLibrary.open('/path/to/ffmpeg')
final ffmpeg = FFmpeg(dylib);
ffmpeg.av_log_set_level(AV_LOG_DEBUG);
final videoInputCtx = calloc<Pointer<AVFormatContext>>();
final videoPkt = ffmpeg.av_packet_alloc();
final videoPktPtr = calloc<Pointer<AVPacket>>();
final videoFile = "/path/to/video/file.mp4";
if (0 != ffmpeg.avformat_open_input(
videoInputCtx, videoFile.toNativeUtf8().cast(), nullptr, nullptr)) {
throw Exception('Failed to open video file: $videoFile');
}
// ... do more stuff ...
// We're dealing with C ... be sure to clean up resources!
ffmpeg
..avformat_close_input(videoInputCtx)
..av_packet_free(videoPktPtr);
if (videoPktPtr != nullptr) {
calloc.free(videoPktPtr);
}
if (videoInputCtx != nullptr) {
calloc.free(videoInputCtx);
}
}
Features
- This package is basically a wrapper around
FfiGen()
that usesbuild_runner
and makes it more accessible as part of a standard build process. It offers reasonable defaults for FFmpeg. - Specify your own
headerPaths
to FFmpeg header files, or use default included headers. If supplied,headerPaths
will be tried in order, so multiple build platforms can be supported. - Specify which FFmpeg libraries (
FFmpegLibrary.avCodec
, etc.), (all by default), should be included. - Pass standard
FfiGen()
include/exclude options via strongly-typed options ofSet<String>
for functions, structs, macros, enums, etc. usingFFInclude({...})
,FFExclude({...})
,ffAllowAll
, orffDenyAll
. - Customize the generated class name for functions (
FFmpeg
by default). - Pass custom
llvmPaths
toFfiGen()
(optional).
Getting started
Prerequisites
- Flutter is not required. Only Dart + the package dependencies are required for code generation.
- Actually running your FFI code requires an FFmpeg binary (either executable CLI or dylib, e.g. in the
fvp
package for Flutter). - This package does not require
fvp
or itsmdk-sdk
. Any FFmpeg binary built with the functions/features used and compatible with both the target system and the version of headers used to build the bindings will work.
Installation
- Add the 4 required packages:
dart pub add ffipeg
dart pub add ffi
dart pub add --dev ffipeg_builder
dart pub add --dev build_runner
Usage
- You will need to ensure the FFmpeg binary is available in your built Flutter app or Dart executable's path.
- You may need a specific
Platform
switch to specify the path/name passed into theDynamicLibrary()
constructor.
- You may need a specific
Refer to the FFmpegGen
class source documentation for specific usage of the annotation.
Refer to the example code above to get started, or ffipeg_muxer
package for a working CLI/Dart class example demonstratng how to mux an audio and video file without transcoding (copies the codecs).
Premise
There is currently no simple way of including the FFmpeg binary in a cross-platform Flutter desktop app. ffmpeg_kit_flutter
does not offer a Windows or Linux version (Why not? They already have a build pipeline for 3 platforms...).
The only solution I found was fvp
, which includes the FFmpeg binary via its bundled mdk-sdk
, but it offers no FFmpeg API itself. And including both fvp
and a built FFmpeg binary in my app would introduce too much bloat for the one function I needed.
Therefore, I learned to use FFmpeg through FFI and created this package.
Contributing
Contributions are welcome, especially if any bugs are found. Please open an issue in the repo at https://github.com/dra11y/ffipeg-dart.
Libraries
- ffipeg
- Generate Dart FFI bindings to FFmpeg with a simple library annotation.