subhra74/xdm · error · AssembleFailedException

FFmpegNotFound

FFmpegNotFound

Error message

ErrorCode.FFmpegNotFound

What it means

After downloading, AssemblePieces may convert the file to MP3 audio via mediaProcessor.ConvertToMp3Audio. If the result is not MediaProcessingResult.Success, an AssembleFailedException is thrown with ErrorCode.FFmpegNotFound (when the ffmpeg executable was not found) or ErrorCode.FFmpegError for other processing failures.

Solutions

  1. Install ffmpeg and ensure it is on the system PATH (or set the configured ffmpeg path in settings).
  2. Verify the exact executable path: run `ffmpeg -version` in a terminal as the same user running the downloader.
  3. Disable ConvertToMp3 in Config.Instance if conversion is not required - the original file will be kept.
  4. Reinstall/repair the app so its bundled media processor is restored.

Example fix

// before
config.ConvertToMp3 = true; // ffmpeg not installed -> FFmpegNotFound
// after
if (IsOnPath("ffmpeg")) config.ConvertToMp3 = true;
else { InstallFfmpeg(); /* or */ config.ConvertToMp3 = false; }
Defensive patterns

Strategy: fallback

Validate before calling

static bool FfmpegAvailable() {
    try { var psi = new ProcessStartInfo("ffmpeg", "-version") { UseShellExecute = false };
          using var p = Process.Start(psi); return p != null; }
    catch { return false; }
}
// before enabling: if (!FfmpegAvailable()) keepOriginalFileOnly = true;

Try / catch

try { downloader.Resume(); }
catch (AssembleFailedException e) when (e.ErrorCode == ErrorCode.FFmpegNotFound) {
    KeepOriginalFile(); // skip MP3 conversion
    NotifyUser("Install ffmpeg for MP3 conversion");
}

Prevention

When it happens

Trigger: ConvertToMp3Audio returns MediaProcessingResult.AppNotFound because the ffmpeg/external media tool cannot be located on the system PATH or configured location while ConvertToMp3 is enabled in Config.

Common situations: ffmpeg not installed, installed but not on PATH, bundled ffmpeg missing after an app update, flatpak/snap confinement hiding the binary, wrong custom tool path configured in settings.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of subhra74/xdm@1ca5a25aae (2026-09-13). Data as JSON: /api/errors/42ae28dd71bd783d. Report an issue: GitHub.

Appendix: source

Thrown at app/XDM/XDM.Core/Downloader/Progressive/SingleHttp/SingleSourceHTTPDownloader.cs:426

                        }

                        if (this.cancelFlag.IsCancellationRequested) return;

                        if (state!.ConvertToMp3)
                        {
                            if (mediaProcessor != null)
                            {
                                mediaProcessor.ProgressChanged += (s, e) =>
                                {
                                    var prg = 50 + e.Progress / 2;
                                    if (prg > 100) prg = 100;
                                    this.OnAssembleProgressChanged(prg);
                                };
                                var res = mediaProcessor.ConvertToMp3Audio(outFile!, TargetFile!,
                                    this.cancelFlag, out totalBytes);
                                if (res != MediaProcessingResult.Success)
                                {
                                    throw new AssembleFailedException(
                                        res == MediaProcessingResult.AppNotFound ? ErrorCode.FFmpegNotFound :
                                        ErrorCode.FFmpegError); //TODO: Add more info about error
                                }

                                if (Config.Instance.FetchServerTimeStamp)
                                {
                                    try
                                    {
                                        File.SetLastWriteTime(TargetFile, state.LastModified);
                                    }
                                    catch { }
                                }
                                this.totalSize = totalBytes;
                            }
                            else
                            {
                                throw new AssembleFailedException(ErrorCode.Generic); //TODO: Add more info about error
                            }

View on GitHub (pinned to 1ca5a25aae)