diff --git a/CodeLegacy/Data/MediaFile.cs b/CodeLegacy/Data/MediaFile.cs index 61ab667..6ebcd07 100644 --- a/CodeLegacy/Data/MediaFile.cs +++ b/CodeLegacy/Data/MediaFile.cs @@ -101,7 +101,7 @@ namespace Flowframes.Data public async Task Initialize(bool progressBar = true, bool countFrames = true) { - Logger.Log($"MediaFile {Name}: Initializing", true); + Logger.Log($"Analyzing media '{Name}'", true); try { @@ -116,11 +116,10 @@ namespace Flowframes.Data DataStreams = AllStreams.Where(x => x.Type == Stream.StreamType.Data).Select(x => (DataStream)x).ToList(); AttachmentStreams = AllStreams.Where(x => x.Type == Stream.StreamType.Attachment).Select(x => (AttachmentStream)x).ToList(); MayHaveAlpha = VideoStreams.Any(vs => vs.CanHaveAlpha); - Logger.Log($"Loaded and sorted streams for {Name}", true); } catch (Exception e) { - Logger.Log($"Failed to initialized MediaFile: {e.Message}", true); + Logger.Log($"Failed to initialize MediaFile: {e.Message}", true); } Initialized = true; diff --git a/CodeLegacy/Data/QueryInfo.cs b/CodeLegacy/Data/QueryInfo.cs index 4dc86c3..509be4e 100644 --- a/CodeLegacy/Data/QueryInfo.cs +++ b/CodeLegacy/Data/QueryInfo.cs @@ -2,15 +2,33 @@ { class QueryInfo { - public string path; - public long filesize; - public string cmd = null; + public string Path; + public long SizeBytes; + public string Command = ""; - public QueryInfo(string path, long filesize, string cmd = null) + public QueryInfo(string path, long filesize = 0, string cmd = "") { - this.path = path; - this.filesize = filesize; - this.cmd = cmd; + Path = path; + SizeBytes = filesize; + Command = cmd; + } + + public override bool Equals(object obj) + { + if (obj is QueryInfo other) + return Path == other.Path && SizeBytes == other.SizeBytes; + return false; + } + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 31 + (Path?.GetHashCode() ?? 0); + hash = hash * 31 + SizeBytes.GetHashCode(); + return hash; + } } } } diff --git a/CodeLegacy/IO/Symlinks.cs b/CodeLegacy/IO/Symlinks.cs index b973688..323e293 100644 --- a/CodeLegacy/IO/Symlinks.cs +++ b/CodeLegacy/IO/Symlinks.cs @@ -18,13 +18,13 @@ namespace Flowframes.IO public static bool SymlinksAllowed() { string origFile = Paths.GetExe(); - string linkPath = Paths.GetExe() + "lnktest"; - bool success = CreateSymbolicLink(linkPath, origFile, Flag.Unprivileged); + string testLinkPath = Paths.GetExe() + "lnktest"; + bool success = CreateSymbolicLink(testLinkPath, origFile, Flag.Unprivileged); if (!success) return false; - File.Delete(linkPath); + File.Delete(testLinkPath); return true; } diff --git a/CodeLegacy/Media/FfmpegCommands.cs b/CodeLegacy/Media/FfmpegCommands.cs index cd796a2..0b5e230 100644 --- a/CodeLegacy/Media/FfmpegCommands.cs +++ b/CodeLegacy/Media/FfmpegCommands.cs @@ -114,7 +114,7 @@ namespace Flowframes if (allowDurationFromMetadata) { - Logger.Log($"GetDuration({inputFile}) - Reading duration by checking metadata.", true, false, "ffmpeg"); + Logger.Log($"[{nameof(GetDurationMs)}] Reading duration by checking metadata", true, false, "ffmpeg"); string argsMeta = $"ffprobe -v quiet -show_streams -select_streams v:0 -show_entries stream=duration {inputFile.Wrap()}"; var outputLinesMeta = NUtilsTemp.OsUtils.RunCommand($"cd /D {GetAvDir().Wrap()} && {argsMeta}").SplitIntoLines(); @@ -144,7 +144,7 @@ namespace Flowframes if (demuxInsteadOfPacketTs) { - Logger.Log($"GetDuration({inputFile}) - Reading duration by demuxing.", true, false, "ffmpeg"); + Logger.Log($"[{nameof(GetDurationMs)}] Reading duration by demuxing", true, false, "ffmpeg"); string argsDemux = $"ffmpeg -loglevel panic -stats -i {inputFile.Wrap()} -map 0:v:0 -c copy -f null NUL"; var outputLinesDemux = NUtilsTemp.OsUtils.RunCommand($"cd /D {GetAvDir().Wrap()} && {argsDemux}").SplitIntoLines().Where(l => l.IsNotEmpty() && l.MatchesWildcard("*time=* *")); @@ -156,7 +156,7 @@ namespace Flowframes } else { - Logger.Log($"GetDuration({inputFile}) - Reading duration using packet timestamps.", true, false, "ffmpeg"); + Logger.Log($"[{nameof(GetDurationMs)}] Reading duration using packet timestamps", true, false, "ffmpeg"); string argsPackets = $"ffprobe -v error -select_streams v:0 -show_packets -show_entries packet=pts_time -of csv=p=0 {inputFile.Wrap()}"; var outputLinesPackets = NUtilsTemp.OsUtils.RunCommand($"cd /D {GetAvDir().Wrap()} && {argsPackets}").SplitIntoLines().Where(l => l.IsNotEmpty()).ToList(); @@ -405,10 +405,12 @@ namespace Flowframes public static async Task IsEncoderCompatible(string enc) { - Logger.Log($"IsEncoderCompatible('{enc}')", true, false, "ffmpeg"); + Logger.Log($"Running ffmpeg to check if encoder '{enc}' is available...", true, false, "ffmpeg"); string args = $"-loglevel error -f lavfi -i color=black:s=1920x1080 -vframes 1 -c:v {enc} -f null -"; string output = await RunFfmpeg(args, LogMode.Hidden); - return !output.SplitIntoLines().Where(l => !l.Lower().StartsWith("frame") && l.IsNotEmpty()).Any(); + bool compat = !output.SplitIntoLines().Where(l => !l.Lower().StartsWith("frame") && l.IsNotEmpty()).Any(); + Logger.Log($"Encoder '{enc}' is {(compat ? "available!" : "not available.")}", true, false, "ffmpeg"); + return compat; } public static List GetAudioCodecs(string path, int streamIndex = -1) diff --git a/CodeLegacy/Media/GetFrameCountCached.cs b/CodeLegacy/Media/GetFrameCountCached.cs index 928d9a0..2176d62 100644 --- a/CodeLegacy/Media/GetFrameCountCached.cs +++ b/CodeLegacy/Media/GetFrameCountCached.cs @@ -19,19 +19,15 @@ namespace Flowframes.Media public static async Task GetFrameCountAsync(string path, int retryCount = 3) { - Logger.Log($"Getting frame count ({path})", true); + Logger.Log($"Getting frame count ({path})...", true); long filesize = IoUtils.GetPathSize(path); QueryInfo hash = new QueryInfo(path, filesize); - if (filesize > 0 && CacheContains(hash)) + if (filesize > 0 && cache.ContainsKey(hash)) { - Logger.Log($"Cache contains this hash, using cached value.", true); - return GetFromCache(hash); - } - else - { - Logger.Log($"Hash not cached, reading frame count.", true); + Logger.Log($"Using cached frame count value.", true); + return cache[hash]; } int frameCount; @@ -54,7 +50,7 @@ namespace Flowframes.Media if (frameCount > 0) { - Logger.Log($"Adding hash with value {frameCount} to cache.", true); + Logger.Log($"Caching frame count ({frameCount}).", true); cache.Add(hash, frameCount); } else @@ -74,24 +70,6 @@ namespace Flowframes.Media return frameCount; } - private static bool CacheContains(QueryInfo hash) - { - foreach (KeyValuePair entry in cache) - if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize) - return true; - - return false; - } - - private static int GetFromCache(QueryInfo hash) - { - foreach (KeyValuePair entry in cache) - if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize) - return entry.Value; - - return 0; - } - public static void Clear() { cache.Clear(); diff --git a/CodeLegacy/Media/GetMediaResolutionCached.cs b/CodeLegacy/Media/GetMediaResolutionCached.cs index 9812834..cb9dd8b 100644 --- a/CodeLegacy/Media/GetMediaResolutionCached.cs +++ b/CodeLegacy/Media/GetMediaResolutionCached.cs @@ -38,12 +38,12 @@ namespace Flowframes.Media private static bool CacheContains(QueryInfo hash) { - return cache.Any(entry => entry.Key.path == hash.path && entry.Key.filesize == hash.filesize); + return cache.Any(entry => entry.Key.Path == hash.Path && entry.Key.SizeBytes == hash.SizeBytes); } private static Size GetFromCache(QueryInfo hash) { - return cache.Where(entry => entry.Key.path == hash.path && entry.Key.filesize == hash.filesize).Select(entry => entry.Value).FirstOrDefault(); + return cache.Where(entry => entry.Key.Path == hash.Path && entry.Key.SizeBytes == hash.SizeBytes).Select(entry => entry.Value).FirstOrDefault(); } public static void Clear() diff --git a/CodeLegacy/Media/GetVideoInfo.cs b/CodeLegacy/Media/GetVideoInfo.cs index e1ec9bb..1e3dcbc 100644 --- a/CodeLegacy/Media/GetVideoInfo.cs +++ b/CodeLegacy/Media/GetVideoInfo.cs @@ -30,7 +30,7 @@ namespace Flowframes.Media public static async Task GetFfmpegOutputAsync(string path, string argsIn, string argsOut, string lineFilter = "", bool noCache = false) { Process process = OsUtils.NewProcess(true); - process.StartInfo.Arguments = $"/C cd /D {GetAvPath().Wrap()} & " + + process.StartInfo.Arguments = $"/C cd /D {AvProcess.GetAvDir().Wrap()} & " + $"ffmpeg.exe -hide_banner -y {argsIn} {path.GetConcStr()} -i {path.Wrap()} {argsOut}"; return await GetInfoAsync(path, process, lineFilter, noCache); } @@ -41,7 +41,7 @@ namespace Flowframes.Media string showFormat = mode == FfprobeMode.ShowBoth || mode == FfprobeMode.ShowFormat ? "-show_format" : ""; string showStreams = mode == FfprobeMode.ShowBoth || mode == FfprobeMode.ShowStreams ? "-show_streams" : ""; - process.StartInfo.Arguments = $"/C cd /D {GetAvPath().Wrap()} & " + + process.StartInfo.Arguments = $"/C cd /D {AvProcess.GetAvDir().Wrap()} & " + $"ffprobe -v quiet {path.GetConcStr()} {showFormat} {showStreams} {path.Wrap()}"; string output = await GetInfoAsync(path, process, lineFilter, streamIndex, stripKeyName); @@ -112,7 +112,7 @@ namespace Flowframes.Media private static bool CacheContains(QueryInfo hash, ref Dictionary cacheDict) { foreach (KeyValuePair entry in cacheDict) - if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize && entry.Key.cmd == hash.cmd) + if (entry.Key.Path == hash.Path && entry.Key.SizeBytes == hash.SizeBytes && entry.Key.Command == hash.Command) return true; return false; @@ -121,7 +121,7 @@ namespace Flowframes.Media private static string GetFromCache(QueryInfo hash, ref Dictionary cacheDict) { foreach (KeyValuePair entry in cacheDict) - if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize && entry.Key.cmd == hash.cmd) + if (entry.Key.Path == hash.Path && entry.Key.SizeBytes == hash.SizeBytes && entry.Key.Command == hash.Command) return entry.Value; return ""; @@ -131,10 +131,5 @@ namespace Flowframes.Media { cmdCache.Clear(); } - - private static string GetAvPath() - { - return Path.Combine(Paths.GetPkgPath(), Paths.audioVideoDir); - } } } diff --git a/CodeLegacy/Os/NvApi.cs b/CodeLegacy/Os/NvApi.cs index e7389a4..2b075e4 100644 --- a/CodeLegacy/Os/NvApi.cs +++ b/CodeLegacy/Os/NvApi.cs @@ -29,13 +29,13 @@ namespace Flowframes.Os { float vramGb = gpu.GetVramGb(); vramGb = (float)(Math.Round(vramGb * 2, MidpointRounding.AwayFromZero) / 2); // Round to nearest 0.5 GB - Logger.Log($"Nvidia GPU: {gpu.FullName} ({vramGb.ToString("0.#")} GB) {GetArch(gpu)} Architecture", true); + Logger.Log($"[NvAPI] Nvidia GPU: {gpu.FullName} ({vramGb.ToString("0.#")} GB) {GetArch(gpu)} Architecture", true); GpuVram[gpu] = vramGb; } NvGpus = gpus.OrderByDescending(g => GpuVram[g]).ThenBy(g => g.FullName).ToList(); string mostVramGpu = gpus.Length > 1 ? $" Most VRAM: {GpuWithMostVram.FullName} ({GpuVram[GpuWithMostVram].ToString("0.#")} GB)" : ""; - Logger.Log($"Initialized Nvidia API in {sw.ElapsedMs} ms. GPU{(gpus.Length > 1 ? "s" : "")}: {string.Join(", ", gpus.Select(g => g.FullName))}.{mostVramGpu}", true); + Logger.Log($"[NvAPI] Initialized Nvidia API in {sw.ElapsedMs} ms. GPU{(gpus.Length > 1 ? "s" : "")}: {string.Join(", ", gpus.Select(g => g.FullName))}.{mostVramGpu}", true); } catch (Exception e) { diff --git a/CodeLegacy/Os/OsUtils.cs b/CodeLegacy/Os/OsUtils.cs index dd93768..3c43fb4 100644 --- a/CodeLegacy/Os/OsUtils.cs +++ b/CodeLegacy/Os/OsUtils.cs @@ -1,19 +1,19 @@ -using System.Collections.Generic; -using System.Text; -using System.Security.Principal; +using DiskDetector; +using DiskDetector.Models; +using Flowframes.MiscUtils; +using Microsoft.VisualBasic.Devices; +using Microsoft.Win32; using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Management; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using Flowframes.IO; -using DiskDetector; -using DiskDetector.Models; -using Microsoft.VisualBasic.Devices; -using Flowframes.MiscUtils; -using System.Linq; using Tulpep.NotificationWindow; -using System.Runtime.InteropServices; namespace Flowframes.Os { @@ -50,8 +50,7 @@ namespace Flowframes.Os } finally { - if (user != null) - user.Dispose(); + user?.Dispose(); } return isAdmin; } @@ -167,28 +166,29 @@ namespace Flowframes.Os } } - public static string GetWindowsVer() + public static string GetWindowsVer() => GetWindowsVerVerbose(out _); + + public static string GetWindowsVerVerbose(out string osDesc) { - string os = RuntimeInformation.OSDescription; + osDesc = RuntimeInformation.OSDescription.Replace("Microsoft ", "").Trim(); - if (os.StartsWith("Microsoft Windows 6.1")) - return "Windows 7"; - - if (os.StartsWith("Microsoft Windows 6.2")) - return "Windows 8"; - - if (os.StartsWith("Microsoft Windows 6.3")) - return "Windows 8.1"; - - if (os.StartsWith("Microsoft Windows 10.0")) + if (osDesc.StartsWith("Windows 10.0")) { - int buildNum = os.Split("Microsoft Windows 10.0").Last().GetInt(); + int buildNum = osDesc.Split("Windows 10.0").Last().GetInt(); // Assuming build numbers for distinguishing Windows 10 and 11 - Windows 10: Builds 10240 to 19044 - Windows 11: Builds 22000 and above return buildNum >= 22000 ? "Windows 11" : "Windows 10"; } - return ""; - // return os.Replace("Microsoft ", ""); // Fallback to raw description without "Microsoft " + if (osDesc.StartsWith("Windows 6.1")) + return "Windows 7"; + + if (osDesc.StartsWith("Windows 6.2")) + return "Windows 8"; + + if (osDesc.StartsWith("Windows 6.3")) + return "Windows 8.1"; + + return "???"; } public static IEnumerable GetChildProcesses(Process process) @@ -347,5 +347,31 @@ namespace Flowframes.Os return false; } } + + public enum DevModeState { Disabled, Enabled, Unknown } + + public static DevModeState GetDeveloperModeState() + { + const string subKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"; + const string valueName = "AllowDevelopmentWithoutDevLicense"; + + foreach (var view in new[] { RegistryView.Registry64, RegistryView.Registry32 }) + { + try + { + using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view)) + using (var key = baseKey.OpenSubKey(subKey, writable: false)) + { + if(key != null && key.GetValue(valueName) is int val) + { + return val == 1 ? DevModeState.Enabled : DevModeState.Disabled; + } + } + } + catch { } + } + + return DevModeState.Unknown; + } } } \ No newline at end of file diff --git a/CodeLegacy/Os/StartupChecks.cs b/CodeLegacy/Os/StartupChecks.cs index 0784629..6f06b53 100644 --- a/CodeLegacy/Os/StartupChecks.cs +++ b/CodeLegacy/Os/StartupChecks.cs @@ -11,11 +11,13 @@ namespace Flowframes.Os { class StartupChecks { + public static bool IsAdmin = OsUtils.IsUserAdministrator(); + static bool IsWin10Or11() { string winVer = OsUtils.GetWindowsVer(); - if (winVer.IsEmpty()) + if (winVer.Trim('?').IsEmpty()) return true; // If it fails, return true for future-proofing return winVer.Lower().Contains("windows 10") || winVer.Lower().Contains("windows 11"); @@ -43,8 +45,8 @@ namespace Flowframes.Os Application.Exit(); } - string winVer = OsUtils.GetWindowsVer(); - Logger.Log($"Running {winVer}", true); + string winVer = OsUtils.GetWindowsVerVerbose(out string winVerDesc); + Logger.Log($"[OS] Running {winVer} ({winVerDesc.Replace("Windows ", "")}) [{(IsAdmin ? "Admin" : "User")}]", true); if (!Environment.Is64BitOperatingSystem && !Config.GetBool("allow32Bit", false)) { @@ -70,7 +72,7 @@ namespace Flowframes.Os bool silent = Config.GetBool("silentDevmodeCheck", true); string ver = Updater.GetInstalledVer().ToString(); bool symlinksAllowed = Symlinks.SymlinksAllowed(); - Logger.Log($"Symlinks allowed: {symlinksAllowed}", true); + Logger.Log($"Symlink creation is {(symlinksAllowed ? "allowed." : $"not allowed!")} (Admin: {IsAdmin} - Dev Mode: {OsUtils.GetDeveloperModeState()})", true); if (!symlinksAllowed && Config.Get(Config.Key.askedForDevModeVersion) != ver) {