MathewSachin/Captura · error · FFmpegNotFoundException

FFmpeg could not be found. Please download using the…

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.

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.

Appendix: 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)