Last updated: February 23, 2025

<span aria-hidden="true" id="automate-video-thumbnails-with-ffmpeg-and-net"></span>

# Automate video thumbnails with FFmpeg and .Net

![Tim Koschützki](/assets/images/teammates/avatar-tim-kos-1.jpg?dpl=dpl_C6YH6XrtnwbHLJcm1LDKywQn4CB3)

#### Tim Koschützki

Co-founder · Berlin, Germany · Show bio

[](https://x.com/tim%5Fkos)[](https://github.com/tim-kos)

Video processing is an essential part of many applications, whether you're building a content management system or simply providing video previews for your users. In this DevTip, you'll learn how to automate video thumbnail generation using FFmpeg in .NET. With modern libraries and async programming, you can integrate a robust thumbnail extraction process into your applications.

<span aria-hidden="true" id="setting-up-ffmpeg-and-ffmpegcore"></span>

## Setting up FFmpeg and ffmpegcore

First, ensure FFmpeg is installed on your system. You can download it from the[official website⁠](https://ffmpeg.org/download.html) or use package managers:

* Windows: `winget install ffmpeg`
* macOS: `brew install ffmpeg`
* Ubuntu/Debian: `apt install ffmpeg`

Next, add the FFMpegCore NuGet package to your .NET project:

```xml
<PackageReference Include="FFMpegCore" Version="5.2.0" />

```

<span aria-hidden="true" id="creating-a-thumbnail-generator-service"></span>

## Creating a thumbnail generator service

Let's create a service that handles thumbnail generation using FFMpegCore:

```csharp
using FFMpegCore;
using FFMpegCore.Enums;
using Microsoft.Extensions.Logging;

public class ThumbnailService
{
    private readonly ILogger<ThumbnailService> _logger;

    public ThumbnailService(ILogger<ThumbnailService> logger)
    {
        _logger = logger;
    }

    public async Task<bool> GenerateThumbnailAsync(
        string inputFile,
        string outputFile,
        TimeSpan captureTime,
        int width = 320,
        int height = 240)
    {
        try
        {
            await FFMpegArguments
                .FromFileInput(inputFile)
                .OutputToFile(outputFile, false, options =>
                    options
                        .Seek(captureTime)
                        .WithFrameOutputCount(1)
                        .WithVideoFilters(filterOptions =>
                            filterOptions.Scale(width: width, height: height))
                )
                .ProcessAsynchronously();

            return true;
        }
        catch (FFMpegException ex)
        {
            _logger.LogError(ex, "FFmpeg error while generating thumbnail");
            return false;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unexpected error while generating thumbnail");
            return false;
        }
    }
}

```

<span aria-hidden="true" id="how-the-code-works"></span>

### How the code works

* The service uses dependency injection for logging
* FFMpegCore provides a fluent API for configuring FFmpeg commands
* The `-ss` seek operation is handled by the `Seek` method
* Video scaling is configured through the `WithVideoFilters` option
* Proper async/await patterns are implemented
* Comprehensive error handling with logging is included

<span aria-hidden="true" id="using-the-thumbnail-service"></span>

## Using the thumbnail service

Here's how to use the thumbnail service in a .NET application:

```csharp
public class Program
{
    public static async Task Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddConsole()
                .SetMinimumLevel(LogLevel.Information);
        });

        var logger = loggerFactory.CreateLogger<ThumbnailService>();
        var thumbnailService = new ThumbnailService(logger);

        var result = await thumbnailService.GenerateThumbnailAsync(
            inputFile: "sample.mp4",
            outputFile: "thumbnail.jpg",
            captureTime: TimeSpan.FromSeconds(5)
        );

        Console.WriteLine(result
            ? "Thumbnail generated successfully"
            : "Failed to generate thumbnail");
    }
}

```

<span aria-hidden="true" id="advanced-features"></span>

## Advanced features

The thumbnail service can be extended with additional features:

```csharp
public class ThumbnailService
{
    // ... existing code ...

    public async Task<IReadOnlyList<string>> GenerateMultipleThumbnailsAsync(
        string inputFile,
        string outputDirectory,
        int count)
    {
        var mediaInfo = await FFProbe.AnalyseAsync(inputFile);
        var duration = mediaInfo.Duration;
        var interval = duration.TotalSeconds / (count + 1);
        var thumbnails = new List<string>();

        for (var i = 1; i <= count; i++)
        {
            var time = TimeSpan.FromSeconds(interval * i);
            var outputFile = Path.Combine(
                outputDirectory,
                $"thumbnail_{i:D2}.jpg"
            );

            if (await GenerateThumbnailAsync(inputFile, outputFile, time))
            {
                thumbnails.Add(outputFile);
            }
        }

        return thumbnails;
    }
}

```

This extension allows generating multiple thumbnails at evenly spaced intervals throughout the video.

<span aria-hidden="true" id="cross-platform-considerations"></span>

## Cross-platform considerations

FFMpegCore automatically handles path differences across operating systems, but ensure FFmpeg is properly installed and accessible in your system's PATH. For containerized environments, include FFmpeg installation in your Dockerfile:

```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0
RUN apt-get update && apt-get install -y ffmpeg

```

<span aria-hidden="true" id="version-compatibility"></span>

## Version compatibility

This solution has been tested with:

* .NET 6.0 or later
* FFmpeg 4.x or later
* FFMpegCore 5.2.0

<span aria-hidden="true" id="conclusion"></span>

## Conclusion

FFMpegCore provides a modern, type-safe way to integrate FFmpeg with .NET applications for video thumbnail generation. This approach offers better error handling, cross-platform support, and async operations compared to direct process calls. For more advanced video processing needs, check out Transloadit's [🤖/video/thumbs](/docs/robots/video-thumbs.md) robot, which handles thumbnail generation at scale.

Happy coding!

\#ffmpeg#dotnet#c-sharp#video-encoding-service

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed · 5 GB included in the free plan

Cancel anytime
