UNPKG

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
<!-- // Muaz Khan - www.MuazKhan.com // MIT License - www.WebRTC-Experiment.com/licence // Experiments - github.com/muaz-khan/WebRTC-Experiment --> <!DOCTYPE html> <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>