recordrtc
Version:
RecordRTC is a server-less (entire client-side) JavaScript library can be used to record WebRTC audio/video media streams. It supports cross-browser audio/video recording.
317 lines (262 loc) • 9.33 kB
HTML
<!--
// Muaz Khan - www.MuazKhan.com
// MIT License - www.WebRTC-Experiment.com/licence
// Experiments - github.com/muaz-khan/WebRTC-Experiment
-->
<html>
<head>
<meta charset="utf-8" />
<title>RecordRTC over Node.js</title>
<script>
if (location.href.indexOf('file:') == 0) {
document.write('<h1 style="color:red;">Please load this HTML file on HTTP or HTTPS.</h1>');
}
</script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<script src="https://www.webrtc-experiment.com/RecordRTC.js">
</script>
<style>
html {
background-color: #f7f7f7;
}
body {
background-color: white;
border: 1px solid rgb(15, 158, 238);
margin: 1% 35%;
text-align: center;
}
hr {
border: 0;
border-top: 1px solid rgb(15, 158, 238);
}
a {
color: #2844FA;
text-decoration: none;
}
a:hover,
a:focus {
color: #1B29A4;
}
a:active {
color: #000;
}
audio,
video {
border: 1px solid rgb(15, 158, 238);
width: 94%;
}
button[disabled],
input[disabled] {
background: rgba(216, 205, 205, 0.2);
border: 1px solid rgb(233, 224, 224);
}
</style>
</head>
<body>
<h1><a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC">RecordRTC</a> <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC/RecordRTC-to-Nodejs">over Node.js</a>
</h1>
<p>
<video></video>
</p>
<hr />
<div>
<label id="percentage">0%</label>
<progress id="progress-bar" value="0"></progress>
<br />
</div>
<hr />
<div>
<button id="btn-start-recording">Start Recording</button>
<button id="btn-stop-recording" disabled="">Stop Recording</button>
</div>
<script>
// fetching DOM references
var btnStartRecording = document.querySelector('#btn-start-recording');
var btnStopRecording = document.querySelector('#btn-stop-recording');
var videoElement = document.querySelector('video');
var progressBar = document.querySelector('#progress-bar');
var percentage = document.querySelector('#percentage');
</script>
<script>
// global variables
var currentBrowser = !!navigator.mozGetUserMedia ? 'gecko' : 'chromium';
var fileName;
var audioRecorder;
var videoRecorder;
// Firefox can record both audio/video in single webm container
// Don't need to create multiple instances of the RecordRTC for Firefox
// You can even use below property to force recording only audio blob on chrome
// var isRecordOnlyAudio = true;
var isRecordOnlyAudio = !!navigator.mozGetUserMedia;
// if recording only audio, we should replace "HTMLVideoElement" with "HTMLAudioElement"
if (isRecordOnlyAudio && currentBrowser == 'chromium') {
var parentNode = videoElement.parentNode;
parentNode.removeChild(videoElement);
videoElement = document.createElement('audio');
videoElement.style.padding = '.4em';
videoElement.controls = true;
parentNode.appendChild(videoElement);
}
</script>
<script>
// reusable helpers
// this function submits both audio/video or single recorded blob to nodejs server
function postFiles(audio, video) {
// getting unique identifier for the file name
fileName = generateRandomString();
// this object is used to allow submitting multiple recorded blobs
var files = {};
// recorded audio blob
files.audio = {
name: fileName + '.' + audio.blob.type.split('/')[1],
type: audio.blob.type,
contents: audio.dataURL
};
if (video) {
files.video = {
name: fileName + '.' + video.blob.type.split('/')[1],
type: video.blob.type,
contents: video.dataURL
};
}
files.uploadOnlyAudio = !video;
videoElement.src = '';
videoElement.poster = '/ajax-loader.gif';
xhr('/upload', JSON.stringify(files), function(_fileName) {
var href = location.href.substr(0, location.href.lastIndexOf('/') + 1);
videoElement.src = href + 'uploads/' + _fileName;
videoElement.play();
videoElement.muted = false;
videoElement.controls = true;
var h2 = document.createElement('h2');
h2.innerHTML = '<a href="' + videoElement.src + '">' + videoElement.src + '</a>';
document.body.appendChild(h2);
});
if (mediaStream) mediaStream.stop();
}
// XHR2/FormData
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback(request.responseText);
}
};
request.upload.onprogress = function(event) {
progressBar.max = event.total;
progressBar.value = event.loaded;
progressBar.innerHTML = 'Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%";
};
request.upload.onload = function() {
percentage.style.display = 'none';
progressBar.style.display = 'none';
};
request.open('POST', url);
request.send(data);
}
// generating random string
function generateRandomString() {
if (window.crypto) {
var a = window.crypto.getRandomValues(new Uint32Array(3)),
token = '';
for (var i = 0, l = a.length; i < l; i++) token += a[i].toString(36);
return token;
} else {
return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
}
}
// when btnStopRecording is clicked
function onStopRecording() {
audioRecorder.getDataURL(function(audioDataURL) {
var audio = {
blob: audioRecorder.getBlob(),
dataURL: audioDataURL
};
// if record both wav and webm
if (!isRecordOnlyAudio) {
videoRecorder.getDataURL(function(videoDataURL) {
var video = {
blob: videoRecorder.getBlob(),
dataURL: videoDataURL
};
postFiles(audio, video);
});
}
// if record only audio (either wav or ogg)
if (isRecordOnlyAudio) postFiles(audio);
});
}
</script>
<script>
var mediaStream = null;
// reusable getUserMedia
function captureUserMedia(success_callback) {
var session = {
audio: true,
video: true
};
navigator.getUserMedia(session, success_callback, function(error) {
alert(JSON.stringify(error));
});
}
</script>
<script>
// UI events handling
btnStartRecording.onclick = function() {
btnStartRecording.disabled = true;
captureUserMedia(function(stream) {
mediaStream = stream;
videoElement.src = window.URL.createObjectURL(stream);
videoElement.play();
videoElement.muted = true;
videoElement.controls = false;
// it is second parameter of the RecordRTC
var audioConfig = {};
if (!isRecordOnlyAudio) {
audioConfig.onAudioProcessStarted = function() {
// invoke video recorder in this callback
// to get maximum sync
videoRecorder.startRecording();
};
}
audioRecorder = RecordRTC(stream, audioConfig);
if (!isRecordOnlyAudio) {
// it is second parameter of the RecordRTC
var videoConfig = {
type: 'video'
};
videoRecorder = RecordRTC(stream, videoConfig);
}
audioRecorder.startRecording();
// enable stop-recording button
btnStopRecording.disabled = false;
});
};
btnStopRecording.onclick = function() {
btnStartRecording.disabled = false;
btnStopRecording.disabled = true;
if (isRecordOnlyAudio) {
audioRecorder.stopRecording(onStopRecording);
}
if (!isRecordOnlyAudio) {
audioRecorder.stopRecording(function() {
videoRecorder.stopRecording(function() {
onStopRecording();
});
});
}
};
</script>
<script>
window.onbeforeunload = function() {
startRecording.disabled = false;
};
</script>
<footer style="width:100%;position: fixed; right: 0; text-align: center;color:red;">
<a href="https://www.WebRTC-Experiment.com">www.WebRTC-Experiment.com</a>
</footer>
</body>
</html>