Создание диктофона с помощью Media Recorder и getUserMedia
MediaStream Recording API позволяет легко записывать аудио и / или видео потоки. При использовании MediaDevices.getUserMedia()
обеспечивается простой способ записи мультимедиа с устройств ввода пользователя и мгновенного использования результата в веб-приложениях. В этой статье показано, как использовать эти технологии для создания забавного приложения для диктофона.
Пример приложения: веб-диктофон
Чтобы продемонстрировать базовое использование API MediaRecorder, мы создали веб-диктофон. Это позволяет записывать фрагменты аудио, а затем воспроизводить их. Он даже дает вам визуализацию звукового ввода вашего устройства с помощью API Web Audio. Для краткости мы просто сосредоточимся на функциональности записи и воспроизведения в этой статье.
Основные настройки приложения
Для работы с медиапотоком, который мы хотим захватить, мы используем функцию getUserMedia()
. Затем мы используем API MediaRecorder для записи потока и выводим каждый записанный фрагмент в источник сгенерированного элемента audio
, чтобы его можно было воспроизвести.
Сначала мы объявим некоторые переменные для кнопок записи и остановки, article
которые будут содержать сгенерированные аудиоплееры:
const record = document.querySelector('.record');
const stop = document.querySelector('.stop');
const soundClips = document.querySelector('.sound-clips');
Далее настраиваем базовую структуру getUserMedia
:
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
console.log('getUserMedia supported.');
navigator.mediaDevices.getUserMedia (
// constraints - only audio needed for this app
{
audio: true
})
// Success callback
.then(function(stream) {
})
// Error callback
.catch(function(err) {
console.log('The following `getUserMedia` error occured: ' + err);
}
);
} else {
console.log('getUserMedia not supported on your browser!');
}
Все это заключено в условие, которое проверяет, поддерживается ли getUserMedia
, прежде чем запускать что-либо еще. Далее мы вызываем getUserMedia()
и внутри него определяем:
- Ограничения : Для нашего диктофона должно быть записано только аудио.
Then
: этот код запускается после успешного завершения вызоваgetUserMedia
.Catch
: код запускается, если по какой-либо причине произошел сбой вызоваgetUserMedia
.
Примечание . Весь код, приведенный ниже, находится внутри getUserMedia
обратного вызова в готовой версии.
Захват медиапотока
После успешного создания медиапотока вы создаете новый экземпляр Media Recorder с помощью конструктора MediaRecorder()
и передаете ему поток напрямую. Это ваша точка входа в использование MediaRecorder API - теперь поток готов к записи в Blob
.
const mediaRecorder = new MediaRecorder(stream);
В интерфейсе MediaRecorder
есть ряд методов, которые позволяют вам управлять записью медиапотока; в веб-диктофоне мы просто используем два и слушаем некоторые события. Прежде всего MediaRecorder.start()
, используется для начала записи потока после нажатия кнопки записи:
record.onclick = function() {
mediaRecorder.start();
console.log(mediaRecorder.state);
console.log("recorder started");
record.style.background = "red";
record.style.color = "black";
}
Когда MediaRecorder выполняет запись, свойство MediaRecorder.state
возвращает значение «recording».
По мере продвижения записи нам нужно собирать аудиоданные. Мы регистрируем обработчик событий, чтобы сделать это, используем mediaRecorder.ondataavailable
:
let chunks = [];
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
}
Наконец, мы используем метод MediaRecorder.stop()
, чтобы остановить запись, когда нажата кнопка остановки, и завершить готовый Blob
к использованию где-нибудь еще в нашем приложении.
stop.onclick = function() {
mediaRecorder.stop();
console.log(mediaRecorder.state);
console.log("recorder stopped");
record.style.background = "";
record.style.color = "";
}
Обратите внимание, что запись также может быть остановлена естественным образом, если поток мультимедиа заканчивается (например, если вы захватывали дорожку песни, а дорожка закончилась или пользователь прекратил совместное использование своего микрофона).
Получение и использование Blob
Когда запись остановлена, свойство state
возвращает значение «inactive», и вызывается событие остановки. Мы для этого регистрируем обработчик событий mediaRecorder.onstop
, и создаем наш BLOB-объект из всех кусков, которые мы получили:
mediaRecorder.onstop = function(e) {
console.log("recorder stopped");
const clipName = prompt('Enter a name for your sound clip');
const clipContainer = document.createElement('article');
const clipLabel = document.createElement('p');
const audio = document.createElement('audio');
const deleteButton = document.createElement('button');
clipContainer.classList.add('clip');
audio.setAttribute('controls', '');
deleteButton.innerHTML = "Delete";
clipLabel.innerHTML = clipName;
clipContainer.appendChild(audio);
clipContainer.appendChild(clipLabel);
clipContainer.appendChild(deleteButton);
soundClips.appendChild(clipContainer);
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
deleteButton.onclick = function(e) {
let evtTgt = e.target;
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
}
}
Давайте пройдемся по приведенному выше коду и посмотрим, что происходит.
Во-первых, мы отображаем подсказку с просьбой дать пользователю название своего клипа.
Затем мы создаем структуру HTML, подобную следующей, вставляя ее в наш контейнер клипов, который является элементом article
.
_your clip name_
После этого мы создаем объединенные Blob
из записанных аудиоблоков и создаем объект URL, указывающий на него, используя window.URL.createObjectURL(blob)
. Затем мы устанавливаем значение атрибута src
элемента audio
в полученный URL из объекта, чтобы при нажатии кнопки воспроизведения на аудиоплеере он воспроизводил наш Blob
.
Наконец, мы устанавливаем обработчик onclick
для кнопки удаления как функцию, которая удаляет всю структуру HTML клипа.