С вебом никак не связан, пишу для себя по настроению, поэтому могу не знать/плохо знаю какие-то, казалось бы, базовые вещи.
Проблема: когда пользователь запрашивает аудио файл для воспроизведения у сервера, он получает непосредственно сам буфер(string)/содержимое этого аудио файла. После получения буфера его необходимо как-то обработать и воспроизвести. Для решения этой проблемы я смог найти только способ с использованием объектов Blob и Audio, но в моем случае он не работает, выдавая в консоль браузера:
Не удалось декодировать медиаресурс blob:http://localhost:3000/8d214977-3b73-4efc-a917-b65693cacf72.
NotSupportedError: The media resource indicated by the src attribute or assigned media provider object was not suitable.
Не удалось декодировать медиаресурс blob:http://localhost:3000/8d214977-3b73-4efc-a917-b65693cacf72, ошибка: Error Code: NS_ERROR_DOM_MEDIA_METADATA_ERR (0x806e0006)
Вот обработчик, который при нажатии на кнопку отправляет серверу POST запрос, содержащий имя запрашиваемого аудио файла, а после ответа пытается его воспроизвести:
function handler(event) {
fetch('http://localhost:3000/play', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({path: event.explicitOriginalTarget.value}) // имя файла
}).then(data => {
data.text().then(audioBuffer => {
const blob = new Blob([audioBuffer], {type: 'audio/mp3'});
const urlBlob = URL.createObjectURL(blob);
new Audio(urlBlob).play();
});
});
}
Сторона сервера, обрабатывающая запросы роута /play:
server.on('request', (req, res) => {
const urlObj = url.parse(req.url, true);
switch (urlObj.pathname) {
// ...
case '/play':
let body = '';
req.on('data', data => {
body = data; // получаем данные о имени файла (путь к файлу) от клиента
});
req.on('end', () => {
sendAudioFile(res, body); // когда получили данные, отправляем файл клиенту
});
break;
// ...
}
});
Содержимое функции sendAudioFile:
function sendAudioFile(response, body) {
const path = JSON.parse(body.toString()).path; // что-то вроде D:/Music/Artist/Album/song.mp3
const splitedPath = path.split('.');
const format = splitedPath[splitedPath.length - 1]; // mp3
const fileSize = fs.statSync(path).size;
const header = {
'Content-Length': fileSize,
'Content-Type': `audio/${format}`
};
response.writeHead(200, header);
fs.createReadStream(path).pipe(response);
}