nilaoda/N_m3u8DL-RE · error · FileNotFoundException
ResString.mkvmergeNotFound
Error message
ResString.mkvmergeNotFound
What it means
When --use-mkvmerge is combined with --mux-after-done, DoWorkAsync requires the mkvmerge binary. It falls back to GlobalUtil.FindExecutable("mkvmerge") and throws FileNotFoundException with the localized resource string if mkvmerge cannot be located on disk.
Solutions
- Install MKVToolNix so mkvmerge is on PATH
- Pass --mkvmerge-binary-path with the full path to mkvmerge
- Verify with: mkvmerge --version
- Drop --use-mkvmerge to use the default ffmpeg muxer instead
Example fix
// before N_m3u8DL-RE "URL" -M --use-mkvmerge // after N_m3u8DL-RE "URL" -M --use-mkvmerge --mkvmerge-binary-path "/usr/bin/mkvmerge"
Defensive patterns
Strategy: validation
Validate before calling
if (useMkvmerge && muxAfterDone)
{
var mkv = GlobalUtil.FindExecutable("mkvmerge");
if (mkv == null || !File.Exists(mkv)) throw new FileNotFoundException("install MKVToolNix or pass --mkvmerge-binary-path");
} Type guard
static bool MkvmergeAvailable(CLIOptions o) => !o.MuxOptions.UseMkvmerge || (o.MkvmergeBinaryPath != null && File.Exists(o.MkvmergeBinaryPath)) || GlobalUtil.FindExecutable("mkvmerge") != null; Try / catch
try { await DoWorkAsync(option); }
catch (FileNotFoundException ex) when (ex.Message.Contains("mkvmerge"))
{
Console.Error.WriteLine("mkvmerge not found: install MKVToolNix or set --mkvmerge-binary-path");
} Prevention
- Install MKVToolNix alongside ffmpeg on machines used for muxing
- On Windows, add the MKVToolNix install directory to PATH
- Verify with `mkvmerge --version` before long batch runs
When it happens
Trigger: Running with --mux-after-done --use-mkvmerge while mkvmerge (from MKVToolNix) is not installed, not on PATH, or --mkvmerge-binary-path points to a missing file.
Common situations: Users choosing mkvmerge muxing without MKVToolNix installed; Windows PATH not including MKVToolNix install dir; typo in custom binary path.
Related errors
- ResString.ffmpegNotFound
- MuxAfterDone disabled, MuxImports not allowed!
- ResString.shakaPackagerNotFound
- Key must be 12 or 8 bytes!
- Download init file failed!
AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13).
Data as JSON: /api/errors/9fa225a1c2b611a7.
Report an issue: GitHub.
Appendix: source
Thrown at src/N_m3u8DL-RE/Program.cs:146
}
// 预先检查ffmpeg
option.FFmpegBinaryPath ??= GlobalUtil.FindExecutable("ffmpeg");
if (string.IsNullOrEmpty(option.FFmpegBinaryPath) || !File.Exists(option.FFmpegBinaryPath))
{
throw new FileNotFoundException(ResString.ffmpegNotFound);
}
Logger.Extra($"ffmpeg => {option.FFmpegBinaryPath}");
// 预先检查mkvmerge
if (option is { MuxOptions.UseMkvmerge: true, MuxAfterDone: true })
{
option.MkvmergeBinaryPath ??= GlobalUtil.FindExecutable("mkvmerge");
if (string.IsNullOrEmpty(option.MkvmergeBinaryPath) || !File.Exists(option.MkvmergeBinaryPath))
{
throw new FileNotFoundException(ResString.mkvmergeNotFound);
}
Logger.Extra($"mkvmerge => {option.MkvmergeBinaryPath}");
}
// 预先检查
if (option.Keys is { Length: > 0 } || option.KeyTextFile != null)
{
if (!string.IsNullOrEmpty(option.DecryptionBinaryPath) && !File.Exists(option.DecryptionBinaryPath))
{
throw new FileNotFoundException(option.DecryptionBinaryPath);
}
switch (option.DecryptionEngine)
{
case DecryptEngine.SHAKA_PACKAGER:
{
var file = FindShakaPackager();
if (file == null) throw new FileNotFoundException(ResString.shakaPackagerNotFound);
option.DecryptionBinaryPath = file;View on GitHub (pinned to e113dee70c)