
If you need audio/screen/camera recording in a web app, RecordRTC is one of those libraries that just gets the job done. It wraps the native MediaRecorder/WebRTC bits with friendlier APIs, so you spend less time wrestling with browser quirks and more time shipping.
Project links
- GitHub: https://github.com/muaz-khan/RecordRTC
- NPM:
recordrtc
What it can do
- Microphone audio recording
- Camera or screen video recording
- Audio + video together
- Works with common containers/codecs (depends on the browser — WebM/Opus/VP8/VP9, etc.)
- Easy export as Blob/object URL, or trigger download
Quick start
Below are two official snippets from the README demonstrating Promises-style and a normal approach:
// Promises-style demo (from the official README)
let stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
let recorder = new RecordRTCPromisesHandler(stream, {
type: 'video'
});
recorder.startRecording();
const sleep = m => new Promise(r => setTimeout(r, m));
await sleep(3000);
await recorder.stopRecording();
let blob = await recorder.getBlob();
invokeSaveAsDialog(blob);
// Normal coding demo (from the official README)
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(async function(stream) {
let recorder = RecordRTC(stream, {
type: 'video'
});
recorder.startRecording();
const sleep = m => new Promise(r => setTimeout(r, m));
await sleep(3000);
recorder.stopRecording(function() {
let blob = recorder.getBlob();
invokeSaveAsDialog(blob);
});
});
Gotchas
- Permissions + HTTPS: recording needs a secure context and user consent. Safari’s MediaRecorder support is lagging — plan a fallback if targeting it.
- Container/encoding format: match the browser-supported
mimeType
.video/webm;codecs=vp8
andaudio/webm;codecs=opus
are safe choices on Chromium. - Single-channel vs stereo: stick to single-channel unless you really need stereo for smaller files.
- Long sessions: consider chunking or periodic writes to avoid massive memory blobs.
- Upload: send the Blob (multipart/form-data) and store as WebM/MP4 on the server; transcode with FFmpeg if needed.
Configuration (common options)
Each Recorder has slightly different options, but these are the ones you’ll most often tweak:
type
: a general hint for the recording type, e.g.,audio
,video
,canvas
,gif
.mimeType
: container + encoding format, e.g.:- Audio:
audio/webm;codecs=opus
,audio/ogg;codecs=opus
(depending on the browser). - Video:
video/webm;codecs=vp8
orvp9
.
- Audio:
bitsPerSecond
/videoBitsPerSecond
/audioBitsPerSecond
: bitrate; higher means larger files and better quality (up to browser limits).numberOfAudioChannels
: 1 or 2. For voice, 1 is usually enough.sampleRate
/desiredSampRate
: common sample rates are 44100/48000.timeSlice
: emit data periodically throughondataavailable
— suitable for uploading while recording.disableLogs
: suppress library logs.
RecordRTC exposes multiple Recorders. You can choose one manually or let it auto-select:
StereoAudioRecorder
(WebAudio-based) — audio-only.MediaStreamRecorder
(MediaRecorder-based) — general A/V.WhammyRecorder
— assemble frames into WebM (compatibility fallback).CanvasRecorder
— record<canvas>
.GifRecorder
— output GIF (usually larger files).
Example: chunked recording and upload (keep memory stable, suitable for retries):
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
const recorder = new RecordRTC(stream, {
type: 'audio',
mimeType: 'audio/webm;codecs=opus',
numberOfAudioChannels: 1,
timeSlice: 5000, // every 5 seconds
ondataavailable: async (blob) => {
// upload this chunk
const form = new FormData();
form.append('chunk', blob, `part-${Date.now()}.webm`);
await fetch('/upload', { method: 'POST', body: form });
}
});
recorder.startRecording();
// ... later
recorder.stopRecording(() => {
// stop tracks
stream.getTracks().forEach(t => t.stop());
});
If you need to explicitly choose a specific Recorder:
const r = new RecordRTC.StereoAudioRecorder(stream, {
mimeType: 'audio/webm',
numberOfAudioChannels: 1
});
r.record();
r.stop((blob) => { /* upload or playback */ });
Browser compatibility (quick notes)
- HTTPS & permissions:
getUserMedia
/getDisplayMedia
need a secure origin and user consent. - Chrome / Edge (Chromium): solid MediaRecorder + WebM/Opus/VP8 support; system-audio capture for screen varies by OS/browser version.
- Firefox: generally good, but some
mimeType
/bitrate combos differ from Chromium. - Safari (incl. iOS): more conservative MediaRecorder support and tighter codec/container options; iOS has extra platform limits (backgrounding, file sizes, autoplay policies).
- Screen capture:
getDisplayMedia
is widely available on modern browsers; system-audio availability depends on platform. - Download/playback: some mobile environments are picky about
blob:
URLs and autoplay — prefer user gestures for playback.
A tiny capability probe helps you fall back gracefully:
function pickSupportedMime(candidates) {
const M = window.MediaRecorder;
if (!M) return '';
return candidates.find(t => M.isTypeSupported?.(t)) || '';
}
const mime = pickSupportedMime([
'audio/webm;codecs=opus',
'audio/ogg;codecs=opus',
'audio/webm',
]);
const recorder = new RecordRTC(stream, { type: 'audio', mimeType: mime || undefined });
Where it fits
- Voice notes or video assignments in online classrooms/interviews
- Voice/video feedback inside forms or customer support widgets
- Team screen-recording helpers for quick bug reports
- Demos and repro videos for issues
Wrap-up
RecordRTC aims to make the common cases of browser recording straightforward. For many apps, that’s exactly what you need. If you later move into real-time interaction (live RTC), backend-side recording, or cloud transcoding, you can still build on top of this foundation.
Tags
Copyright Notice
This article is created by WebRTC.link and licensed under CC BY-NC-SA 4.0. This site repost articles will cite the source and author. If you need to repost, please cite the source and author.
Comments
GiscusComments powered by Giscus, based on GitHub Discussions