Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to Create a Video and Audio Recorder with JavaScript MediaRecorder API?
In this tutorial, you will learn how to create an audio and video recorder using JavaScript's MediaRecorder API with WebRTC technology. This allows you to capture and record media directly in the browser.
What is WebRTC?
WebRTC (Web Real-Time Communication) enables real-time communication capabilities in web browsers. It allows access to user devices like webcams and microphones through JavaScript APIs.
The core method for accessing media devices is:
navigator.mediaDevices.getUserMedia(constraints)
The getUserMedia() function requests user permission to access the webcam and microphone. It returns a Promise that resolves with a MediaStream if permission is granted, or rejects if denied.
HTML Structure
Our interface includes:
Video Section: A video element to display the live stream, plus start/stop buttons
Audio Section: Start/stop buttons for audio recording
Font Awesome icons: For attractive play/stop button styling
Example: Complete HTML Structure
<!DOCTYPE html>
<html>
<head>
<title>Video & Audio Recorder</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {
text-align: center;
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
color: #2196F3;
margin-bottom: 30px;
}
.recorder-section {
margin: 30px 0;
padding: 20px;
border: 2px solid #ddd;
border-radius: 10px;
background: #f9f9f9;
}
video {
background-color: #333;
border-radius: 8px;
margin: 10px 0;
width: 480px;
height: 320px;
}
audio {
margin: 10px 0;
width: 300px;
}
button {
margin: 10px;
padding: 12px 20px;
border: none;
border-radius: 25px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
}
.start-btn {
background: #4CAF50;
color: white;
}
.stop-btn {
background: #f44336;
color: white;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
.recorded-media {
margin: 15px 0;
padding: 10px;
background: white;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>Video & Audio Recorder</h1>
<div class="recorder-section" id="vid-recorder">
<h3>Record Video</h3>
<video autoplay muted id="vidBox"></video><br>
<button type="button" class="start-btn" id="video_st" onclick="startVideoRecording()">
<i class="fa fa-play"></i> Start Video
</button>
<button type="button" class="stop-btn" id="video_en" disabled onclick="stopRecording('video')">
<i class="fa fa-stop"></i> Stop Video
</button>
<div id="video-recordings"></div>
</div>
<div class="recorder-section" id="audio_rec">
<h3>Record Audio</h3>
<button type="button" class="start-btn" id="aud_st" onclick="startAudioRecording()">
<i class="fa fa-play"></i> Start Audio
</button>
<button type="button" class="stop-btn" id="aud_en" disabled onclick="stopRecording('audio')">
<i class="fa fa-stop"></i> Stop Audio
</button>
<div id="audio-recordings"></div>
</div>
<script>
let mediaRecorder;
let recordedChunks = [];
let currentStream;
async function startVideoRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
currentStream = stream;
document.getElementById('vidBox').srcObject = stream;
recordedChunks = [];
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: 'video/webm' });
createVideoElement(blob);
stopAllTracks();
};
mediaRecorder.start(100);
document.getElementById('video_st').disabled = true;
document.getElementById('video_en').disabled = false;
} catch (error) {
console.error('Error accessing video:', error);
alert('Could not access camera. Please check permissions.');
}
}
async function startAudioRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
currentStream = stream;
recordedChunks = [];
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: 'audio/webm' });
createAudioElement(blob);
stopAllTracks();
};
mediaRecorder.start(100);
document.getElementById('aud_st').disabled = true;
document.getElementById('aud_en').disabled = false;
} catch (error) {
console.error('Error accessing audio:', error);
alert('Could not access microphone. Please check permissions.');
}
}
function stopRecording(type) {
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
}
if (type === 'video') {
document.getElementById('video_st').disabled = false;
document.getElementById('video_en').disabled = true;
document.getElementById('vidBox').srcObject = null;
} else {
document.getElementById('aud_st').disabled = false;
document.getElementById('aud_en').disabled = true;
}
}
function stopAllTracks() {
if (currentStream) {
currentStream.getTracks().forEach(track => track.stop());
currentStream = null;
}
}
function createVideoElement(blob) {
const videoElement = document.createElement('video');
videoElement.controls = true;
videoElement.className = 'recorded-media';
videoElement.style.width = '400px';
videoElement.style.height = '240px';
const url = URL.createObjectURL(blob);
videoElement.src = url;
const downloadLink = createDownloadLink(blob, 'video.webm');
const container = document.createElement('div');
container.appendChild(videoElement);
container.appendChild(downloadLink);
document.getElementById('video-recordings').appendChild(container);
}
function createAudioElement(blob) {
const audioElement = document.createElement('audio');
audioElement.controls = true;
audioElement.className = 'recorded-media';
const url = URL.createObjectURL(blob);
audioElement.src = url;
const downloadLink = createDownloadLink(blob, 'audio.webm');
const container = document.createElement('div');
container.appendChild(audioElement);
container.appendChild(downloadLink);
document.getElementById('audio-recordings').appendChild(container);
}
function createDownloadLink(blob, filename) {
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = filename;
downloadLink.textContent = 'Download';
downloadLink.style.margin = '0 10px';
downloadLink.style.color = '#2196F3';
return downloadLink;
}
</script>
</body>
</html>
Key MediaRecorder API Methods
The MediaRecorder API provides these essential methods:
start()- Begins recording the media streamstop()- Stops recording and triggers theonstopeventondataavailable- Event fired when recorded data is availableonstop- Event fired when recording stops
How It Works
The recording process follows these steps:
Request Permission:
getUserMedia()asks for camera/microphone accessCreate MediaRecorder: Initialize with the media stream
Start Recording:
mediaRecorder.start()begins captureCollect Data:
ondataavailablestores chunks of recorded dataStop & Save:
onstopcreates a Blob and generates playable media
Error Handling
Always include error handling for common issues:
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
// Handle successful stream
} catch (error) {
if (error.name === 'NotAllowedError') {
console.log('User denied permission');
} else if (error.name === 'NotFoundError') {
console.log('No media devices found');
}
}
Browser Compatibility
MediaRecorder API is supported in:
Chrome 47+
Firefox 25+
Safari 14+
Edge 79+
Conclusion
The MediaRecorder API with WebRTC provides a powerful way to create audio and video recording applications directly in the browser. With proper error handling and user permission management, you can build robust media capture functionality for web applications.
