mirror of
https://github.com/unclshura/splitter.git
synced 2026-06-22 00:22:01 +00:00
Better console UI
This commit is contained in:
parent
a6b9d9c069
commit
ccfa3936c7
106
Logger.cs
106
Logger.cs
@ -17,9 +17,16 @@ public static class Logger
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Console.SetCursorPosition(0, _logLines);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||||
|
Console.Write($"{prefix} ");
|
||||||
|
|
||||||
Console.ForegroundColor = color;
|
Console.ForegroundColor = color;
|
||||||
Console.WriteLine($"{prefix} {msg}");
|
Console.WriteLine(msg);
|
||||||
|
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
|
|
||||||
_logLines++;
|
_logLines++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,39 +37,88 @@ public static class Logger
|
|||||||
public static void LogWarn(string msg) => Log("[WARN]", ConsoleColor.Yellow, msg);
|
public static void LogWarn(string msg) => Log("[WARN]", ConsoleColor.Yellow, msg);
|
||||||
public static void LogError(string msg) => Log("[ERR ]", ConsoleColor.Red, msg);
|
public static void LogError(string msg) => Log("[ERR ]", ConsoleColor.Red, msg);
|
||||||
|
|
||||||
public static void DrawProgress(int progressLevel, double progress, TimeSpan eta, double speed)
|
private static readonly Dictionary<int, int> _progressTrack = new();
|
||||||
|
|
||||||
|
public static void DrawProgress(string name, int progressLevel, double progress, TimeSpan eta, double speed)
|
||||||
|
{
|
||||||
|
if (PlainText || progressLevel < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Crop name to max 20 chars
|
||||||
|
name = name.Length > 20 ? name[..20] : name;
|
||||||
|
|
||||||
|
lock (_consoleLock)
|
||||||
|
{
|
||||||
|
var width = Math.Max(20, Console.WindowWidth - 20);
|
||||||
|
|
||||||
|
// Reserve space for name + space
|
||||||
|
var namePrefix = name + " ";
|
||||||
|
var barWidth = Math.Max(10, width - namePrefix.Length);
|
||||||
|
|
||||||
|
var filled = (int)(progress * barWidth);
|
||||||
|
if (filled < 0) filled = 0;
|
||||||
|
if (filled > barWidth) filled = barWidth;
|
||||||
|
|
||||||
|
// --- NEW: skip drawing if visually unchanged ---
|
||||||
|
if (_progressTrack.TryGetValue(progressLevel, out var lastFilled) &&
|
||||||
|
lastFilled == filled)
|
||||||
|
{
|
||||||
|
return; // no visual change → skip
|
||||||
|
}
|
||||||
|
|
||||||
|
_progressTrack[progressLevel] = filled;
|
||||||
|
// ------------------------------------------------
|
||||||
|
|
||||||
|
var barLine = _logLines + 1 + progressLevel * 2;
|
||||||
|
var infoLine = _logLines + 2 + progressLevel * 2;
|
||||||
|
|
||||||
|
// Draw progress bar
|
||||||
|
Console.SetCursorPosition(0, barLine);
|
||||||
|
Console.Write("\u001b[38;2;0;255;0m"); // green
|
||||||
|
Console.Write(namePrefix);
|
||||||
|
Console.Write("[");
|
||||||
|
Console.Write(new string('#', filled));
|
||||||
|
Console.Write(new string('-', barWidth - filled));
|
||||||
|
Console.Write("]\u001b[0m");
|
||||||
|
|
||||||
|
// Info line
|
||||||
|
Console.SetCursorPosition(0, infoLine);
|
||||||
|
|
||||||
|
var etaStr = eta.TotalSeconds < 0 || double.IsInfinity(eta.TotalSeconds)
|
||||||
|
? "ETA: --:--"
|
||||||
|
: $"ETA: {eta:mm\\:ss}";
|
||||||
|
|
||||||
|
var speedStr = double.IsNaN(speed) || double.IsInfinity(speed)
|
||||||
|
? "Speed: -.-x"
|
||||||
|
: $"Speed: {speed:F2}x";
|
||||||
|
|
||||||
|
var info = $"{progress * 100:0.0}% {etaStr} {speedStr} ";
|
||||||
|
|
||||||
|
Console.Write("\u001b[38;2;180;180;180m" +
|
||||||
|
info.PadRight(Console.WindowWidth - 1) +
|
||||||
|
"\u001b[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ClearProgress(int progressLevel)
|
||||||
{
|
{
|
||||||
if (PlainText || progressLevel < 0)
|
if (PlainText || progressLevel < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (_consoleLock)
|
lock (_consoleLock)
|
||||||
{
|
{
|
||||||
var width = Math.Max(20, Console.WindowWidth - 20);
|
var barLine = _logLines + 1 + progressLevel * 2;
|
||||||
var filled = (int)(progress * width);
|
var infoLine = _logLines + 2 + progressLevel * 2;
|
||||||
if (filled < 0) filled = 0;
|
|
||||||
if (filled > width) filled = width;
|
|
||||||
|
|
||||||
var barLine = _logLines + 1 + progressLevel*2;
|
// Clear bar line
|
||||||
var infoLine = _logLines + 2 + progressLevel*2;
|
|
||||||
|
|
||||||
// Progress bar with 24-bit color (green)
|
|
||||||
Console.SetCursorPosition(0, barLine);
|
Console.SetCursorPosition(0, barLine);
|
||||||
Console.Write("\u001b[38;2;0;255;0m[");
|
Console.Write(new string(' ', Console.WindowWidth - 1));
|
||||||
Console.Write(new string('#', filled));
|
|
||||||
Console.Write(new string('-', width - filled));
|
|
||||||
Console.Write("]\u001b[0m");
|
|
||||||
|
|
||||||
// Info line: percentage, ETA, speed
|
// Clear info line
|
||||||
Console.SetCursorPosition(0, infoLine);
|
Console.SetCursorPosition(0, infoLine);
|
||||||
var etaStr = eta.TotalSeconds < 0 || double.IsInfinity(eta.TotalSeconds)
|
Console.Write(new string(' ', Console.WindowWidth - 1));
|
||||||
? "ETA: --:--"
|
}
|
||||||
: $"ETA: {eta:mm\\:ss}";
|
}
|
||||||
var speedStr = double.IsNaN(speed) || double.IsInfinity(speed)
|
|
||||||
? "Speed: -.-x"
|
|
||||||
: $"Speed: {speed:F2}x";
|
|
||||||
|
|
||||||
var info = $"{progress * 100:0.0}% {etaStr} {speedStr} ";
|
|
||||||
Console.Write("\u001b[38;2;180;180;180m" + info.PadRight(Console.WindowWidth - 1) + "\u001b[0m");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,9 @@ public abstract class LoggingBase(int progressLine)
|
|||||||
protected void LogError(string message)
|
protected void LogError(string message)
|
||||||
=> Logger.LogError(message);
|
=> Logger.LogError(message);
|
||||||
|
|
||||||
protected void DrawProgress(double percent, TimeSpan eta, double fps)
|
protected void DrawProgress(string name, double percent, TimeSpan eta, double fps)
|
||||||
=> Logger.DrawProgress(progressLine, percent, eta, fps);
|
=> Logger.DrawProgress(name, progressLine, percent, eta, fps);
|
||||||
|
|
||||||
|
protected void ClearProgress(int progressLevel)
|
||||||
|
=> Logger.ClearProgress(progressLevel);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using FFmpeg.AutoGen;
|
||||||
|
|
||||||
namespace splitter;
|
namespace splitter;
|
||||||
|
|
||||||
@ -39,12 +40,20 @@ public class SimpleSplitter(int segmentNo) : LoggingBase(segmentNo), ISegmentPro
|
|||||||
|
|
||||||
using var proc = Process.Start(psi) ?? throw new Exception("Failed to start ffmpeg.");
|
using var proc = Process.Start(psi) ?? throw new Exception("Failed to start ffmpeg.");
|
||||||
|
|
||||||
ShowFFMpegProgress(length, proc);
|
var name = Path.GetFileNameWithoutExtension(outputFile);
|
||||||
|
ShowFFMpegProgress(length, proc, name);
|
||||||
|
|
||||||
proc.WaitForExit();
|
proc.WaitForExit();
|
||||||
|
|
||||||
|
ClearProgress(segmentNo);
|
||||||
|
|
||||||
|
if (proc.ExitCode != 0)
|
||||||
|
LogError($"Segment {name} FFmpeg encoding failed");
|
||||||
|
else
|
||||||
|
LogInfo($"Segment {name} processing completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowFFMpegProgress(double length, Process proc)
|
private void ShowFFMpegProgress(double length, Process proc, string name)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
@ -76,7 +85,7 @@ public class SimpleSplitter(int segmentNo) : LoggingBase(segmentNo), ISegmentPro
|
|||||||
var etaSeconds = speed > 0 ? remaining / speed : remaining;
|
var etaSeconds = speed > 0 ? remaining / speed : remaining;
|
||||||
var eta = TimeSpan.FromSeconds(etaSeconds);
|
var eta = TimeSpan.FromSeconds(etaSeconds);
|
||||||
|
|
||||||
DrawProgress(progress, eta, speed);
|
DrawProgress(name, progress, eta, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@ public class TrackingSplitter : LoggingBase, ISegmentProcessor, IDisposable
|
|||||||
if (!capture.IsOpened())
|
if (!capture.IsOpened())
|
||||||
throw new Exception("Cannot open video");
|
throw new Exception("Cannot open video");
|
||||||
|
|
||||||
|
var name = Path.GetFileNameWithoutExtension(outputFile);
|
||||||
var skip = TimeSpan.FromSeconds(start);
|
var skip = TimeSpan.FromSeconds(start);
|
||||||
var duration = TimeSpan.FromSeconds(length);
|
var duration = TimeSpan.FromSeconds(length);
|
||||||
|
|
||||||
@ -158,17 +159,20 @@ public class TrackingSplitter : LoggingBase, ISegmentProcessor, IDisposable
|
|||||||
var etaSeconds = speed > 0 ? remainingFrames / speed : 0;
|
var etaSeconds = speed > 0 ? remainingFrames / speed : 0;
|
||||||
var eta = TimeSpan.FromSeconds(etaSeconds);
|
var eta = TimeSpan.FromSeconds(etaSeconds);
|
||||||
|
|
||||||
DrawProgress(progress, eta, speed);
|
DrawProgress(name, progress, eta, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
stdin.Flush();
|
stdin.Flush();
|
||||||
stdin.Close();
|
stdin.Close();
|
||||||
|
|
||||||
await ffmpeg.WaitForExitAsync();
|
await ffmpeg.WaitForExitAsync();
|
||||||
|
|
||||||
|
ClearProgress(_segmentNo);
|
||||||
|
|
||||||
if (ffmpeg.ExitCode != 0)
|
if (ffmpeg.ExitCode != 0)
|
||||||
LogError($"Segment {_segmentNo} FFmpeg encoding failed");
|
LogError($"Segment {name} FFmpeg encoding failed");
|
||||||
else
|
else
|
||||||
LogInfo($"Segment {_segmentNo} processing completed");
|
LogInfo($"Segment {name} processing completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Rect box, Point2f center)? SelectTrackedObject(
|
private (Rect box, Point2f center)? SelectTrackedObject(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user