Порефакторю потом.
✔️ HTTP-запросы отправляются методом fetch(). Он всегда работает асинхронно, поэтому взял синтаксис async/await. И хотя запросы не блокируются во время ожидания ответа от сервера, процесс все равно синхронен.
✔️ Аудиофайл создается так:
1️⃣ Fetch всегда отдает данные как promise. Приводим промис к json и забираем base64-строку.
Ukfj/9//0P...
2️⃣ Функцией atob() декодируем её в бинарную строку. В ней каждый символ будет представлять байт бинарных данных.
Кракозябры. Не сойдется кодировка, но это не важно.
3️⃣ Мы все ещё работаем со строкой. Для создания аудиофайла нужны байты. Приведём строку к структуре массива байтов Uint8Array. Наша цель получить кол-во элементов в массиве равное длине бинарной строки.
Много нулей:
0, 0, 0...
Нам важно только чтобы кол-во элементов массива равнялось их кол-ву в бинарной строке!
Тип данных уже не string, а object!
4️⃣ Проходим циклом по массиву байтов, меняя каждый 0 на char-код каждого символа строки.
Нули заменены на char-коды символов: 82, 73, 70, 70...
5️⃣ Создаем объект Blob, представляющий сырые бинарные данные (коллекция байтов). На вход подаётся созданный ранее массив. Со строками он не умеет работать, отсюда и вся махинация.
6️⃣ Создаем url нашего файла, а затем и сам аудиофайл через объект new Audio(url);
7️⃣ Запускаем озвучку в браузере методом .play().
✔️ Бинго! Надо озвучить другой текст? Подставляем его в тело запроса и жмем Enter.
const getAudio = async() => {
try {
sessionIdFromLs = localStorage.getItem("session_id");
const response1 = await fetch("ЗАПРОС НА TTS-СИНТЕЗ", {
"headers": {
"X-Session-ID": `${sessionIdFromLs}`,
"Content-Type": "application/json"
},\
"body": "{ТЕКСТ ДЛЯ ОЗВУЧКИ}",
"method": "POST"
});
if (response1.ok) {
const data_blob = await response1.json();
const blob_value = data_blob.data;
const binary = atob(blob_value);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i <binary.length; i++) bytes[i] = binary.charCodeAt(i);
const blob = new Blob([bytes], {type: 'audio/wav'});
const url = URL.createObjectURL(blob);
const audio = new Audio(url);
audio.play()
} else {
const response2 = await fetch("ЗАПРОС СОЗДАНИЯ СЕССИИ", {
"headers": {
"content-type": "application/json"
},
"body": "{ЛОГИН И ПАРОЛЬ}",
"method": "POST"
});
const data = await response2.json();
sessionIdFromLs = data.session_id;
localStorage.setItem("session_id", sessionIdFromLs);
const response3 = await fetch("ЗАПРОС НА TTS-СИНТЕЗ", {
"headers": {
"X-Session-ID": `${sessionIdFromLs}`,
"Content-Type": "application/json"
},
"body": "{ТЕКСТ ДЛЯ ОЗВУЧКИ}",
"method": "POST"
});
const data_blob = await response3.json();
const blob_value = data_blob.data;
const binary = atob(blob_value);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i <binary.length; i++) bytes[i] = binary.charCodeAt(i);
const blob = new Blob([bytes], {type: 'audio/wav'});
const url = URL.createObjectURL(blob);
const audio = new Audio(url);
audio.play()
};
} catch(error) {
console.error('Ошибка: ', error);
};
};
getAudio()