From 9f34dd100bca086c4e73b9ac9ebea320e5f3caf2 Mon Sep 17 00:00:00 2001 From: DoTheSneedful Date: Tue, 4 Jun 2024 22:36:35 -0400 Subject: [PATCH] Fix for ffmpeg/ffprobe long paths not working In effect, ffprobe/mkvextract cannot read the long path to get the streams. For example, when trying to use the subtitle filter to burn internal subs no subtitle streams were extracted from the file so none were shown when trying to use the filter. Solution is use \\?\ or \\?\UNC\ prefix for programs that do not have a similar manifest for native longer path support. Testing: Trim/Crop/Subtitle/Resize filters on a long path in the typical format and UNC path format. Z:\anime\WorldEnd - What are you doing at the end of the world! Are you busy! Will you save us! (2017) [tvdb-325208]\Season 01\WorldEnd - What are you doing at the end of the world! Are you busy! Will you save us! (2017) - S01E01 - Broken Chronograph [HDTV-1080p][AAC 2.0][x265].mkv \\192.168.2.80\media-server\anime\WorldEnd - What are you doing at the end of the world! Are you busy! Will you save us! (2017) [tvdb-325208]\Season 01\WorldEnd - What are you doing at the end of the world! Are you busy! Will you save us! (2017) - S01E02 - Late Autumn Nights Dream [HDTV-1080p][AAC 2.0][x265].mkv --- Components/FFprobe.cs | 1 + MainForm.cs | 7 ++++--- Utility.cs | 18 +++++++++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Components/FFprobe.cs b/Components/FFprobe.cs index ce6e54c..3e764eb 100644 --- a/Components/FFprobe.cs +++ b/Components/FFprobe.cs @@ -17,6 +17,7 @@ class FFprobe : Process public FFprobe(string inputFile, string format = "-f avisynth", List dataToProbe = null, string argument = null) { + inputFile = Utility.ExtendedLenPath(inputFile); if (argument == null) // No override arguments, time to construct this bad boy { if (dataToProbe == null) diff --git a/MainForm.cs b/MainForm.cs index 872ae92..9b85abf 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -1794,6 +1794,7 @@ void SetFile(string path) string streamInfo = prober.Probe(); Program.SubtitleTracks = new Dictionary>(); Program.AttachmentList = new List(); + var workingFile = Utility.ExtendedLenPath(Program.InputFile); using (var s = new StringReader(streamInfo)) { @@ -1890,12 +1891,12 @@ void SetFile(string path) if (type == SubtitleType.VTTSub && !File.Exists(file)) { logIndexingProgress("Extracting vtt..."); - ExecuteFFmpegCommand($@" -i ""{Program.InputFile}"" -map 0:{streamindex} ""{file}"""); + ExecuteFFmpegCommand($@" -i ""{workingFile}"" -map 0:{streamindex} ""{file}"""); } else if (!File.Exists(file)) // If we didn't extract it already { logIndexingProgress("Extracting..."); - using (var mkvextract = new MkvExtract($@"tracks ""{Program.InputFile}"" ""{streamindex}:{file}""")) + using (var mkvextract = new MkvExtract($@"tracks ""{workingFile}"" ""{streamindex}:{file}""")) { mkvextract.Start(); mkvextract.WaitForExit(); @@ -1946,7 +1947,7 @@ void SetFile(string path) } logIndexingProgress("Extracting..."); - using (var mkvextract = new MkvExtract($@"attachments ""{Program.InputFile}"" ""{attachindex}:{file}""")) + using (var mkvextract = new MkvExtract($@"attachments ""{workingFile}"" ""{attachindex}:{file}""")) { mkvextract.Start(); mkvextract.WaitForExit(); diff --git a/Utility.cs b/Utility.cs index a8e2796..3042378 100644 --- a/Utility.cs +++ b/Utility.cs @@ -141,7 +141,7 @@ public static string GetCompatiblePath(string input) { // AviSynth and various plugins can't deal with utf-8 paths, so we convert the possibly weird path into 8.3 notation var compatible = new StringBuilder(255); - NativeMethods.GetShortPathName(@"\\?\" + input, compatible, compatible.Capacity); + NativeMethods.GetShortPathName(ExtendedLenPath(input), compatible, compatible.Capacity); // the \\?\ is added because GetShortPathName will fail if input is longer than 256 characters otherwise. return compatible.ToString(); } @@ -438,6 +438,22 @@ public static System.Drawing.Font CreateFontFromString(String data) return new Font(fontName, fontSize, fontStyle); } + public static string ExtendedLenPath(string path) + { + string pathWithPrefix; + // ffmpeg + tools only support long paths when using the \\?\ prefix + // https://trac.ffmpeg.org/ticket/8885 + // https://learn.microsoft.com/en-gb/windows/win32/fileio/maximum-file-path-limitation?tabs=registry + if (path.StartsWith(@"\\")) + { + pathWithPrefix = @"\\?\UNC" + path.Substring(1); + } + else + { + pathWithPrefix = @"\\?\" + path; + } + return pathWithPrefix; + } } public enum FileType