{"id":22079756,"url":"https://github.com/radek-k/ffmediatoolkit","last_synced_at":"2025-04-08T12:08:33.267Z","repository":{"id":40267268,"uuid":"184913381","full_name":"radek-k/FFMediaToolkit","owner":"radek-k","description":"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.","archived":false,"fork":false,"pushed_at":"2023-08-06T14:30:52.000Z","size":39526,"stargazers_count":368,"open_issues_count":25,"forks_count":57,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-08T12:08:28.715Z","etag":null,"topics":["csharp","decoder","dotnet","encoder","ffmpeg","frame-extraction","h264","library","mp4","netcore","netstandard","video","video-encoder"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radek-k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-04T15:38:06.000Z","updated_at":"2025-02-23T16:08:39.000Z","dependencies_parsed_at":"2024-12-08T00:02:02.360Z","dependency_job_id":"d424d3a4-712c-4880-a2f8-26ee2379b300","html_url":"https://github.com/radek-k/FFMediaToolkit","commit_stats":{"total_commits":466,"total_committers":17,"mean_commits":27.41176470588235,"dds":0.128755364806867,"last_synced_commit":"4dffe1eac1e36449c330bb215bba6e38155ee067"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radek-k%2FFFMediaToolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radek-k%2FFFMediaToolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radek-k%2FFFMediaToolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radek-k%2FFFMediaToolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radek-k","download_url":"https://codeload.github.com/radek-k/FFMediaToolkit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247838444,"owners_count":21004580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","decoder","dotnet","encoder","ffmpeg","frame-extraction","h264","library","mp4","netcore","netstandard","video","video-encoder"],"created_at":"2024-11-30T23:10:32.193Z","updated_at":"2025-04-08T12:08:33.246Z","avatar_url":"https://github.com/radek-k.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FFMediaToolkit\n\n[![Build status](https://ci.appveyor.com/api/projects/status/9vaaqchtx1d5nldj?svg=true)](https://ci.appveyor.com/project/radek-k/ffmediatoolkit) [![Nuget](https://img.shields.io/nuget/v/FFMediaToolkit.svg)](https://www.nuget.org/packages/FFMediaToolkit/)\n[![License](https://img.shields.io/github/license/radek-k/FFMediaToolkit.svg)](https://github.com/radek-k/FFMediaToolkit/blob/master/LICENSE)\n\n\u003e ⚠ **This library is not recommended for production use.**\n\n**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.\n\n## Features\n\n- Decoding/encoding audio-video files in many formats supported by FFmpeg.\n- Extracting audio data as floating point arrays.\n- Access to any video frame by timestamp.\n- Creating videos from images with metadata, pixel format, bitrate, CRF, FPS, GoP, dimensions and other codec settings.\n- Supports reading multimedia chapters and metadata.\n\n## Code samples\n\n- Extract all video frames as PNG files\n  \n    ```c#\n    int i = 0;\n    var file = MediaFile.Open(@\"C:\\videos\\movie.mp4\");\n    while(file.Video.TryGetNextFrame(out var imageData))\n    {\n        imageData.ToBitmap().Save($@\"C:\\images\\frame_{i++}.png\");\n        // See the #Usage details for example .ToBitmap() implementation\n        // The .Save() method may be different depending on your graphics library\n    }\n    ```\n\n- Video decoding\n  \n    ```c#\n    // Opens a multimedia file.\n    // You can use the MediaOptions properties to set decoder options.\n    var file = MediaFile.Open(@\"C:\\videos\\movie.mp4\");\n    \n     // Gets the frame at 5th second of the video.\n    var frame5s = file.Video.GetFrame(TimeSpan.FromSeconds(5));\n    \n    // Print informations about the video stream.\n    Console.WriteLine($\"Bitrate: {file.Info.Bitrate / 1000.0} kb/s\");\n    var info = file.Video.Info;\n    Console.WriteLine($\"Duration: {info.Duration}\");\n    Console.WriteLine($\"Frames count: {info.NumberOfFrames ?? \"N/A\"}\");\n    var frameRateInfo = info.IsVariableFrameRate ? \"average\" : \"constant\";\n    Console.WriteLine($\"Frame rate: {info.AvgFrameRate} fps ({frameRateInfo})\");\n    Console.WriteLine($\"Frame size: {info.FrameSize}\");\n    Console.WriteLine($\"Pixel format: {info.PixelFormat}\");\n    Console.WriteLine($\"Codec: {info.CodecName}\");\n    Console.WriteLine($\"Is interlaced: {info.IsInterlaced}\");\n    ```\n\n- Encode video from images.\n  \n    ```c#\n    // You can set there codec, bitrate, frame rate and many other options.\n    var settings = new VideoEncoderSettings(width: 1920, height: 1080, framerate: 30, codec: VideoCodec.H264);\n    settings.EncoderPreset = EncoderPreset.Fast;\n    settings.CRF = 17;\n    using(var file = MediaBuilder.CreateContainer(@\"C:\\videos\\example.mp4\").WithVideo(settings).Create())\n    {\n        while(file.Video.FramesCount \u003c 300)\n        {\n            file.Video.AddFrame(/*Your code*/);\n        }\n    }\n    ```\n\n## Setup\n\nInstall the **FFMediaToolkit** package from [NuGet](https://www.nuget.org/packages/FFMediaToolkit/).\n\n```shell\ndotnet add package FFMediaToolkit\n```\n  \n```Package\nPM\u003e Install-Package FFMediaToolkit\n```\n\n**FFmpeg libraries are not included in the package.** To use FFMediaToolkit, you need the **FFmpeg shared build** binaries: `avcodec`, `avformat`, `avutil`, `swresample`, `swscale`.\n\n- **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`.\n- **Linux** - Download FFmpeg using your package manager.\n- **macOS**, **iOS**, **Android** - Not supported.\n\n**You need to set `FFmpegLoader.FFmpegPath` with a full path to FFmpeg libraries.**\n\u003e If you want to use 64-bit FFmpeg, you have to disable the *Build* -\u003e *Prefer 32-bit* option in Visual Studio project properties.\n\n## Usage details\n\nFFMediaToolkit 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\u003cbyte\u003e`](https://docs.microsoft.com/pl-pl/dotnet/api/system.span-1?view=netstandard-2.1).\n\n\u003e **If you want to process or save the `ImageData`, you should convert it to another graphics object, using one of the following methods.**\n\n\u003e **These methods are not included in the program to avoid additional dependencies and provide compatibility with many graphics libraries.**\n\n- **For [ImageSharp](https://github.com/SixLabors/ImageSharp) library (.NET Standard/Core - cross-platform):**\n  \n    ```c#\n    using SixLabors.ImageSharp;\n    using SixLabors.ImageSharp.PixelFormats;\n    ...\n    public static Image\u003cBgr24\u003e ToBitmap(this ImageData imageData)\n    {\n        return Image.LoadPixelData\u003cBgr24\u003e(imageData.Data, imageData.ImageSize.Width, imageData.ImageSize.Height);\n    }\n    ```\n\n- **For .NET Framework `System.Drawing.Bitmap` (Windows only):**\n  \n    ```c#\n    // ImageData -\u003e Bitmap (unsafe)\n    public static unsafe Bitmap ToBitmap(this ImageData bitmap)\n    {\n        fixed(byte* p = bitmap.Data)\n        {\n            return new Bitmap(bitmap.ImageSize.Width, bitmap.ImageSize.Height, bitmap.Stride, PixelFormat.Format24bppRgb, new IntPtr(p));\n        }\n    }\n  \n    // Bitmap -\u003e ImageData (safe)\n    ...\n        var rect = new Rectangle(Point.Empty, bitmap.Size);\n        var bitLock = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);\n        var bitmapData = ImageData.FromPointer(bitLock.Scan0, bitmap.Size, ImagePixelFormat.Bgr24);\n        \n        mediaFile.Video.AddFrame(bitmapData); // Encode the frame\n        \n        bitmap.UnlockBits(bitLock); // UnlockBits() must be called after encoding the frame\n   ...\n    ```\n\n- **For .NET Framework/Core desktop apps with WPF UI. (Windows only):**\n  \n    ```c#\n    using System.Windows.Media.Imaging;\n    ...\n    // ImageData -\u003e BitmapSource (unsafe)\n    public static unsafe BitmapSource ToBitmap(this ImageData bitmapData)\n    {\n        fixed(byte* ptr = bitmapData.Data)\n        {\n            return BitmapSource.Create(bitmapData.ImageSize.Width, bitmapData.ImageSize.Height, 96, 96, PixelFormats.Bgr32, null, new IntPtr(ptr), bitmapData.Data.Length, bitmapData.Stride);\n        }\n    }\n  \n    // BitmapSource -\u003e ImageData (safe)\n    public static ImageData ToImageData(this BitmapSource bitmap)\n    {\n        var wb = new WriteableBitmap(bitmap);\n        return ImageData.FromPointer(wb.BackBuffer, ImagePixelFormat.Bgra32, wb.PixelWidth, wb.PixelHeight);\n    }\n    ```\n\n- **FFMediaToolkit will also work with any other graphics library that supports creating images from `Span\u003cbyte\u003e`, byte array or memory pointer**\n\n## Visual Basic usage\nWriting decoded bitmap directly to the WPF `WriteableBitmap` buffer using the `TryReadFrameToPointer` method:\n````vb\nDim file As FileStream = New FileStream(\"path to the video file\", FileMode.Open, FileAccess.Read)\nDim media As MediaFile = MediaFile.Load(file)\nDim bmp As WriteableBimap = New WriteableBitmap(media.Video.Info.FrameSize.Width, media.Video.Info.FrameSize.Height, 96, 96, PixelFormats.Bgr24, Nothing)\nbmp.Lock()\nDim decoded As Boolean = media.Video.TryGetFrame(TimeSpan.FromMinutes(1), bmp.BackBuffer, bmp.BackBufferStride)\nIf decoded Then\n    bmp.AddDirtyRect(New Int32Rect(0, 0, media.Video.Info.FrameSize.Width, media.Video.Info.FrameSize.Height))\nEnd If\nbmp.Unlock()\nimageBox.Source = bmp\n````\nConverting `ImageData` to a byte array:\n````vb\nDim data() As Byte = media.Video.GetNextFrame().Data.ToArray()\n````\n## Licensing\n\nThis project is licensed under the [MIT](https://github.com/radek-k/FFMediaToolkit/blob/master/LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradek-k%2Fffmediatoolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradek-k%2Fffmediatoolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradek-k%2Fffmediatoolkit/lists"}