diff --git a/CompressionTask.cs b/CompressionTask.cs index 7071cdb..3465c28 100644 --- a/CompressionTask.cs +++ b/CompressionTask.cs @@ -3,7 +3,7 @@ namespace LiteCut { - internal class CompressionTask + internal class CompressionTask(string inputFilePath, string outputFilePath, int targetFileSizeMB, TimeSpan startTime, TimeSpan endTime, bool mergeAudio) { public EventHandler? CompressionProgress; @@ -11,22 +11,6 @@ internal class CompressionTask public EventHandler? CompressionOutput; - private readonly string inputFilePath; - private readonly string outputFilePath; - private readonly int targetFileSizeMB; - private readonly TimeSpan startTime; - private readonly TimeSpan endTime; - private readonly bool mergeAudio; - - public CompressionTask(string inputFilePath, string outputFilePath, int targetFileSizeMB, TimeSpan startTime, TimeSpan endTime, bool mergeAudio) - { - this.inputFilePath = inputFilePath; - this.outputFilePath = outputFilePath; - this.targetFileSizeMB = targetFileSizeMB; - this.startTime = startTime; - this.endTime = endTime; - this.mergeAudio = mergeAudio; - } public async Task CompressVideo() { double targetFileSizeBytes = targetFileSizeMB * 1024; diff --git a/FFmpegInstaller.cs b/FFmpegInstaller.cs new file mode 100644 index 0000000..57369b0 --- /dev/null +++ b/FFmpegInstaller.cs @@ -0,0 +1,161 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32; + +namespace LiteCut +{ + public static class FFmpegInstaller + { + public static bool InstallFFmpeg() + { + try + { + + ProcessStartInfo startInfo = new() + { + FileName = "winget", + Arguments = "install Gyan.FFmpeg -h", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + using Process process = new(); + process.StartInfo = startInfo; + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + + // Refresh this process' PATH from the registry so newly-installed executables are found without restarting + RefreshProcessPathFromRegistry(); + + // Quick verification: try running `ffmpeg -version` + if (CanRunFFmpeg()) + { + return true; + } + + var ffmpegInstallationDirectory = FindFFmpeg(); + + if (!string.IsNullOrEmpty(ffmpegInstallationDirectory)) + { + string dir = Path.GetDirectoryName(ffmpegInstallationDirectory); + string current = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) ?? string.Empty; + Environment.SetEnvironmentVariable("PATH", dir + ";" + current, EnvironmentVariableTarget.Process); + + if (!CanRunFFmpeg()) + { + MessageBox.Show("FFmpeg was not directly accessbile. You may need to restart LiteCut or your computer."); + return true; // installation likely succeeded, but process PATH wasn't picked up by all mechanisms + } + } + else + { + MessageBox.Show("FFmpeg was installed but could not be located. Try restarting Litecut or your computer."); + return true; + } + } + catch (Exception ex) + { + MessageBox.Show($"Error: {ex.Message}"); + return false; + } + + return false; + } + + private static void RefreshProcessPathFromRegistry() + { + try + { + const string systemEnvKey = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; + string systemPath = Registry.LocalMachine.OpenSubKey(systemEnvKey)?.GetValue("Path") as string ?? string.Empty; + string userPath = Registry.CurrentUser.OpenSubKey("Environment")?.GetValue("Path") as string ?? string.Empty; + + string merged; + if (string.IsNullOrEmpty(systemPath)) merged = userPath; + else if (string.IsNullOrEmpty(userPath)) merged = systemPath; + else merged = systemPath + ";" + userPath; + + if (!string.IsNullOrEmpty(merged)) + { + Environment.SetEnvironmentVariable("PATH", merged, EnvironmentVariableTarget.Process); + } + } + catch + { + // Non-fatal — leave process PATH unchanged if registry read fails. + } + } + + private static bool CanRunFFmpeg() + { + try + { + ProcessStartInfo psi = new() + { + FileName = "ffmpeg", + Arguments = "-version", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + using Process p = Process.Start(psi); + if (p is null) + { + return false; + } + p.WaitForExit(3000); + return p.ExitCode == 0; + } + catch + { + return false; + } + } + + + private static string FindFFmpeg() + { + try + { + ProcessStartInfo psi = new() + { + FileName = "where", + Arguments = "ffmpeg", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + using Process p = Process.Start(psi); + if (p == null) return string.Empty; + + string output = p.StandardOutput.ReadToEnd(); + p.WaitForExit(2000); + + if (string.IsNullOrWhiteSpace(output)) return string.Empty; + + var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var line in lines) + { + var path = line.Trim(); + if (File.Exists(path)) return path; + } + } + catch + { + } + + return string.Empty; + } + } +} diff --git a/FileAssociation.cs b/FileAssociation.cs index 7837c18..383ecda 100644 --- a/FileAssociation.cs +++ b/FileAssociation.cs @@ -11,10 +11,8 @@ public static void AssociateFile() var applicationInfo = new ApplicationInfo("LiteCut", "LiteCut", "LiteCut", Application.ExecutablePath); applicationInfo.SupportedExtensions.Add(".mp4"); - IApplicationRegistrationService registrationService = new ApplicationRegistrationService(); - + var registrationService = new ApplicationRegistrationService(); registrationService.RegisterApplication(applicationInfo); - - } + } } } diff --git a/InstallFFmpeg.cs b/InstallFFmpeg.cs deleted file mode 100644 index 417fff4..0000000 --- a/InstallFFmpeg.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LiteCut -{ - public static class InstallFFmpeg - { - public static bool installFFmpeg() - { - try - { - var output = new StringBuilder(); - ProcessStartInfo startInfo = new ProcessStartInfo - { - FileName = "winget", - Arguments = $"install ffmpeg", - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = false - }; - - using (Process process = new Process()) - { - process.StartInfo = startInfo; - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - process.WaitForExit(); - } - } - catch (Exception ex) - { - MessageBox.Show($"Error: {ex.Message}"); - return false; - } - return true; - - } - } - - -} diff --git a/LiteCut.cs b/LiteCut.cs index d3b3c4f..8e5835c 100644 --- a/LiteCut.cs +++ b/LiteCut.cs @@ -12,12 +12,12 @@ public LiteCut(string[] args) { FFMpeg.GetCodecs(); } - catch + catch (Exception e) { - DialogResult result = MessageBox.Show("FFMpeg is not installed, or has no codecs. Do you want to try to install it now?", "error", MessageBoxButtons.YesNo); + DialogResult result = MessageBox.Show($"Error retrieving FFmpeg codecs: \n {e.Message} \n\n This usually happens when FFmpeg is not installed. Do you want to try to install it now?", "error", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { - var installResult = InstallFFmpeg.installFFmpeg(); + var installResult = FFmpegInstaller.InstallFFmpeg(); if (installResult == true) { MessageBox.Show("Successfully installed FFMpeg!"); @@ -88,7 +88,7 @@ private async void CompressButton_Click(object sender, EventArgs e) var endTime = TimeSpan.FromSeconds((double)EndTimeBox.Value); var mergeAudio = MergeAudioTrackCheckBox.Checked; - CompressionTask compression = new CompressionTask(fileName, fileName + "_compressed.mp4", size, startTime, endTime, mergeAudio ); + var compression = new CompressionTask(fileName, fileName + "_compressed.mp4", size, startTime, endTime, mergeAudio ); compression.CompressionProgress += (sender, progress) => { if (ProgressBar.InvokeRequired)