A cross-browser implementation to record audio/video streams:
- MediaStreamRecorder can record both audio and video in single WebM file on Firefox.
- MediaStreamRecorder can record audio as WAV and video as either WebM or animated gif on Chrome.
MediaStreamRecorder is useful in scenarios where you're planning to submit/upload recorded blobs in realtime to the server! You can get blobs after specific time-intervals.
Demos using MediaStreamRecorder.js library
Experiment Name | Demo | Source Code |
---|---|---|
Audio Recording | Demo | Source |
Video Recording | Demo | Source |
Gif Recording | Demo | Source |
There is a similar project: RecordRTC! Demo - Documentation
You can install scripts using NPM:
npm install msr
Then link single/standalone "MediaStreamRecorder.js" file:
<script src="./node_modules/msr/MediaStreamRecorder.js"> </script>
<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
To link specific files, you must download this ZIP:
<script src="/MediaStreamRecorder-v1.2.js" data-require="MediaRecorder" data-scripts-dir="/"> </script>
data-require
: Comma separated modules names. Supported values are StereoRecorder,MediaRecorder,WhammyRecorder,GifRecorder
.
// to record audio only on chrome
data-require="StereoRecorder"
// to record audio only on firefox
data-require="MediaRecorder"
// to record audio both on chrome and firefox
data-require="MediaRecorder,StereoRecorder"
// to record only video (both on chrome and firefox)
data-require="MediaRecorder,WhammyRecorder"
// to record only gif
data-require="GifRecorder"
// to record everything
data-require="StereoRecorder,MediaRecorder,WhammyRecorder,GifRecorder"
data-scripts-dir="/"
: Location of the directory where all required script files resides.
// root-directory
data-scripts-dir="/"
// sub/nested directory
data-scripts-dir="../subdir/"
// same directory where HTML-file is placed
data-scripts-dir="../"
// you can use absolute-URIs
data-scripts-dir="//cdn.webrtc-experiment.com/msr/"
You can manually link the files as well; use data-manual=true
:
<!--
This file provides public-API for all recording scenarios
You need to use "data-manual" only with this script.
-->
<script src="MediaStreamRecorder-v1.2.js" data-manual="true"> </script>
<!-- cross-browser getUserMedia/AudioContext declarations -->
<script src="../common/Cross-Browser-Declarations.js"> </script>
<!-- stores AudioContext-level objects in memory for re-usability purposes -->
<script src="../common/ObjectStore.js"> </script>
<!-- both these files are used to support audio recording in chrome -->
<script src="../AudioStreamRecorder/StereoRecorder.js"> </script>
<script src="../AudioStreamRecorder/StereoAudioRecorder.js"> </script>
<!-- this one uses MediaRecorder draft for voice & video recording (works only in Firefox) -->
<script src="../AudioStreamRecorder/MediaRecorder.js"> </script>
<!-- these files are supporting video-recording in chrome (webm) -->
<script src="../VideoStreamRecorder/WhammyRecorder.js"> </script>
<script src="../VideoStreamRecorder/WhammyRecorderHelper.js"> </script>
<script src="../VideoStreamRecorder/lib/whammy.js"> </script>
<!-- these files are used to support gif-recording in both chrome & firefox -->
<script src="../VideoStreamRecorder/GifRecorder.js"> </script>
<script src="../VideoStreamRecorder/lib/gif-encoder.js"> </script>
<!-- link either specific files -->
<script src="//cdn.webrtc-experiment.com/MediaStreamRecorder-v1.2.js" data-require="MediaRecorder" data-scripts-dir="/msr/"> </script>
<!-- or standalone file -->
<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
var mediaConstraints = {
audio: !!navigator.mozGetUserMedia, // don't forget audio!
video: true // don't forget video!
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
mediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
};
mediaRecorder.start(3000);
}
function onMediaError(e) {
console.error('media error', e);
}
mediaRecorder.stop();
<!-- link either specific files -->
<script src="//cdn.webrtc-experiment.com/MediaStreamRecorder-v1.2.js" data-require="StereoRecorder,MediaRecorder" data-scripts-dir="/msr/"> </script>
<!-- or standalone file -->
<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
var mediaConstraints = {
audio: true
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'audio/ogg';
mediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
};
mediaRecorder.start(3000);
}
function onMediaError(e) {
console.error('media error', e);
}
<!-- link either specific files -->
<script src="//cdn.webrtc-experiment.com/MediaStreamRecorder-v1.2.js" data-require="WhammyRecorder" data-scripts-dir="/msr/"> </script>
<!-- or standalone file -->
<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
var mediaConstraints = {
video: true
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
// for gif recording
// mediaRecorder.mimeType = 'image/gif';
mediaRecorder.videoWidth = 320;
mediaRecorder.videoHeight = 240;
mediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
};
mediaRecorder.start(3000);
}
function onMediaError(e) {
console.error('media error', e);
}
PHP code:
<?php
foreach(array('video', 'audio') as $type) {
if (isset($_FILES["${type}-blob"])) {
$fileName = $_POST["${type}-filename"];
$uploadDirectory = "uploads/$fileName";
if (!move_uploaded_file($_FILES["${type}-blob"]["tmp_name"], $uploadDirectory)) {
echo("problem moving uploaded file");
}
echo($uploadDirectory);
}
}
?>
JavaScript Code:
var fileType = 'video'; // or "audio"
var fileName = 'ABCDEF.webm'; // or "wav" or "ogg"
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
xhr('save.php', formData, function (fileURL) {
window.open(fileURL);
});
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
callback(location.href + request.responseText);
}
};
request.open('POST', url);
request.send(data);
}
Browser | Support |
---|---|
Firefox | Stable / Aurora / Nightly |
Google Chrome | Stable / Canary / Beta / Dev |
Opera | Stable / NEXT |
Android | Chrome / Firefox / Opera |
MediaStreamRecorder.js library is released under MIT licence.