ManagedCodecs.Thumbnails 0.8.0

dotnet add package ManagedCodecs.Thumbnails --version 0.8.0
                    
NuGet\Install-Package ManagedCodecs.Thumbnails -Version 0.8.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ManagedCodecs.Thumbnails" Version="0.8.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ManagedCodecs.Thumbnails" Version="0.8.0" />
                    
Directory.Packages.props
<PackageReference Include="ManagedCodecs.Thumbnails" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ManagedCodecs.Thumbnails --version 0.8.0
                    
#r "nuget: ManagedCodecs.Thumbnails, 0.8.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ManagedCodecs.Thumbnails@0.8.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ManagedCodecs.Thumbnails&version=0.8.0
                    
Install as a Cake Addin
#tool nuget:?package=ManagedCodecs.Thumbnails&version=0.8.0
                    
Install as a Cake Tool

ManagedCodecs.Thumbnails

Thumbnails and the basic facts of an uploaded video, without FFmpeg, in pure managed C#: for web back ends, serverless functions and Blazor WebAssembly apps that cannot run FFmpeg, on files nobody has vetted.

The stream must be seekable. An MP4 file's index can come after its data (most camera and phone files), so an ASP.NET request body or a serverless upload is first buffered: a MemoryStream, or a temporary file for large ones.

using ManagedCodecs.Thumbnails;

await using var buffer = new MemoryStream();
await request.Body.CopyToAsync(buffer);
buffer.Position = 0;

var info = VideoProbe.Read(buffer);
// info.Duration, info.DisplayWidth x info.DisplayHeight (as shown: aspect ratio and phone rotation applied),
// info.Codec, info.FramesPerSecond, info.Rotation, info.Audio?.SampleRate, info.Audio?.Channels

buffer.Position = 0;
var thumbnail = await VideoThumbnail.CreateAsync(buffer, new ThumbnailOptions { MaxWidth = 480 }, cancellationToken);
thumbnail.SavePng(output); // or thumbnail.SaveJpeg(output, quality: 85), or thumbnail.Pixels (RGBA) to an image library for WebP
  • The thumbnail: the frame shown at ThumbnailOptions.At, as ffmpeg's -ss takes it (by default 10% in, at most 10 s; with SkipDark, past dark frames keyframe by keyframe), upright, scaled down by area to fit MaxWidth x MaxHeight, converted by the frame's own matrix and range. Within 0 to 3 levels of FFmpeg's scaler on every sample tested.
  • Untrusted input: frames larger than MaxPixels (16,777,216 by default) are refused before decoding, a CancellationToken stops the work, and damaged streams decode on with concealment.
  • What it reads: MP4 (QuickTime, fragmented and edited files too) and AVI, with H.264 or MJPEG video. The probe decodes nothing; it reads the headers and sample tables only.
  • As ffprobe reports them: the duration is format=duration's and the size, aspect ratio, rotation, frame rate and audio facts are ffprobe's, checked on every sample the library is tested with. The displayed size is the coded one stretched by the pixels' aspect ratio (wider for a ratio above 1, taller below it), then turned by the rotation.
  • What it refuses: a codec the library does not decode (HEVC, VP9, AV1, MPEG-4 Part 2) throws NotSupportedException; a file without video, or one that isn't AVI or MP4 or is malformed, throws InvalidDataException. AVI's audio is not read (Audio is null), so an AVI file lasts as long as its video.

The README has the rest, and the decision record the design. MIT licensed; the license covers the code, not the formats: codec patents (H.264, AAC) apply regardless of the language a decoder is written in.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.8.0 0 11/4/2026
0.7.0 221 11/2/2026
0.6.0 142 11/1/2026
0.5.0 281 11/1/2026