Updated the file storage method to use the AI voice name and a hash of the message, to save on compute cycles
Signed-off-by: Nathan <nat@natfan.io>
This commit is contained in:
parent
10a6babce9
commit
7a11a3512f
@ -1,16 +1,20 @@
|
|||||||
using EmojiCSharp;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using EmojiCSharp;
|
||||||
using TwitchLib.Client.Models;
|
using TwitchLib.Client.Models;
|
||||||
|
|
||||||
namespace TTSMe;
|
namespace TTSMe;
|
||||||
|
|
||||||
public static class ExtensionMethods {
|
public static class ExtensionMethods {
|
||||||
|
private static byte[] ToBytes(this string str) => Encoding.UTF8.GetBytes(str);
|
||||||
|
private static string ToHexString(this byte[] bytes) => Convert.ToHexString(bytes);
|
||||||
|
private static string ToSHA256HashedString(this string str) => SHA256.HashData(str.ToBytes()).ToHexString();
|
||||||
|
|
||||||
internal static string? GetStoredVoice(this ChatMessage chatMessage) => Voices.Instance().GetVoice(chatMessage.Username);
|
internal static string? GetStoredVoice(this ChatMessage chatMessage) => Voices.Instance().GetVoice(chatMessage.Username);
|
||||||
internal static bool HasStoredVoice(this ChatMessage chatMessage) => Voices.Instance().HasVoice(chatMessage.Username);
|
internal static bool HasStoredVoice(this ChatMessage chatMessage) => Voices.Instance().HasVoice(chatMessage.Username);
|
||||||
// parse out all emojis into their full names
|
internal static string GetMessageText(this ChatMessage chatMessage) => EmojiParser.ParseToAliases(chatMessage.Message).Replace(":", " colon ").Replace("_", " underscore ");
|
||||||
internal static string GetMessageText(this ChatMessage chatMessage) =>
|
private static string GetMessageHash(this ChatMessage chatMessage) => chatMessage.GetMessageText().ToSHA256HashedString();
|
||||||
EmojiParser.ParseToAliases(chatMessage.Message)
|
internal static string GetAudioFilePath(this ChatMessage chatMessage) => Path.Combine(TTSClient.AudioBasePath, $"{chatMessage.GetStoredVoice()!}-{chatMessage.GetMessageHash()}.mp3");
|
||||||
.Replace(":", " colon ")
|
|
||||||
.Replace("_", " underscore ");
|
|
||||||
|
|
||||||
internal static TextToSpeechRequest ToTTSRequest(this ChatMessage chatMessage) => new(chatMessage.GetMessageText(), chatMessage.GetStoredVoice()!);
|
internal static TextToSpeechRequest ToTTSRequest(this ChatMessage chatMessage) => new(chatMessage.GetMessageText(), chatMessage.GetStoredVoice()!);
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using LibVLCSharp.Shared;
|
using LibVLCSharp.Shared;
|
||||||
using TwitchLib.Client.Models;
|
using TwitchLib.Client.Models;
|
||||||
@ -14,14 +13,12 @@ public static class TTSClient {
|
|||||||
},
|
},
|
||||||
BaseAddress = new Uri("https://api.openai.com")
|
BaseAddress = new Uri("https://api.openai.com")
|
||||||
};
|
};
|
||||||
private const string basePath = "C:/data/twitch/tts";
|
public const string AudioBasePath = @"C:\data\twitch\tts";
|
||||||
|
|
||||||
public static async Task<string> GenerateSpeech(ChatMessage chatMessage) {
|
public static async Task GenerateSpeech(ChatMessage chatMessage) {
|
||||||
|
Console.WriteLine($"Generating speech as {chatMessage.GetAudioFilePath()} for {chatMessage.Username}: {chatMessage.Message}");
|
||||||
HttpResponseMessage response = await httpClient.PostAsJsonAsync("v1/audio/speech", chatMessage.ToTTSRequest());
|
HttpResponseMessage response = await httpClient.PostAsJsonAsync("v1/audio/speech", chatMessage.ToTTSRequest());
|
||||||
byte[] bytes = await response.Content.ReadAsByteArrayAsync();
|
await File.WriteAllBytesAsync(chatMessage.GetAudioFilePath(), await response.Content.ReadAsByteArrayAsync());
|
||||||
string outputPath = Path.Combine(basePath, $"{Guid.NewGuid()}.mp3");
|
|
||||||
await File.WriteAllBytesAsync(outputPath, bytes);
|
|
||||||
return outputPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task PlaySpeech(string path) {
|
public static async Task PlaySpeech(string path) {
|
||||||
|
@ -21,7 +21,7 @@ public class Voices {
|
|||||||
public static async Task ProcessVoiceMessage(ChatMessage chatMessage) {
|
public static async Task ProcessVoiceMessage(ChatMessage chatMessage) {
|
||||||
string? voice = chatMessage.GetStoredVoice();
|
string? voice = chatMessage.GetStoredVoice();
|
||||||
if (voice is null) return;
|
if (voice is null) return;
|
||||||
string filePath = await TTSClient.GenerateSpeech(chatMessage);
|
if (!File.Exists(chatMessage.GetAudioFilePath())) await TTSClient.GenerateSpeech(chatMessage);
|
||||||
await TTSClient.PlaySpeech(filePath);
|
await TTSClient.PlaySpeech(chatMessage.GetAudioFilePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user