Создайте видео и аудио рекордер с JavaScript MediaRecorder API
WebRTC очень популярен для доступа к камерам и микрофонам устройств, а также для потоковой передачи видео или аудио в браузере. Но во многих случаях нам может потребоваться записать потоковую передачу для будущего использования или для пользователей (например, пользователь может захотеть загрузить потоковую передачу и т. д.). В этом случае мы можем использовать MediaRecorder API для записи потокового мультимедиа.
В этой статье мы создадим базовый веб-сайт Video and Audio Recorder, используя чистый JavaScript и его API MediaRecorder.
Описание проекта: Веб-сайт, который мы создаем, будет иметь:
- Опция выбора, позволяющая пользователям выбирать, какой тип мультимедиа (аудио или видео со звуком) записывать.
- Если пользователь решит записывать видео, браузер запросит разрешение на доступ к камере и микрофону устройства, и если пользователь разрешит, то —
- Элемент видео будет отображать медиапоток камеры.
- Кнопка «Начать запись» запускает запись.
- Кнопка «Остановить запись» остановит запись.
- Когда запись завершена, отображается новый элемент видео, содержащий записанный носитель.
- Ссылка, позволяющая пользователям загружать записанное видео.
- Если пользователь выберет запись только аудио, то браузер запросит разрешение на доступ к микрофону, а если пользователь разрешит, то —
- Кнопка «Начать запись» запускает запись.
- Кнопка «Остановить запись» остановит запись.
- Когда запись завершена, отображается новый аудиоэлемент, содержащий записанный звук.
- Дается ссылка, позволяющая пользователям загружать записанный звук.
Итак, давайте сначала настроим нашу простую HTML-страницу —
index.html
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" > < meta http-equiv = "X-UA-Compatible" content = "IE=edge" > < meta name = "viewport" content = "width=device-width, initial-scale=1.0" > < link rel = "stylesheet" href = "index.css" > < title >Video & Audio Recorder</ title > </ head > < body > < h1 > Video & Audio Recorder </ h1 > < label for = "media" > Select what you want to record: </ label > < select id = "media" > < option value = "choose-an-option" > Choose an option </ option > < option value = "vid" >Video</ option > < option value = "aud" >Audio</ option > </ select > < div class = "display-none" id = "vid-recorder" > < h3 >Record Video </ h3 > < video autoplay id = "web-cam-container" style = "background-color: black;" > Your browser doesn"t support the video tag </ video > < div class = "recording" id = "vid-record-status" > Click the "Start video Recording" button to start recording </ div > <!-- This button will start the video recording --> < button type = "button" id = "start-vid-recording" onclick="startRecording(this, document.getElementById("stop-vid-recording"))"> Start video recording </ button > <!-- This button will stop the video recording --> < button type = "button" id = "stop-vid-recording" disabled onclick="stopRecording(this, document.getElementById("start-vid-recording"))"> Stop video recording </ button > <!--The video element will be created using JavaScript and contains recorded video--> <!-- <video id="recorded-video" controls> Your browser doesn"t support the video tag </video> --> <!-- The below link will let the users download the recorded video --> <!-- <a href="" > Download it! </a> --> </ div > < div class = "display-none" id = "aud-recorder" > < h3 > Record Audio</ h3 > < div class = "recording" id = "aud-record-status" > Click the "Start Recording" button to start recording </ div > < button type = "button" id = "start-aud-recording" onclick="startRecording(this, document.getElementById("stop-aud-recording"))"> Start recording </ button > < button type = "button" id = "stop-aud-recording" disabled onclick="stopRecording(this, document.getElementById("start-aud-recording"))"> Stop recording </ button > <!-- The audio element will contain the recorded audio and will be created using Javascript --> <!-- <audio id="recorded-audio" controls></audio> --> <!-- The below link will let the users download the recorded audio --> <!-- <a href="" > Download it! </a> --> </ div > < script src = "index.js" ></ script > </ body > </ html > |
Выход:
Если вы внимательно проверите index.html , вы увидите, что теги видео и аудио не имеют никакого источника. Мы добавим источники позже, используя JavaScript. На данный момент у нас есть опция выбора, которая позволяет пользователю выбрать тип носителя, который он хочет записать. Первый элемент видео внутри элемента div «vid-recorder» будет содержать поток с веб-камеры, а элемент видео в комментариях будет содержать записанное видео. Обратите внимание, что только последний элемент видео имеет атрибут «controls» , так как первый элемент видео будет содержать поток и не нуждается ни в каких элементах управления.
Внутри div «aud-recorder» у нас есть две кнопки для запуска и остановки записи, элемент audio с комментариями будет содержать записанный звук.
Теперь давайте добавим немного CSS на HTML-страницу —
index.css
body { text-align : center ; color : green ; font-size : 1.2em ; } .display- none { display : none ; } .recording { color : red ; background-color : rgb ( 241 211 211 ); padding : 5px ; margin : 6px auto ; width : fit-content; } video { background-color : black ; display : block ; margin : 6px auto ; width : 420px ; height : 240px ; } audio { display : block ; margin : 6px auto ; } a { color : green ; } |
Выход:
На данный момент мы добавили класс «display-none» в разделы «vid-Recorder» и «Aud-Recorder» . Поскольку мы хотим отображать правильный рекордер на основе выбора пользователя.
Теперь давайте реализуем логику для отображения только выбранного пользователем рекордера с помощью JavaScript —
index.js
const mediaSelector = document.getElementById( "media" ); let selectedMedia = null ; // Handler function to handle the "change" event // when the user selects some option mediaSelector.addEventListener( "change" , (e) => { selectedMedia = e.target.value; document.getElementById( `${selectedMedia}-recorder`).style.display = "block" ; document.getElementById( `${otherRecorder(selectedMedia)}-recorder`) .style.display = "none" ; }); function otherRecorder(selectedMedia) { return selectedMedia === "vid" ? "aud" : "vid" ; } |
Вывод: когда пользователь выбирает «видео», отображается следующий видеомагнитофон —
Точно так же, когда пользователь выбирает опцию «аудио» , отображается аудиорекордер —
Приведенный выше код отображает только выбранный пользователем рекордер, т. е. аудио или видео. Мы добавили прослушиватель события «change» в элемент mediaSelector, когда значение элемента select изменяется, он генерирует событие «change» , и это событие обрабатывается заданной функцией обратного вызова. Функция обратного вызова изменяет свойство CSS «display» выбранного устройства записи мультимедиа на «block», а другого устройства записи мультимедиа — на «none» .
Доступ к веб-камере и микрофону: WebRTC API getUserMedia позволяет получить доступ к камере и микрофону устройства. Метод getUserMedia() возвращает Promise, который разрешается в MediaStream, который содержит мультимедийное содержимое (поток мультимедийных дорожек) на основе заданных спецификаций. Метод getUserMedia() принимает объект MediaStreamConstraints в качестве параметра, определяющего все ограничения, которым должен соответствовать результирующий медиапоток.
const mediaStreamConstraints = { audio: true, video: true }; // The above MediaStreamConstraints object // specifies that the resulting media must have // both the video and audio media content or tracks. // The mediaStreamConstraints object is passed to // the getUserMedia method navigator.mediaDevices.getUserMedia( MediaStreamConstraints ) .then( resultingMediaStream => { // Code to use the received media stream });
Когда вызывается метод getUserMedia, браузер запрашивает у пользователя разрешение на использование камеры и микрофона устройства. Если пользователь разрешает это, то обещание, возвращаемое getUserMedia, разрешается в результирующий медиапоток, в противном случае генерируется исключение NotAllowedError . В приведенном выше коде полученный медиапоток содержит как видеоданные, так и аудиоданные.
Итак, добавьте следующие строки кода в файл index.js:
index.js
const mediaSelector = document.getElementById( "media" ); // Added code const webCamContainer = document .getElementById( "web-cam-container" ); let selectedMedia = null ; /* Previous code ... Added code */ const audioMediaConstraints = { audio: true , video: false }; const videoMediaConstraints = { // or you can set audio to false // to record only video audio: true , video: true }; function startRecording(thisButton, otherButton) { navigator.mediaDevices.getUserMedia( selectedMedia === "vid" ? videoMediaConstraints : audioMediaConstraints) .then(mediaStream => { // Use the mediaStream in // your application // Make the mediaStream global window.mediaStream = mediaStream; if (selectedMedia === "vid" ) { // Remember to use the "srcObject" // attribute since the "src" attribute // doesn"t support media stream as a value webCamContainer.srcObject = mediaStream; } document.getElementById( `${selectedMedia}-record-status`) .innerText = "Recording" ; thisButton.disabled = true ; otherButton.disabled = false ; }); } function stopRecording(thisButton, otherButton) { // Stop all the tracks in the received // media stream i.e. close the camera // and microphone window.mediaStream.getTracks().forEach(track => { track.stop(); }); document.getElementById( `${selectedMedia}-record-status`) .innerText = "Recording done!" ; thisButton.disabled = true ; otherButton.disabled = false ; } |
Функция startRecording вызывает метод navigator.mediaDevices.getUserMedia() для доступа к камере и микрофону устройства, отключает кнопку «начать запись» и включает кнопку «остановить запись» . Принимая во внимание, что функция stopRecording закрывает камеру и микрофон, вызывая метод «stop()» каждой медиадорожки, используемой медиапотоком, отключает кнопку «остановить запись» и включает кнопку «начать запись» .
Внедрение рекордера: до сих пор мы имели доступ только к веб-камере и микрофону, но ничего не делали для записи мультимедиа.
Чтобы записать медиапоток, нам сначала нужно создать экземпляр MediaRecorder (интерфейс для записи медиапотоков) с помощью конструктора MediaRecorder.
Конструктор MediaRecorder принимает два параметра:
- поток: поток похож на поток данных (данные любого типа). Здесь, в этой статье, мы будем использовать MediaStream, который в основном представляет собой поток медиа (видео или аудио или и того, и другого) данных или медиаконтента.
- Опции (необязательные): объект, содержащий некоторые характеристики записи. Вы можете установить MIME-тип записанного медиафайла, битрейт аудио, видео и т. д. MIME-тип — это стандарт, представляющий формат записанного медиафайла (например, два типа MIME — «аудио/ webm», «video/mp4» обозначают аудиофайл webm и видеофайл mp4 соответственно).
Синтаксис:
const mediaRecorder = new MediaRecorder( stream, { mimeType: "audio/webm" });
Приведенная выше строка кода создает новый экземпляр MediaRecorder, который записывает данный поток и сохраняет его в виде аудиофайла WebM.
Итак, измените файл index.js:
index.js file
/* Previous code ... */ function startRecording(thisButton, otherButton) { navigator.mediaDevices.getUserMedia( selectedMedia === "vid" ? videoMediaConstraints : audioMediaConstraints) .then(mediaStream => { /* New code */ // Create a new MediaRecorder // instance that records the РЕКОМЕНДУЕМЫЕ СТАТЬИ |