-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathProgram.cs
More file actions
112 lines (94 loc) · 5.37 KB
/
Program.cs
File metadata and controls
112 lines (94 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using NAudio.Mixer;
using NAudio.Wave;
using Spectre.Console;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Whisper.net;
using Whisper.net.Ggml;
namespace CurseWordExtractor
{
internal class Program
{
static async Task Main(string[] args)
{
// This is for Spectre to force windows to use Unicode for output
Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.InputEncoding = System.Text.Encoding.UTF8;
Console.Clear();
var bestTitleEver = new FigletText("Potty Mouth Filter") { Color = Color.Yellow , Justification = Justify.Center};
;
AnsiConsole.Write(bestTitleEver);
if (args.Length == 0 || (!File.Exists(args[0]))) // check user argument
{
AnsiConsole.MarkupLineInterpolated($"[bold red]✗ Error:[/] Please enter a valid file path!");
return;
}
string originalFile = args[0];
string profanityFreeAudioPath = string.Empty;
string highQualityAudioFile = string.Empty;
string whisperAudioFile = string.Empty;
try
{
await AnsiConsole.Status().Spinner(Spinner.Known.Circle).StartAsync("Booting up PottyMouth filter :)...", async ctx =>
{
AnsiConsole.MarkupLine("[bold yellow]Loading CurseWords.txt [/]");
ctx.Status("[bold yellow]Loading CurseWords.txt[/]");
// Get Curse Word List
HashSet<string> badWords = Helpers.GetCurseWordList();
AnsiConsole.MarkupLine("\t\t[blue]:small_blue_diamond:[/] CurseWords.txt loaded");
ctx.Status("[bold yellow]Extracting 16kHz audio...[/]");
whisperAudioFile = ExtractAudio.GetAudio16khz(originalFile);
// Run Whisper
ctx.Status("[bold yellow]Detecting profanity via Whisper...[/]");
Queue<ProfanityMatch> rawMatches;
rawMatches = await ProfanityDetector.DetectProfanity(whisperAudioFile, badWords);
// strip duplicates
rawMatches = Helpers.DeduplicateMatches(rawMatches);
ctx.Status("[bold yellow]Correcting timestamps with Vosk...[/]");
// Vosk
Queue<ProfanityMatch> alignedMatches = PreciseAligner.AlignTimeStamps(rawMatches, whisperAudioFile, badWords);
// take the sorted items off the table and pour them straight into a new Queue
Queue<ProfanityMatch> finalSortedMatches = new Queue<ProfanityMatch>(alignedMatches.OrderBy(m => m.Start));
string reportFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Censored_Timestamps.txt");
ctx.Status($"[#DCDCAA]Exporting {finalSortedMatches.Count} timestamps to: {reportFile}[/]");
using (StreamWriter writer = new StreamWriter(reportFile))
{
writer.WriteLine("PROFANITY TIMESTAMP REPORT");
writer.WriteLine($"Date: {DateTime.Now}");
writer.WriteLine($"Total Detections: {finalSortedMatches.Count}");
writer.WriteLine("----------------------------------------------------------------------");
// {0,-16} = Start takes 16 chars, left aligned.
writer.WriteLine("{0,-16} | {1,-16} | {2,-15} | {3}", "START", "END", "WORD", "CONFIDENCE");
writer.WriteLine("----------------------------------------------------------------------");
foreach (var match in finalSortedMatches)
{
writer.WriteLine("{0,-16} | {1,-16} | {2,-15} | {3:P1}",
match.Start.ToString(@"hh\:mm\:ss\.fff"),
match.End.ToString(@"hh\:mm\:ss\.fff"),
match.Word,
match.Confidence);
}
}
ctx.Status("[bold yellow]Extracting high-quality audio...[/]");
highQualityAudioFile = ExtractAudio.GetHighQualityAudio(originalFile);
ctx.Status("[bold yellow]Censoring audio...[/]");
profanityFreeAudioPath = AudioProcessor.CensorAudio(finalSortedMatches, highQualityAudioFile);
});
// Muxing runs OUTSIDE Status so its Progress bar doesn't conflict
Muxer.MuxVideo(originalFile, profanityFreeAudioPath);
AnsiConsole.Write(new Panel(new Markup("[bold #4EC9B0]✔ Profanity filter applied successfully![/]")).Border(BoxBorder.Rounded).BorderColor(Color.Teal).Padding(1, 0, 1, 0));
}
catch (Exception ex) { AnsiConsole.MarkupLineInterpolated($"[#DCDCAA]{Markup.Escape(ex.Message)}[/]"); }
finally
{
Helpers.CleanUp(whisperAudioFile, highQualityAudioFile, profanityFreeAudioPath);
AnsiConsole.MarkupLineInterpolated($"[bold yellow]Potty Mouth Filter finished at [/][underline][white]{DateTime.Now:HH:mm:ss}[/][/]");
}
}
}
}