-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnabu-casa-tts.js
156 lines (139 loc) · 5.32 KB
/
nabu-casa-tts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { getCookie } from './utils.js';
export async function requestNabuCasaTTS(chunk, server, bearer, selectedLang, selectedVoice) {
const url = `${server}/api/tts_get_url`;
const headers = {
"Authorization": `Bearer ${bearer}`,
"Content-Type": "application/json"
};
const data = {
"platform": "cloud",
"message": chunk,
"cache": false,
"language": selectedLang,
"options": {
"voice": selectedVoice
}
};
try {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
if (response.ok) {
const jsonResponse = await response.json();
const audioUrl = jsonResponse.url;
const audioResponse = await fetch(audioUrl);
return await audioResponse.blob();
} else {
console.error(`Error: ${response.status}, ${response.statusText}`);
return null;
}
} catch (error) {
if (error.name === 'TypeError') {
const errorMessage = `Network error occurred. Refreshing usually fixes this issue.\n\nError details: ${error.message}\n\nDo you want to refresh the page?`;
if (window.confirm(errorMessage)) {
window.location.reload();
} else {
console.warn('Refresh cancelled by user.');
}
return null;
} else {
console.error('Error in requestNabuCasaTTS:', error);
return null;
}
}
}
async function getVoicesForEngine(server, bearer, engineId, language) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(server+"/api/websocket");
ws.onopen = function open() {
// Authenticate with Home Assistant
ws.send(JSON.stringify({ type: "auth", access_token: bearer }));
};
ws.onmessage = function incoming(event) {
const message = JSON.parse(event.data);
// Handle authentication response
if (message.type === "auth_ok") {
// Send the command to list voices
ws.send(JSON.stringify({
id: 1,
type: "tts/engine/voices",
engine_id: engineId,
language: language
}));
}
// Handle the response to list voices
if (message.id === 1) {
if (message.result) {
resolve(message.result.voices);
ws.close();
} else if (message.error) {
reject(`Error: ${message.error.message}`);
ws.close();
}
}
};
ws.onerror = function error(err) {
reject(`WebSocket error: ${err.message}`);
};
});
}
export async function populateNabuCasaVoiceSelect(server, bearer, engineId) {
const voicesSelect = document.getElementById("nabu-casa-voice-select");
const selectedOption = getCookie("nabu-casa-voice-select");
try {
const languages = await getSupportedLanguages(server, bearer, engineId);
voicesSelect.innerHTML = ''; // Clear existing options
for (const language of languages) {
const voices = await getVoicesForEngine(server, bearer, engineId, language);
for (const voice of voices) {
const option = document.createElement('option');
const optionValue = `${language} ${voice.voice_id}`;
option.value = optionValue;
option.textContent = `${language} - ${voice.name}`;
voicesSelect.appendChild(option);
// Check if the current option matches the cookie value
if (optionValue === selectedOption) {
voicesSelect.value = optionValue;
}
}
}
} catch (error) {
console.error('Error populating voice select:', error);
}
}
async function getSupportedLanguages(server, bearer, engineId) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(server+"/api/websocket");
ws.onopen = function open() {
// Authenticate with Home Assistant
ws.send(JSON.stringify({ type: "auth", access_token: bearer }));
};
ws.onmessage = function incoming(event) {
const message = JSON.parse(event.data);
// Handle authentication response
if (message.type === "auth_ok") {
// Send the command to get engine info
ws.send(JSON.stringify({
id: 1,
type: "tts/engine/get",
engine_id: engineId
}));
}
// Handle the response to get engine info
if (message.id === 1) {
if (message.result && message.result.provider) {
resolve(message.result.provider.supported_languages);
ws.close();
} else if (message.error) {
reject(`Error: ${message.error.message}`);
ws.close();
}
}
};
ws.onerror = function error(err) {
reject(`WebSocket error: ${err.message}`);
};
});
}