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:
Nathan Windisch 2024-07-16 02:28:43 +01:00 committed by Nathan
parent 10a6babce9
commit 7a11a3512f
3 changed files with 16 additions and 15 deletions

View File

@ -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()!);
} }

View File

@ -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) {

View File

@ -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());
} }
} }