Лучше всего создать численный типизированный массив, скажем myArray и поместить в него стандартный заголовок аудиофайла формата wav, в конце за ним поместить данные из переменной JS, преобразовав их перед этим в числа. После этого подключить этот массив в качестве src к элементу аудио так:
audio.src = URL.createObjectURL(new Blob([myArray], {type: audio/wav})); |
Цитата:
// мой вариант new Audio('/api/get-wav').addEventListener('canplaythrough', function () { this.play(); }); // ваш вариант fetch('/api/get-wav').then(res => res.blob()).then(blob => { const audio = new Audio( URL.createObjectURL(blob) ); audio.addEventListener('canplaythrough', () => audio.play()); }); |
Лучше тем, что без этого заголовка получатся сырые данные, т. е., будет неизвестно, как их следует читать - с какой частотой семплированья, с каким количеством стереоканалов, сколько байт приходится на семпл и т. п. Хот может я забыл предусмотреть, что в переменной js уже есть этот заголовок, но трудно это представить, если там может всё быть в формате string. А если требуется вывести сообщение об окончании воспроизведения, а то для этого подходит событие onended, т. к., canplaythgrough используют для вывода сообщения, что аудио/видео будет воспроизводиться до конца без остановки.
|
Цитата:
Цитата:
Т.е. чтобы имплементировать воспроизведения аудио нужно будет, в любом случае, получить этот аудиофайл от сервера. Таки вопрос: нахрена нам что-то вручную делать, если можно просто скормить классу Audio ссылку на аудиофайл? |
Nexus,
так было бы просто сделать, если бы этот аудиофайл был статическим. Но изложенная ситуация допускает, что это должен быть не постоянный, а сгенерированный аудиофайл, и возможно с каждым новым ajax-запросом его содержимое должно быть каким-то другим. Т. е., должен каждый раз быть новый звук. Я сам с этим имел дело. Поэтому изложил способ, которым я пользовался чтобы подключить эти сгенерированные данные к элементу аудио, чтобы не приходилось создавать временный файл на жёстком диске. |
Ну если его надо один раз получить, проиграть и забыть, то без разницы каким способом.
Другое дело, если его надо получать и проигрывать. Может быть даже используя полноценный элемент <audio>, с возможностью двигать таймкоды. Тогда, конечно в БЛОБ сохранять. |
Пробую отдавать файл на стороне сервера:
header('Content-type: application/octet-stream'); header('Content-Length: '.filesize('wave.wav')); header('Content-Disposition: attachment; filename="wave.wav"'); readfile('wave.wav'); Смотрю что пересывается. Содержимое похоже на формат wave файла. Подправляю для случая с переменой: header('Content-type: application/octet-stream'); header('Content-Length: '.mb_strlen($rawWave, '8bit')); Смотрю что пересылается. Что прям непонятно что. Что не так я делаю? Как правильно отправлять данные ? |
Видимо без исследования в шестнадцатеричном редакторе содержимого того, что получается не обойтись. Почему Вы просто не подключаете этот файл к аудио:
<audio src="wave.wav"></audio> |
Такого кода должно быть достаточно, другое дело, что Chrome не воспроизводит wav-файлы.
header('Content-Type: audio/wav'); header('Content-Length: ' . mb_strlen($rawWave, '8bit')); header('Content-Disposition: attachment; filename="wave.wav"'); echo $rawWave; |
echo $rawWave; Да помогло, что то не сообразил. Данные получаю ответом на запрос: ... success: function(data) { } ... Это по сути прочитанный файл в переменную. Как запустить эти данные на воспроизведения, я что то так и не понял до конца, если вообще такое возможно. audio = new Audio('/api/get-wav').addEventListener('canplaythrough', function () { this.play(); }); audio.src = URL.createObjectURL(new Blob([data], {type: audio/wav})); } Но нужна тогда ссылка /api/get-wav а ее генерить бы не хотелось бы. |
Часовой пояс GMT +3, время: 09:17. |