add microsoft SAM tts, make aniv messages play tts

This commit is contained in:
2025-12-05 16:04:12 +01:00
parent fd4afb1530
commit c37d2f0a8b
7 changed files with 113 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import { sendMessage } from "lib/commandUtils";
import { redis } from "lib/redis"; import { redis } from "lib/redis";
import { timeout } from "lib/timeout"; import { timeout } from "lib/timeout";
import type User from "user"; import type User from "user";
import { playTTS } from "web/alerts/serverFunctions";
const ANIVNAMES: anivBots[] = ["a_n_e_e_v", "a_n_i_v"]; const ANIVNAMES: anivBots[] = ["a_n_e_e_v", "a_n_i_v"];
@@ -43,6 +44,7 @@ export default async function handleMessage(
user: User, user: User,
) { ) {
if (ANIVNAMES.map((a) => a.toLowerCase()).includes(user.username)) { if (ANIVNAMES.map((a) => a.toLowerCase()).includes(user.username)) {
await playTTS({ text: msg.messageText });
const data: anivMessageStore = await redis const data: anivMessageStore = await redis
.get("anivmessages") .get("anivmessages")
.then((a) => (a === null ? {} : JSON.parse(a))); .then((a) => (a === null ? {} : JSON.parse(a)));

View File

@@ -0,0 +1,9 @@
export type MSTTS = {
type: "microsoft";
text: string;
voice: string;
pitch: string;
speed: string;
};
export type TTS = MSTTS;

View File

@@ -11,3 +11,29 @@ export async function playAlert(alert: alert) {
alert, alert,
}); });
} }
type TTSOptions = {
text: string;
voice?: string;
pitch?: number;
speed?: number;
};
export async function playTTS(options: TTSOptions) {
await sendAlertEvent({
function: "playTTS",
tts: {
type: "microsoft",
voice: options.voice ?? "Sam",
pitch: options.pitch ? options.pitch.toString() : "100",
speed: options.speed ? options.speed.toString() : "150",
text: options.text,
},
});
}
export async function stopTTS() {
await sendAlertEvent({
function: "cancelTTS",
});
}

View File

@@ -1,4 +1,5 @@
import type { serverNotificationEvent } from "web/serverTypes"; import type { serverNotificationEvent } from "web/serverTypes";
import type { TTS } from "./TTSTypes";
type alertBase<name extends string> = { type alertBase<name extends string> = {
name: name; name: name;
@@ -51,4 +52,17 @@ type playAlertEvent = {
alert: alert; alert: alert;
}; };
export type alertEventData = playAlertEvent | serverNotificationEvent; type playTTS = {
function: "playTTS";
tts: TTS;
};
type cancelTTS = {
function: "cancelTTS";
};
export type alertEventData =
| playAlertEvent
| playTTS
| cancelTTS
| serverNotificationEvent;

View File

@@ -0,0 +1,52 @@
import type { TTS } from "web/alerts/TTSTypes";
class TTSManager {
private busy: boolean;
private ttsQueue: TTS[];
private audio: HTMLAudioElement;
constructor() {
this.busy = false;
this.ttsQueue = [];
this.audio = new Audio();
document.body.appendChild(this.audio);
}
private async playAudio(url: string) {
return new Promise((res) => {
this.audio.src = url;
this.audio.load();
this.audio.play();
this.audio.onended = res;
this.audio.onpause = res;
});
}
private async playTTS(tts: TTS) {
this.busy = true;
switch (tts.type) {
case "microsoft":
await this.playAudio(
`https://tetyys.com/SAPI4/SAPI4?text=${tts.text}&voice=${tts.voice}&pitch=${tts.pitch}&speed=${tts.speed}`,
);
break;
}
const newTTS = this.ttsQueue.shift();
if (!newTTS) {
this.busy = false;
return;
} else this.playTTS(newTTS);
}
public queueTTS(input: TTS) {
if (this.busy) this.ttsQueue.push(input);
else this.playTTS(input);
}
public endTTS() {
this.audio.pause();
}
}
export default new TTSManager();

View File

@@ -1,7 +1,8 @@
import type { alertEventData } from "web/alerts/types"; import type { alertEventData } from "web/alerts/types";
import type { serverInstruction } from "web/serverTypes"; import type { serverInstruction } from "web/serverTypes";
import alertManager from "./alertManager"; import AlertManager from "./AlertManager";
import "@fontsource/jersey-15"; import "@fontsource/jersey-15";
import TTSManager from "./TTSManager";
const wsAddress = `ws${location.protocol === "https:" ? "s" : ""}://${location.host}`; const wsAddress = `ws${location.protocol === "https:" ? "s" : ""}://${location.host}`;
@@ -19,7 +20,13 @@ socket.onmessage = (event) => {
const data: alertEventData = JSON.parse(event.data); const data: alertEventData = JSON.parse(event.data);
switch (data.function) { switch (data.function) {
case "playAlert": case "playAlert":
alertManager.queueAlert(data.alert); AlertManager.queueAlert(data.alert);
break;
case "playTTS":
TTSManager.queueTTS(data.tts);
break;
case "cancelTTS":
TTSManager.endTTS();
break; break;
case "serverNotification": case "serverNotification":
console.log(data.message); console.log(data.message);