2024-07-16 01:18:34 +01:00
|
|
|
|
using System.Net.Http.Headers;
|
|
|
|
|
using System.Net.Http.Json;
|
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
|
using LibVLCSharp.Shared;
|
|
|
|
|
using TwitchLib.Client.Models;
|
|
|
|
|
|
|
|
|
|
namespace TTSMe;
|
|
|
|
|
|
|
|
|
|
public static class TTSClient {
|
|
|
|
|
private static readonly HttpClient httpClient = new() {
|
|
|
|
|
DefaultRequestHeaders = {
|
|
|
|
|
Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("OPENAI_API_KEY")),
|
|
|
|
|
},
|
|
|
|
|
BaseAddress = new Uri("https://api.openai.com")
|
|
|
|
|
};
|
2024-07-16 02:28:43 +01:00
|
|
|
|
public const string AudioBasePath = @"C:\data\twitch\tts";
|
2024-07-16 01:18:34 +01:00
|
|
|
|
|
2024-07-16 02:28:43 +01:00
|
|
|
|
public static async Task GenerateSpeech(ChatMessage chatMessage) {
|
|
|
|
|
Console.WriteLine($"Generating speech as {chatMessage.GetAudioFilePath()} for {chatMessage.Username}: {chatMessage.Message}");
|
2024-07-16 01:18:34 +01:00
|
|
|
|
HttpResponseMessage response = await httpClient.PostAsJsonAsync("v1/audio/speech", chatMessage.ToTTSRequest());
|
2024-07-16 02:28:43 +01:00
|
|
|
|
await File.WriteAllBytesAsync(chatMessage.GetAudioFilePath(), await response.Content.ReadAsByteArrayAsync());
|
2024-07-16 01:18:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static async Task PlaySpeech(string path) {
|
|
|
|
|
try {
|
|
|
|
|
await Task.Run(() => {
|
|
|
|
|
TaskCompletionSource<bool> taskCompletionSource = new();
|
|
|
|
|
using LibVLC libVLC = new();
|
|
|
|
|
if (TtsMeCommand.VERBOSE) libVLC.Log += (_, e) => Console.WriteLine($"LibVLC [{e.Level}] {e.Module}:{e.Message}");
|
|
|
|
|
using Media media = new(libVLC, path);
|
|
|
|
|
using MediaPlayer player = new(media);
|
|
|
|
|
|
|
|
|
|
player.EndReached += OnEndReached;
|
|
|
|
|
player.Play();
|
|
|
|
|
player.EndReached += (_, _) => taskCompletionSource.TrySetResult(true);
|
|
|
|
|
taskCompletionSource.Task.Wait();
|
|
|
|
|
player.Stop();
|
|
|
|
|
});
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
Console.WriteLine($"An error occurred during playback: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void OnEndReached(object? sender, EventArgs _) {
|
|
|
|
|
if (sender is MediaPlayer mediaPlayer) mediaPlayer.Stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
internal record TextToSpeechRequest(
|
|
|
|
|
[property: JsonPropertyName("input")] string Input,
|
|
|
|
|
[property: JsonPropertyName("voice")] string Voice,
|
|
|
|
|
[property: JsonPropertyName("model")] string Model = "tts-1",
|
|
|
|
|
[property: JsonPropertyName("response_format")] string ResponseFormat = "mp3",
|
|
|
|
|
[property: JsonPropertyName("speed")] double Speed = 1.0
|
|
|
|
|
);
|