https://github.com/radek-k/ffmediatoolkit
FFMediaToolkit is a cross-platform video decoder/encoder library for .NET that uses FFmpeg native libraries. It supports video frames extraction, reading stream metadata and creating videos from bitmaps in any format supported by FFmpeg.
https://github.com/radek-k/ffmediatoolkit
csharp decoder dotnet encoder ffmpeg frame-extraction h264 library mp4 netcore netstandard video video-encoder
Last synced: 6 months ago
JSON representation
FFMediaToolkit is a cross-platform video decoder/encoder library for .NET that uses FFmpeg native libraries. It supports video frames extraction, reading stream metadata and creating videos from bitmaps in any format supported by FFmpeg.
- Host: GitHub
- URL: https://github.com/radek-k/ffmediatoolkit
- Owner: radek-k
- License: mit
- Created: 2019-05-04T15:38:06.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-08-06T14:30:52.000Z (about 2 years ago)
- Last Synced: 2025-04-08T12:08:28.715Z (6 months ago)
- Topics: csharp, decoder, dotnet, encoder, ffmpeg, frame-extraction, h264, library, mp4, netcore, netstandard, video, video-encoder
- Language: C#
- Homepage:
- Size: 37.7 MB
- Stars: 368
- Watchers: 19
- Forks: 57
- Open Issues: 25
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FFMediaToolkit
[](https://ci.appveyor.com/project/radek-k/ffmediatoolkit) [](https://www.nuget.org/packages/FFMediaToolkit/)
[](https://github.com/radek-k/FFMediaToolkit/blob/master/LICENSE)> ⚠ **This library is not recommended for production use.**
**FFMediaToolkit** is a .NET library for creating and reading multimedia files. It uses native FFmpeg libraries by the [FFmpeg.Autogen](https://github.com/Ruslan-B/FFmpeg.AutoGen) bindings.
## Features
- Decoding/encoding audio-video files in many formats supported by FFmpeg.
- Extracting audio data as floating point arrays.
- Access to any video frame by timestamp.
- Creating videos from images with metadata, pixel format, bitrate, CRF, FPS, GoP, dimensions and other codec settings.
- Supports reading multimedia chapters and metadata.## Code samples
- Extract all video frames as PNG files
```c#
int i = 0;
var file = MediaFile.Open(@"C:\videos\movie.mp4");
while(file.Video.TryGetNextFrame(out var imageData))
{
imageData.ToBitmap().Save($@"C:\images\frame_{i++}.png");
// See the #Usage details for example .ToBitmap() implementation
// The .Save() method may be different depending on your graphics library
}
```- Video decoding
```c#
// Opens a multimedia file.
// You can use the MediaOptions properties to set decoder options.
var file = MediaFile.Open(@"C:\videos\movie.mp4");
// Gets the frame at 5th second of the video.
var frame5s = file.Video.GetFrame(TimeSpan.FromSeconds(5));
// Print informations about the video stream.
Console.WriteLine($"Bitrate: {file.Info.Bitrate / 1000.0} kb/s");
var info = file.Video.Info;
Console.WriteLine($"Duration: {info.Duration}");
Console.WriteLine($"Frames count: {info.NumberOfFrames ?? "N/A"}");
var frameRateInfo = info.IsVariableFrameRate ? "average" : "constant";
Console.WriteLine($"Frame rate: {info.AvgFrameRate} fps ({frameRateInfo})");
Console.WriteLine($"Frame size: {info.FrameSize}");
Console.WriteLine($"Pixel format: {info.PixelFormat}");
Console.WriteLine($"Codec: {info.CodecName}");
Console.WriteLine($"Is interlaced: {info.IsInterlaced}");
```- Encode video from images.
```c#
// You can set there codec, bitrate, frame rate and many other options.
var settings = new VideoEncoderSettings(width: 1920, height: 1080, framerate: 30, codec: VideoCodec.H264);
settings.EncoderPreset = EncoderPreset.Fast;
settings.CRF = 17;
using(var file = MediaBuilder.CreateContainer(@"C:\videos\example.mp4").WithVideo(settings).Create())
{
while(file.Video.FramesCount < 300)
{
file.Video.AddFrame(/*Your code*/);
}
}
```## Setup
Install the **FFMediaToolkit** package from [NuGet](https://www.nuget.org/packages/FFMediaToolkit/).
```shell
dotnet add package FFMediaToolkit
```
```Package
PM> Install-Package FFMediaToolkit
```**FFmpeg libraries are not included in the package.** To use FFMediaToolkit, you need the **FFmpeg shared build** binaries: `avcodec`, `avformat`, `avutil`, `swresample`, `swscale`.
- **Windows** - You can download it from the [BtbN/FFmpeg-Builds](https://github.com/BtbN/FFmpeg-Builds/releases) or [gyan.dev](https://www.gyan.dev/ffmpeg/builds/). You only need `*.dll` files from the `.\bin` directory (**not `.\lib`**) of the ZIP package. Place the binaries in the `.\ffmpeg\x86_64\`(64bit) in the application output directory or set `FFmpegLoader.FFmpegPath`.
- **Linux** - Download FFmpeg using your package manager.
- **macOS**, **iOS**, **Android** - Not supported.**You need to set `FFmpegLoader.FFmpegPath` with a full path to FFmpeg libraries.**
> If you want to use 64-bit FFmpeg, you have to disable the *Build* -> *Prefer 32-bit* option in Visual Studio project properties.## Usage details
FFMediaToolkit uses the [*ref struct*](https://docs.microsoft.com/pl-pl/dotnet/csharp/language-reference/keywords/ref#ref-struct-types) `ImageData` for bitmap images. The `.Data` property contains pixels data in a [`Span`](https://docs.microsoft.com/pl-pl/dotnet/api/system.span-1?view=netstandard-2.1).
> **If you want to process or save the `ImageData`, you should convert it to another graphics object, using one of the following methods.**
> **These methods are not included in the program to avoid additional dependencies and provide compatibility with many graphics libraries.**
- **For [ImageSharp](https://github.com/SixLabors/ImageSharp) library (.NET Standard/Core - cross-platform):**
```c#
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
...
public static Image ToBitmap(this ImageData imageData)
{
return Image.LoadPixelData(imageData.Data, imageData.ImageSize.Width, imageData.ImageSize.Height);
}
```- **For .NET Framework `System.Drawing.Bitmap` (Windows only):**
```c#
// ImageData -> Bitmap (unsafe)
public static unsafe Bitmap ToBitmap(this ImageData bitmap)
{
fixed(byte* p = bitmap.Data)
{
return new Bitmap(bitmap.ImageSize.Width, bitmap.ImageSize.Height, bitmap.Stride, PixelFormat.Format24bppRgb, new IntPtr(p));
}
}
// Bitmap -> ImageData (safe)
...
var rect = new Rectangle(Point.Empty, bitmap.Size);
var bitLock = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
var bitmapData = ImageData.FromPointer(bitLock.Scan0, bitmap.Size, ImagePixelFormat.Bgr24);
mediaFile.Video.AddFrame(bitmapData); // Encode the frame
bitmap.UnlockBits(bitLock); // UnlockBits() must be called after encoding the frame
...
```- **For .NET Framework/Core desktop apps with WPF UI. (Windows only):**
```c#
using System.Windows.Media.Imaging;
...
// ImageData -> BitmapSource (unsafe)
public static unsafe BitmapSource ToBitmap(this ImageData bitmapData)
{
fixed(byte* ptr = bitmapData.Data)
{
return BitmapSource.Create(bitmapData.ImageSize.Width, bitmapData.ImageSize.Height, 96, 96, PixelFormats.Bgr32, null, new IntPtr(ptr), bitmapData.Data.Length, bitmapData.Stride);
}
}
// BitmapSource -> ImageData (safe)
public static ImageData ToImageData(this BitmapSource bitmap)
{
var wb = new WriteableBitmap(bitmap);
return ImageData.FromPointer(wb.BackBuffer, ImagePixelFormat.Bgra32, wb.PixelWidth, wb.PixelHeight);
}
```- **FFMediaToolkit will also work with any other graphics library that supports creating images from `Span`, byte array or memory pointer**
## Visual Basic usage
Writing decoded bitmap directly to the WPF `WriteableBitmap` buffer using the `TryReadFrameToPointer` method:
````vb
Dim file As FileStream = New FileStream("path to the video file", FileMode.Open, FileAccess.Read)
Dim media As MediaFile = MediaFile.Load(file)
Dim bmp As WriteableBimap = New WriteableBitmap(media.Video.Info.FrameSize.Width, media.Video.Info.FrameSize.Height, 96, 96, PixelFormats.Bgr24, Nothing)
bmp.Lock()
Dim decoded As Boolean = media.Video.TryGetFrame(TimeSpan.FromMinutes(1), bmp.BackBuffer, bmp.BackBufferStride)
If decoded Then
bmp.AddDirtyRect(New Int32Rect(0, 0, media.Video.Info.FrameSize.Width, media.Video.Info.FrameSize.Height))
End If
bmp.Unlock()
imageBox.Source = bmp
````
Converting `ImageData` to a byte array:
````vb
Dim data() As Byte = media.Video.GetNextFrame().Data.ToArray()
````
## LicensingThis project is licensed under the [MIT](https://github.com/radek-k/FFMediaToolkit/blob/master/LICENSE) license.