using System.Collections.Concurrent; using System.Data; using System.Diagnostics; using System.Net; using System.Reflection.Metadata.Ecma335; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Timers; using System.Xml.Schema; using Newtonsoft.Json; namespace placeholdervo { public partial class Program { [GeneratedRegex("^(\\[|#)")] private static partial Regex NonTextLine(); public static Config conf; private static string workingDir = "./"; private static ConcurrentQueue scriptFragmentFiles = new ConcurrentQueue(); private static ConcurrentQueue titleCardLines = new ConcurrentQueue(); private static CancellationToken scriptFileCancellationToken; // private static async void webcall() // { // var hc = new HttpClient(){ BaseAddress = new Uri(conf.speech_service)}; // while(true) // { // while(!scriptFragmentFiles.IsEmpty) // { // string scriptFragment; // scriptFragmentFiles.TryDequeue(out scriptFragment); // if(scriptFragment == null) continue; // Console.WriteLine(scriptFragment); // HttpContent fileStreamContent = new StreamContent(File.OpenRead(scriptFragment)); // using (var formData = new MultipartFormDataContent()) // { // formData.Add(fileStreamContent, "file1", "file1"); // var response = await hc.PostAsync("/speak", formData); // if (!response.IsSuccessStatusCode) // { // Console.Error.WriteLine($"{response.StatusCode} - {response.ReasonPhrase} - {await response.Content.ReadAsStringAsync()}"); // } // else // { // var resp = string.Join(", ", JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync())); // Console.WriteLine($"success; {resp}."); // if(resp != null) // { // scriptFragmentVoiceFiles[resp] = scriptFragment; // Console.WriteLine("Ditching script fragment file."); // File.Delete(scriptFragment); // } // } // } // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); // } // if(scriptFileCancellationToken.IsCancellationRequested && scriptFragmentFiles.IsEmpty) // { // return; // } // } // } // private static async void filePickup() // { // while(true) // { // while(!scriptFragmentVoiceFiles.IsEmpty) // { // var files = Directory.GetFiles(conf.sync_dropoff); // Console.WriteLine($"files listed: {string.Join(", ", files)}"); // Console.WriteLine($"hoping for: {string.Join(", ", scriptFragmentVoiceFiles.Keys)}"); // // Console.WriteLine($"sanity check: first listed file: {Path.GetFileName(files.FirstOrDefault())}"); // // Console.WriteLine($"sanity check: first key: {scriptFragmentVoiceFiles.Keys.FirstOrDefault()}"); // // Console.WriteLine($"sanity check: first value: {scriptFragmentVoiceFiles[scriptFragmentVoiceFiles.Keys.FirstOrDefault()]}"); // var audioFile = files.FirstOrDefault(f => scriptFragmentVoiceFiles.ContainsKey(Path.GetFileName(f))); // if(!string.IsNullOrWhiteSpace(audioFile)) // { // Console.WriteLine($"found {audioFile}"); // try // { // var bareAudioFile = Path.GetFileName(audioFile); // var destFile = scriptFragmentVoiceFiles[bareAudioFile]; // destFile = Path.GetFileNameWithoutExtension(destFile) + ".wav"; // destFile = Path.Combine(workingDir, destFile); // File.Move(audioFile, destFile); // if(!scriptFragmentVoiceFiles.Remove(bareAudioFile, out string throwaway)) // { // Console.WriteLine($"failed to remove {bareAudioFile}"); // } // } // catch(Exception e) // { // Console.Error.WriteLine(e.Message); // } // } // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); // } // if(scriptFileCancellationToken.IsCancellationRequested) // { // return; // } // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); // } // } public static async Task Main(string[] args) { conf = JsonConvert.DeserializeObject( File.ReadAllText( AppDomain.CurrentDomain.BaseDirectory + "appsettings.json")) ?? new Config(); var scriptPath = args?.FirstOrDefault(); if(string.IsNullOrWhiteSpace(scriptPath)) { scriptPath = "./script.md"; if(!File.Exists(scriptPath)) { scriptPath = "./script.txt"; if(!File.Exists(scriptPath)) { Console.Error.WriteLine("no script found."); return; } } } var scriptBasename = Path.GetFileNameWithoutExtension(scriptPath); workingDir = Path.GetDirectoryName(scriptPath); var cancelSource = new CancellationTokenSource(); scriptFileCancellationToken = cancelSource.Token; // var apiCallThread = new Thread(new ThreadStart(webcall)); // apiCallThread.Start(); // var fileRetrieveThread = new Thread(new ThreadStart(filePickup)); // fileRetrieveThread.Start(); var lines = File.ReadAllLines(scriptPath) .Append("\n").Append("\n"); var primaryVOLines = new List(); var titlecardLines = new List(); var directiveLines = new List(); foreach(var l in lines) { if(l.StartsWith('#')) { titlecardLines.Add(l); } else if (l.StartsWith('[')) { directiveLines.Add(l); } else { //as opposed to Environment.NewLine, which will be running on linux, and thus \n. ms speech api cooperates more with \r\n. l.ReplaceLineEndings("\r\n"); primaryVOLines.Add(l); } } var scriptStripped = $"{scriptBasename}-primaryVO.txt"; File.WriteAllLines(scriptStripped, primaryVOLines); var titleLevels = new List(){0}; var titleIncrementDepth = 0; foreach(var l in titlecardLines) { titleIncrementDepth = 1; var thisString = l; while(thisString.StartsWith('#')) { thisString = thisString.Substring(1); if(!thisString.StartsWith('#')) { if(titleLevels.Count < titleIncrementDepth) { titleLevels = [.. titleLevels, 0]; } titleLevels[titleIncrementDepth-1]++; if(titleLevels.Count > titleIncrementDepth) { titleLevels.RemoveRange(titleIncrementDepth, titleLevels.Count - titleIncrementDepth); } var TitleCardText = thisString.Trim(); if(titleLevels.Count > 1) { TitleCardText = string.Join('.', titleLevels[1..]) + ": " + TitleCardText; } Console.WriteLine($"title card: {TitleCardText}"); //tc command } else { titleIncrementDepth++; } } } foreach(var l in directiveLines) { var thisLine = l.Trim(); if(!thisLine.Contains(']')) { Console.Error.WriteLine("malformed directive line: "); Console.WriteLine(thisLine); continue; } if (thisLine.EndsWith(']')) { thisLine = thisLine.Trim('[', ']'); if (Uri.TryCreate(thisLine, UriKind.Absolute, out Uri asUri) && (asUri.Scheme == Uri.UriSchemeHttp || asUri.Scheme == Uri.UriSchemeHttps)) { Console.WriteLine($"uri: {asUri}. ship off to yt-dlp or project Ose"); } else { //just a directive, we can't do anything here Console.WriteLine($"mere directive: {thisLine}"); } } else { thisLine = thisLine.TrimStart('['); var directiveName = thisLine[..thisLine.IndexOf(']')]; var parameterText = thisLine[(thisLine.IndexOf(']') + 1) ..].Trim(); if(directiveName == "note") { //note command Console.WriteLine($"on screen note: {parameterText}"); } else { //alt va command Console.WriteLine($"alt VA: {parameterText}"); } } } // cancelSource.Cancel(); // Console.WriteLine("http client \"cancelled\"."); // while(apiCallThread.ThreadState != System.Threading.ThreadState.Stopped) // { // Console.WriteLine("thread still running. waiting."); // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); // } // Console.WriteLine($"api call thread done ({apiCallThread.ThreadState})."); // while(fileRetrieveThread.ThreadState != System.Threading.ThreadState.Stopped) // { // Console.WriteLine("fileRetrieveThread still running. waiting."); // System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); // } // Console.WriteLine($"fileRetrieveThread done ({fileRetrieveThread.ThreadState}). kbai"); } } }