mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-25 12:49:26 +01:00
Console logging improvements, implement Equals/GetHashCode for QueryInfo
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<bool> 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<string> GetAudioCodecs(string path, int streamIndex = -1)
|
||||
|
||||
@@ -19,19 +19,15 @@ namespace Flowframes.Media
|
||||
|
||||
public static async Task<int> 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<QueryInfo, int> 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<QueryInfo, int> 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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Flowframes.Media
|
||||
public static async Task<string> 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<QueryInfo, string> cacheDict)
|
||||
{
|
||||
foreach (KeyValuePair<QueryInfo, string> 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<QueryInfo, string> cacheDict)
|
||||
{
|
||||
foreach (KeyValuePair<QueryInfo, string> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<Process> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user