rework
do I advance the complexity clock and make a whole-ass language?
This commit is contained in:
parent
bc9d4f8119
commit
ba86337756
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -9,7 +9,7 @@
|
|||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build",
|
"preLaunchTask": "build",
|
||||||
"program": "${workspaceFolder}/bin/Debug/net8.0/placeholder-VO.dll",
|
"program": "${workspaceFolder}/bin/Debug/net8.0/script-splitter.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
|
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@ -7,7 +7,7 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"${workspaceFolder}/placeholder-VO.csproj",
|
"${workspaceFolder}/script-splitter.csproj",
|
||||||
"/property:GenerateFullPaths=true",
|
"/property:GenerateFullPaths=true",
|
||||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
],
|
],
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"publish",
|
"publish",
|
||||||
"${workspaceFolder}/placeholder-VO.csproj",
|
"${workspaceFolder}/script-splitter.csproj",
|
||||||
"/property:GenerateFullPaths=true",
|
"/property:GenerateFullPaths=true",
|
||||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
],
|
],
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"watch",
|
"watch",
|
||||||
"run",
|
"run",
|
||||||
"--project",
|
"--project",
|
||||||
"${workspaceFolder}/placeholder-VO.csproj"
|
"${workspaceFolder}/script-splitter.csproj"
|
||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
}
|
}
|
||||||
|
330
Program.cs
330
Program.cs
@ -7,6 +7,7 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
using System.Xml.Schema;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
||||||
@ -15,104 +16,103 @@ namespace placeholdervo
|
|||||||
public partial class Program
|
public partial class Program
|
||||||
{
|
{
|
||||||
|
|
||||||
[GeneratedRegex("^[^a-zA-Z0-9'\"]")]
|
[GeneratedRegex("^(\\[|#)")]
|
||||||
private static partial Regex TextLine();
|
private static partial Regex NonTextLine();
|
||||||
public static Config conf;
|
public static Config conf;
|
||||||
private static string workingDir = "./";
|
private static string workingDir = "./";
|
||||||
|
|
||||||
private static ConcurrentQueue<string> scriptFragmentFiles = new ConcurrentQueue<string>();
|
private static ConcurrentQueue<string> scriptFragmentFiles = new ConcurrentQueue<string>();
|
||||||
|
private static ConcurrentQueue<string> titleCardLines = new ConcurrentQueue<string>();
|
||||||
private static CancellationToken scriptFileCancellationToken;
|
private static CancellationToken scriptFileCancellationToken;
|
||||||
|
|
||||||
private static async void webcall()
|
// private static async void webcall()
|
||||||
{
|
// {
|
||||||
var hc = new HttpClient(){ BaseAddress = new Uri(conf.speech_service)};
|
// var hc = new HttpClient(){ BaseAddress = new Uri(conf.speech_service)};
|
||||||
while(true)
|
// while(true)
|
||||||
{
|
// {
|
||||||
while(!scriptFragmentFiles.IsEmpty)
|
// while(!scriptFragmentFiles.IsEmpty)
|
||||||
{
|
// {
|
||||||
string scriptFragment;
|
// string scriptFragment;
|
||||||
scriptFragmentFiles.TryDequeue(out scriptFragment);
|
// scriptFragmentFiles.TryDequeue(out scriptFragment);
|
||||||
if(scriptFragment == null) continue;
|
// if(scriptFragment == null) continue;
|
||||||
Console.WriteLine(scriptFragment);
|
// Console.WriteLine(scriptFragment);
|
||||||
|
|
||||||
HttpContent fileStreamContent = new StreamContent(File.OpenRead(scriptFragment));
|
// HttpContent fileStreamContent = new StreamContent(File.OpenRead(scriptFragment));
|
||||||
using (var formData = new MultipartFormDataContent())
|
// using (var formData = new MultipartFormDataContent())
|
||||||
{
|
// {
|
||||||
formData.Add(fileStreamContent, "file1", "file1");
|
// formData.Add(fileStreamContent, "file1", "file1");
|
||||||
|
|
||||||
var response = await hc.PostAsync("/speak", formData);
|
// var response = await hc.PostAsync("/speak", formData);
|
||||||
if (!response.IsSuccessStatusCode)
|
// if (!response.IsSuccessStatusCode)
|
||||||
{
|
// {
|
||||||
Console.Error.WriteLine($"{response.StatusCode} - {response.ReasonPhrase} - {await response.Content.ReadAsStringAsync()}");
|
// Console.Error.WriteLine($"{response.StatusCode} - {response.ReasonPhrase} - {await response.Content.ReadAsStringAsync()}");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
var resp = string.Join(", ", JsonConvert.DeserializeObject<string[]>(await response.Content.ReadAsStringAsync()));
|
// var resp = string.Join(", ", JsonConvert.DeserializeObject<string[]>(await response.Content.ReadAsStringAsync()));
|
||||||
Console.WriteLine($"success; {resp}.");
|
// Console.WriteLine($"success; {resp}.");
|
||||||
if(resp != null)
|
// if(resp != null)
|
||||||
{
|
// {
|
||||||
scriptFragmentVoiceFiles[resp] = scriptFragment;
|
// scriptFragmentVoiceFiles[resp] = scriptFragment;
|
||||||
Console.WriteLine("Ditching script fragment file.");
|
// Console.WriteLine("Ditching script fragment file.");
|
||||||
File.Delete(scriptFragment);
|
// File.Delete(scriptFragment);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
|
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||||
}
|
// }
|
||||||
|
|
||||||
if(scriptFileCancellationToken.IsCancellationRequested && scriptFragmentFiles.IsEmpty)
|
// if(scriptFileCancellationToken.IsCancellationRequested && scriptFragmentFiles.IsEmpty)
|
||||||
{
|
// {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private static ConcurrentDictionary<string, string> scriptFragmentVoiceFiles = new ConcurrentDictionary<string, string>();
|
// private static async void filePickup()
|
||||||
|
// {
|
||||||
private static async void filePickup()
|
// while(true)
|
||||||
{
|
// {
|
||||||
while(true)
|
// while(!scriptFragmentVoiceFiles.IsEmpty)
|
||||||
{
|
// {
|
||||||
while(!scriptFragmentVoiceFiles.IsEmpty)
|
// var files = Directory.GetFiles(conf.sync_dropoff);
|
||||||
{
|
// Console.WriteLine($"files listed: {string.Join(", ", files)}");
|
||||||
var files = Directory.GetFiles(conf.sync_dropoff);
|
// Console.WriteLine($"hoping for: {string.Join(", ", scriptFragmentVoiceFiles.Keys)}");
|
||||||
Console.WriteLine($"files listed: {string.Join(", ", files)}");
|
// // Console.WriteLine($"sanity check: first listed file: {Path.GetFileName(files.FirstOrDefault())}");
|
||||||
Console.WriteLine($"hoping for: {string.Join(", ", scriptFragmentVoiceFiles.Keys)}");
|
// // Console.WriteLine($"sanity check: first key: {scriptFragmentVoiceFiles.Keys.FirstOrDefault()}");
|
||||||
// Console.WriteLine($"sanity check: first listed file: {Path.GetFileName(files.FirstOrDefault())}");
|
// // Console.WriteLine($"sanity check: first value: {scriptFragmentVoiceFiles[scriptFragmentVoiceFiles.Keys.FirstOrDefault()]}");
|
||||||
// Console.WriteLine($"sanity check: first key: {scriptFragmentVoiceFiles.Keys.FirstOrDefault()}");
|
// var audioFile = files.FirstOrDefault(f => scriptFragmentVoiceFiles.ContainsKey(Path.GetFileName(f)));
|
||||||
// Console.WriteLine($"sanity check: first value: {scriptFragmentVoiceFiles[scriptFragmentVoiceFiles.Keys.FirstOrDefault()]}");
|
// if(!string.IsNullOrWhiteSpace(audioFile))
|
||||||
var audioFile = files.FirstOrDefault(f => scriptFragmentVoiceFiles.ContainsKey(Path.GetFileName(f)));
|
// {
|
||||||
if(!string.IsNullOrWhiteSpace(audioFile))
|
// Console.WriteLine($"found {audioFile}");
|
||||||
{
|
// try
|
||||||
Console.WriteLine($"found {audioFile}");
|
// {
|
||||||
try
|
// var bareAudioFile = Path.GetFileName(audioFile);
|
||||||
{
|
// var destFile = scriptFragmentVoiceFiles[bareAudioFile];
|
||||||
var bareAudioFile = Path.GetFileName(audioFile);
|
// destFile = Path.GetFileNameWithoutExtension(destFile) + ".wav";
|
||||||
var destFile = scriptFragmentVoiceFiles[bareAudioFile];
|
// destFile = Path.Combine(workingDir, destFile);
|
||||||
destFile = Path.GetFileNameWithoutExtension(destFile) + ".wav";
|
// File.Move(audioFile, destFile);
|
||||||
destFile = Path.Combine(workingDir, destFile);
|
|
||||||
File.Move(audioFile, destFile);
|
|
||||||
|
|
||||||
if(!scriptFragmentVoiceFiles.Remove(bareAudioFile, out string throwaway))
|
// if(!scriptFragmentVoiceFiles.Remove(bareAudioFile, out string throwaway))
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"failed to remove {bareAudioFile}");
|
// Console.WriteLine($"failed to remove {bareAudioFile}");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
catch(Exception e)
|
// catch(Exception e)
|
||||||
{
|
// {
|
||||||
Console.Error.WriteLine(e.Message);
|
// Console.Error.WriteLine(e.Message);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
|
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
|
||||||
}
|
// }
|
||||||
if(scriptFileCancellationToken.IsCancellationRequested)
|
// if(scriptFileCancellationToken.IsCancellationRequested)
|
||||||
{
|
// {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
|
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static async Task Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
@ -123,63 +123,145 @@ namespace placeholdervo
|
|||||||
|
|
||||||
var scriptPath = args?.FirstOrDefault();
|
var scriptPath = args?.FirstOrDefault();
|
||||||
if(string.IsNullOrWhiteSpace(scriptPath))
|
if(string.IsNullOrWhiteSpace(scriptPath))
|
||||||
scriptPath = "./script.txt";
|
{
|
||||||
|
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);
|
workingDir = Path.GetDirectoryName(scriptPath);
|
||||||
|
|
||||||
var cancelSource = new CancellationTokenSource();
|
var cancelSource = new CancellationTokenSource();
|
||||||
scriptFileCancellationToken = cancelSource.Token;
|
scriptFileCancellationToken = cancelSource.Token;
|
||||||
var apiCallThread = new Thread(new ThreadStart(webcall));
|
// var apiCallThread = new Thread(new ThreadStart(webcall));
|
||||||
apiCallThread.Start();
|
// apiCallThread.Start();
|
||||||
var fileRetrieveThread = new Thread(new ThreadStart(filePickup));
|
// var fileRetrieveThread = new Thread(new ThreadStart(filePickup));
|
||||||
fileRetrieveThread.Start();
|
// fileRetrieveThread.Start();
|
||||||
|
|
||||||
var lines = File.ReadAllLines(scriptPath).Where(l => !TextLine().IsMatch(l))
|
var lines = File.ReadAllLines(scriptPath)
|
||||||
.Append("\n").Append("\n"); //pad out file so my tactic for separating doesn't fall off the end of the file
|
.Append("\n").Append("\n");
|
||||||
var lineCountMagnitude = (int)Math.Log10(lines.Count());
|
var primaryVOLines = new List<string>();
|
||||||
|
var titlecardLines = new List<string>();
|
||||||
var runningSavedLines = new List<string>();
|
var directiveLines = new List<string>();
|
||||||
var completeSavedLines = new List<string>();
|
|
||||||
var iteration = 0;
|
|
||||||
|
|
||||||
foreach(var l in lines)
|
foreach(var l in lines)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(l))
|
if(l.StartsWith('#'))
|
||||||
{
|
{
|
||||||
if(runningSavedLines.Any(line => !string.IsNullOrWhiteSpace(line)))
|
titlecardLines.Add(l);
|
||||||
{
|
}
|
||||||
++iteration;
|
else if (l.StartsWith('['))
|
||||||
//x.ToString("D2") should format x with minimum 2 digits, padded left
|
{
|
||||||
var scriptFragment = $"script{iteration.ToString($"D{lineCountMagnitude}")}.txt";
|
directiveLines.Add(l);
|
||||||
File.WriteAllLines(scriptFragment, runningSavedLines);
|
|
||||||
scriptFragmentFiles.Enqueue(scriptFragment);
|
|
||||||
completeSavedLines.AddRange(runningSavedLines);
|
|
||||||
}
|
|
||||||
runningSavedLines = [];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runningSavedLines.Add(l);
|
//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 = $"script{0.ToString($"D{lineCountMagnitude}")}.txt";
|
var scriptStripped = $"{scriptBasename}-primaryVO.txt";
|
||||||
File.WriteAllLines(scriptStripped, completeSavedLines);
|
File.WriteAllLines(scriptStripped, primaryVOLines);
|
||||||
scriptFragmentFiles.Enqueue(scriptStripped);
|
var titleLevels = new List<int>(){0};
|
||||||
cancelSource.Cancel();
|
var titleIncrementDepth = 0;
|
||||||
Console.WriteLine("http client \"cancelled\".");
|
foreach(var l in titlecardLines)
|
||||||
while(apiCallThread.ThreadState != System.Threading.ThreadState.Stopped)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("thread still running. waiting.");
|
titleIncrementDepth = 1;
|
||||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Console.WriteLine($"api call thread done ({apiCallThread.ThreadState}).");
|
|
||||||
|
|
||||||
while(fileRetrieveThread.ThreadState != System.Threading.ThreadState.Stopped)
|
foreach(var l in directiveLines)
|
||||||
{
|
{
|
||||||
Console.WriteLine("fileRetrieveThread still running. waiting.");
|
var thisLine = l.Trim();
|
||||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Console.WriteLine($"fileRetrieveThread done ({fileRetrieveThread.ThreadState}). kbai");
|
|
||||||
|
// 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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,16 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RootNamespace>placeholder_VO</RootNamespace>
|
<RootNamespace>script-splitter</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<None Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user