MathewSachin/Captura · error · FFmpegNotFoundException

FFmpeg could not be found. Please download using the in-buil

Error message

FFmpeg could not be found. Please download using the in-built downloader.

What it means

Thrown by the FFmpegWriter constructor (src/Captura.FFmpeg/Video/FFmpegVideoWriter.cs:36) when FFmpegService.FFmpegExists is false. The live video writer must spawn ffmpeg before creating its named pipes, so it refuses construction without the binary.

Source

Thrown at src/Captura.FFmpeg/Video/FFmpegVideoWriter.cs:36

        readonly NamedPipeServerStream _ffmpegIn;
        byte[] _videoBuffer;

        // This semaphore helps prevent FFmpeg audio/video pipes getting deadlocked.
        readonly SemaphoreSlim _spVideo = new SemaphoreSlim(5);

        // Timeout used with Semaphores, if elapsed would mean FFmpeg might be deadlocked.
        readonly TimeSpan _spTimeout = TimeSpan.FromMilliseconds(50);

        static string GetPipeName() => $"captura-{Guid.NewGuid()}";

        /// <summary>
        /// Creates a new instance of <see cref="FFmpegWriter"/>.
        /// </summary>
        public FFmpegWriter(FFmpegVideoWriterArgs Args)
        {
            if (!FFmpegService.FFmpegExists)
            {
                throw new FFmpegNotFoundException();
            }

            var nv12 = Args.ImageProvider.DummyFrame is INV12Frame;

            var settings = ServiceProvider.Get<FFmpegSettings>();

            var w = Args.ImageProvider.Width;
            var h = Args.ImageProvider.Height;

            _videoBuffer = new byte[(int)(w * h * (nv12 ? 1.5 : 4))];

            Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}");

            var videoPipeName = GetPipeName();

            var argsBuilder = new FFmpegArgsBuilder();

            argsBuilder.AddInputPipe(videoPipeName)

View on GitHub (pinned to 3fdf41529b)

Solutions

  1. Guarantee FFmpegService.FFmpegExists is true before enabling the Record button (run the downloader otherwise).
  2. Verify FFmpegSettings.GetFolderPath() resolves to a real ffmpeg.exe.
  3. Place ffmpeg.exe in the app or lib directory as a fallback.

Example fix

// before
var writer = new FFmpegWriter(args);
// after
if (!FFmpegService.FFmpegExists)
    throw new FFmpegNotFoundException();
var writer = new FFmpegWriter(args);
Defensive patterns

Strategy: validation

Validate before calling

// gate the Record button
recordButton.Enabled = FFmpegService.FFmpegExists;
// and at construction time
if (!FFmpegService.FFmpegExists) throw new FFmpegNotFoundException();

Type guard

static FFmpegWriter CreateOrThrow(FFmpegVideoWriterArgs args)
    => FFmpegService.FFmpegExists ? new FFmpegWriter(args) : throw new FFmpegNotFoundException();

Try / catch

try { var w = new FFmpegWriter(args); }
catch (FFmpegNotFoundException) { /* run downloader, do not retry blindly */ }

Prevention

When it happens

Trigger: Constructing FFmpegWriter (the live recording writer) when FFmpegService.FFmpegExists is false. This is the start-of-recording path, so it fails before any pipe or process is created.

Common situations: User hits Record on a fresh install with no ffmpeg downloaded; the FFmpeg folder setting points at a removed directory; ffmpeg.exe deleted by AV or cleanup.

Related errors


AI-assisted analysis of MathewSachin/Captura@3fdf41529b (2026-08-13). Data as JSON: /api/errors/aa95d849dfcdf318. Report an issue: GitHub.