Записывайте Js-Аудио С Микрофона Или Голосовые Комментарии.



Записывайте JS-аудио с микрофона или голосовые комментарии.

Не так давно при разработке корпоративного веб-приложения заказчик захотел иметь возможность оставлять голосовые комментарии.

Я никогда раньше не сталкивался с созданием медиаконтента и с интересом начал изучать эту тему.

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

После того, как заказчик выполнил задачу, я решил опубликовать максимально упрощенный пример записи и сохранения голосового комментария и написать статью.

Возможно, кому-то этот материал окажется полезным и поможет в изучении.



Постановка задачи

Поставим перед собой задачу разработать мини-приложение, работающее в браузере, которое позволит записать голосовой комментарий, отправить запись на сервер, сервер сохранит запись, в случае успеха вернет ответ с именем созданного.

файл и отобразить объект на странице, чтобы запись можно было прослушать.



Запись звука в браузере

Запись звука было решено реализовать с помощью веб-API MediaStream Recording. Для записи мы будем использовать интерфейс MediaRecorder().

Но сначала давайте создадим интерфейс.

Пусть у нас будет index.html, содержащий только самые основные теги, а в тело тега мы включим файл с нашим будущим JavaScript voice.js:

  
  
  
  
  
  
   

<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>Voice comments</title> </head> <body> <script src="voice.js"></script> </body> </html>

Создадим файл voice.js, определим в нем URL-константу, которая будет содержать ссылку на скрипт, получающий записанный звук.

Далее мы создадим кнопки «Старт» и «Стоп» для запуска и остановки записи звука, а также блок div, в котором будут отображаться сохраненные записи.

На этом наш интерфейс готов, можно переходить непосредственно к записи звука.

Как уже говорилось, для записи мы будем использовать интерфейс MediaRecorder() (подробнее об интерфейсе можно прочитать в документации).

Чтобы это работало, нам нужно определить медиапоток, из которого мы будем брать звук.

Мы его инициализируем только потому, что нам нужна только звуковая дорожка.



navigator.mediaDevices.getUserMedia({ audio: true}) .

then(stream => { const mediaRecorder = new MediaRecorder(stream)});

Теперь у нас есть константа mediaRecorder, содержащая экземпляр интерфейса, и мы продолжим с ней работать.

Для начала записи нам нужно вызвать метод MediaRecorder.start(), для остановки записи — метод MediaRecorder.stop().

В этом случае MediaRecorder.stop() генерирует событие dataavailable, посредством которого мы получим доступ к оцифрованной звукозаписи в виде двоичного массива.

И так опишем вышеописанные события, объявим массив voice[] и запишем в него полученные данные:

navigator.mediaDevices.getUserMedia({ audio: true}) .

then(stream => { const mediaRecorder = new MediaRecorder(stream); let voice = []; document.querySelector('#start').

addEventListener('click', function(){ mediaRecorder.start(); }); mediaRecorder.addEventListener("dataavailable",function(event) { voice.push(event.data); }); document.querySelector('#stop').

addEventListener('click', function(){ mediaRecorder.stop(); }); });

Теперь подготовим полученные данные к отправке.

Для этого по событию остановки мы создадим экземпляр BLOB, поместим в него полученные данные и укажем тип данных MIME. В нашем случае это будет audio/wav.

mediaRecorder.addEventListener("stop", function() { const voiceBlob = new Blob(voice, { type: 'audio/wav' });

В результате у нас есть константа voiceBlob, которая содержит содержимое нашего будущего wav-файла с записью голосового сообщения.



Отправка записи на сервер

Чтобы отправить запись на сервер, я решил использовать метод fetch().

Так как этот метод является самым современным и обеспечивает улучшенный интерфейс выполнения запросов к серверу.

В рамках нашей задачи нам необходимо инициировать POST-запрос, в теле которого мы отправим содержимое нашего будущего файла для сохранения на сервере (как работает метод fetch() и какие возможности есть у метода fetch()).

Подробности можно найти в документации).

Давайте создадим новую форму с голосовым полем и поместим в нее содержимое нашей записи.



let fd = new FormData(); fd.append('voice', voiceBlob);

Создадим асинхронную функцию для отправки сообщения на сервер, получения ответа и отображения аудиообъекта для воспроизведения уже сохраненного файла.

Функция примет форму, созданную выше, в качестве аргумента.

Инициируем запрос к серверу:

let promise = await fetch(URL, { method: 'POST', body: form});

Если HTTP-ответ от сервера не содержит кода ошибки (код ответа в диапазоне 200-299), то нам остается только декодировать ответ, создать на странице новый аудиообъект, определить его свойства и отобразить это.

О том, как формируется ответ, пойдет речь ниже.



Сохранение файла на сервере

Давайте создадим на сервере скрипт, который будет принимать наш POST-запрос голосовым сообщением.

Так как отправленная нами звукозапись по сути уже является файлом в виде, то на сервер мы получим ее соответственно:

$uploadDir = 'voice/'; $typeFile = explode('/', $_FILES['voice']['type']); $uploadFile = $uploadDir .

basename(md5($_FILES['voice']['tmp_name'].

time()).

'.

'.

$typeFile[1]); if (move_uploaded_file($_FILES['voice']['tmp_name'], $uploadFile)) { $response = ['result'=>'OK', 'data'=>'.

/'.

$uploadFile]; } else { $response = ['result'=>'ERROR', 'data'=>'']; } echo json_encode($response);

В Интернете можно найти множество подобных примеров PHP-кода для обработки полученных файлов.

Сначала инициализируем переменные $uploadDir — каталог, в котором будет сохранен полученный файл, тип файла &typeFile в нашем случае будет равен wav и полное имя файла, включая каталог.

Имя файла в этом случае формируется путем объединения «временного» имени файла и строкового значения текущего времени, зашифрованного методом md5. Если файл с голосовым сообщением успешно сохранен в указанной директории, формируем ответ в виде массива, содержащего поле результата, равное «ОК» или «ОШИБКА» в зависимости от результата и поля «данные», которое, в случае успешной обработки содержит ссылку на сохраненный файл.

Для удобства преобразуем массив в объект JSON и отправляем его в ответ. Полный код примера опубликован по адресу GitHub .

P.S. Браузер позволяет записывать медиаконтент только при наличии защищенного HTTPS-соединения.

Теги: #JavaScript #php #запись звука #голосовые сообщения

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.