Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Воспроизведение аудио (https://javascript.ru/forum/misc/81263-vosproizvedenie-audio.html)

Опан1 31.10.2020 11:27

Лучше всего создать численный типизированный массив, скажем myArray и поместить в него стандартный заголовок аудиофайла формата wav, в конце за ним поместить данные из переменной JS, преобразовав их перед этим в числа. После этого подключить этот массив в качестве src к элементу аудио так:
audio.src = URL.createObjectURL(new Blob([myArray], {type: audio/wav}));

Nexus 31.10.2020 13:20

Цитата:

Сообщение от Опан1
Лучше всего создать численный типизированный массив, скажем myArray и поместить в него стандартный заголовок аудиофайла формата wav, в конце за ним поместить данные из переменной JS

И чем же это лучше?

// мой вариант
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());
});

Опан1 31.10.2020 15:32

Лучше тем, что без этого заголовка получатся сырые данные, т. е., будет неизвестно, как их следует читать - с какой частотой семплированья, с каким количеством стереоканалов, сколько байт приходится на семпл и т. п. Хот может я забыл предусмотреть, что в переменной js уже есть этот заголовок, но трудно это представить, если там может всё быть в формате string. А если требуется вывести сообщение об окончании воспроизведения, а то для этого подходит событие onended, т. к., canplaythgrough используют для вывода сообщения, что аудио/видео будет воспроизводиться до конца без остановки.

Nexus 31.10.2020 16:11

Цитата:

Сообщение от Опан1
Лучше тем, что без этого заголовка получатся сырые данные

:-?

Цитата:

Сообщение от Опан1
если там может всё быть в формате string

Вы уперлись в то, что у вас данные аудиофайла находятся в переменной, однако у автора пока-что вообще никаких данных нет, т.к. он не смог ответить на вопрос какой тип данных находится в переменной.

Т.е. чтобы имплементировать воспроизведения аудио нужно будет, в любом случае, получить этот аудиофайл от сервера.
Таки вопрос: нахрена нам что-то вручную делать, если можно просто скормить классу Audio ссылку на аудиофайл?

Опан1 31.10.2020 18:41

Nexus,
так было бы просто сделать, если бы этот аудиофайл был статическим. Но изложенная ситуация допускает, что это должен быть не постоянный, а сгенерированный аудиофайл, и возможно с каждым новым ajax-запросом его содержимое должно быть каким-то другим. Т. е., должен каждый раз быть новый звук. Я сам с этим имел дело. Поэтому изложил способ, которым я пользовался чтобы подключить эти сгенерированные данные к элементу аудио, чтобы не приходилось создавать временный файл на жёстком диске.

voraa 31.10.2020 18:48

Ну если его надо один раз получить, проиграть и забыть, то без разницы каким способом.
Другое дело, если его надо получать и проигрывать. Может быть даже используя полноценный элемент <audio>, с возможностью двигать таймкоды. Тогда, конечно в БЛОБ сохранять.

him 02.11.2020 14:00

Пробую отдавать файл на стороне сервера:

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'));


Смотрю что пересылается. Что прям непонятно что.
Что не так я делаю? Как правильно отправлять данные ?

Опан1 02.11.2020 16:45

Видимо без исследования в шестнадцатеричном редакторе содержимого того, что получается не обойтись. Почему Вы просто не подключаете этот файл к аудио:
<audio src="wave.wav"></audio>

Nexus 02.11.2020 16:46

Такого кода должно быть достаточно, другое дело, что Chrome не воспроизводит wav-файлы.
header('Content-Type: audio/wav');
header('Content-Length: ' . mb_strlen($rawWave, '8bit'));
header('Content-Disposition: attachment; filename="wave.wav"');

echo $rawWave;

him 09.11.2020 17:05

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.