HTML5 Video + Audio Recording and Uploading
Flash was used to do various things that client side scripting language like javascript could not do, but with the arrival of HTML5 flash was slowly starting to die, web developers started to get used to HTML5 because of a one basic thing “Flash Content require flash player to be installed in the browser”, google officially announced that they will reduce the support for flash with the upcoming releases of Android, and Apple will never going to support flash.
But Flash is still alive because there are situations which still require flash, for example hardware accessing like webcam, microphone, video streaming using RTMP etc. but however it seems like HTML5 is empowering with Hardware accessibility as well. HTML5 WebRTC is quite a hot topic these days this spec allows browser to access hardware like camera and microphone after the user permission. wonderful thing about this specification is it promises that it will work in cross devices. webRTC is still in the early stage and it require developers to do some homework before starting to use it
In this post i’m covering the usage of a pure javascript library I wrote which has the capability of recording webcam and microphone streams in the client side and upload those files to a server. if you are interested about basics of webRTC please visit here
There is only one dependency for the script
1. VideoRecorderJS.min.js
Currently only few browsers support webRTC getUsermedia spc, and this library only support for following browsers
> Microsoft Edge
> Chrome
> Firefox
> Opera
try out the code 🙂
Client Side
<html> <head> </head> <body> <div id="videorecorder"> <video id="viredemovideoele"></video> <span style="font-size:20px;" id="countdown"></span> </div> <input id="playback" value="PlayBack" type="button"/> <input id="clearrecording" value="Clear Recording" type="button"/> <input id="startRecrodBut1" value="Start Recording" type="button"/> <input id="stopRecBut1" value="Stop Recording" type="button"/> <input id="uploadrecord" value="Upload Recording" type="button"/> </br> <p id="status"></p> <video id="recordedvideo" controls></video> <audio id="audiored" controls></audio> <a id="downloadurl">Download</a> <div id="progressNumber" style="font-size:20px;"></div> <script src="../dist/VideoRecorderJS.min.js" type="text/javascript"></script> <script type="text/javascript"> var startRecord = document.getElementById("startRecrodBut1"); var stopRecord = document.getElementById("stopRecBut1"); var countdownElement = document.getElementById("countdown"); var playBackRecord = document.getElementById("playback"); var discardRecordng = document.getElementById("clearrecording"); var uploadrecording = document.getElementById("uploadrecord"); var progressNumber = document.getElementById("progressNumber"); var virec = new VideoRecorderJS.init( { resize: 0.8, // recorded video dimentions are 0.4 times smaller than the original webpquality: 0.5, // chrome and opera support webp imags, this is about the aulity of a frame framerate: 15, // recording frame rate videotagid: "viredemovideoele", videoWidth: "640", videoHeight: "480", log: true, mediaRecorderType : "webscript", workerPath : "../dist/recorderWorker.js" }, function () { //success callback. this will fire if browsers supports }, function (err) { //onerror callback, this will fire for mediaErrors if (err.name == "BROWSER_NOT_SUPPORTED") { //handler code goes here } else if (err.name == "PermissionDeniedError") { //handler code goes here } else if (err.name == "NotFoundError") { //handler code goes here } else { throw 'Unidentified Error.....'; } } ); startRecord.addEventListener("click", function () { virec.startCapture(); // this will start recording video and the audio stopCountDown(); startCountDown(); }); stopRecord.addEventListener("click", function () { /* stops the recording and after recording is finalized oncaptureFinish call back will occur */ virec.stopCapture(oncaptureFinish); stopCountDown(); }); playBackRecord.addEventListener("click", function () { /* Clientside playback, */ virec.play(); }); discardRecordng.addEventListener("click", function () { /* Clears the current recorded video + audio allowing another recording to happen */ virec.clearRecording(); stopCountDown(); }); uploadrecording.addEventListener("click", function () { /* Uploading the content to the server, here I have sliced the blobs into chunk size of 1048576 bits so that uploading time will reduce. Gmail uses this same technique when we attach some files to a mail, it slize the file in the client side and then uploads chunk by chunk */ var uploadoptions = { blobchunksize: 1048576, requestUrl: "php/fileupload.php", requestParametername: "filename", videoname: "video.webm", audioname: "audio.wav" }; virec.uploadData(uploadoptions, function (totalchunks, currentchunk) { /* This function will callback during, each successfull upload of a blob so you can use this to show a progress bar or something */ progressNumber.innerHTML = ((currentchunk / totalchunks) * 100); console.log(currentchunk + " OF " + totalchunks); }); }); //------------------------------- few functions that demo, how to play with the api -------------------------- var countdowntime = 15; var functioncalltime = 0; var timerInterval = null; function oncaptureFinish(result) { document.getElementById('status').innerHTML = ""; result.forEach(function (item) { if (item.type == "video") { var videoblob = item.blob; var videobase64 = window.URL.createObjectURL(videoblob); document.getElementById('recordedvideo').src = videobase64; document.getElementById('downloadurl').style.display = ''; document.getElementById('downloadurl').href = videobase64; document.getElementById('status').innerHTML = document.getElementById('status').innerHTML + "video=" + Math.ceil(videoblob.size / (1024)) + "KB"; } else if (item.type == "audio") { var audioblob = item.blob; document.getElementById('audiored').src = window.URL.createObjectURL(audioblob); document.getElementById('status').innerHTML = document.getElementById('status').innerHTML + "Audio=" + Math.ceil(audioblob.size / (1024)) + "KB"; } }); } function setCountDownTime(time) { countdownElement.innerHTML = time; return time; } function startCountDown() { if (timerInterval == null) { functioncalltime = countdowntime; var value = setCountDownTime(functioncalltime); timerInterval = setInterval(function () { var value = setCountDownTime(--functioncalltime); if (value == 0) { clearInterval(timerInterval); virec.stopCapture(oncaptureFinish); } }, 1000); } } function stopCountDown() { if (timerInterval) { clearInterval(timerInterval); timerInterval = null; } } </script> </body> </html>
Server Side
you can use any server side language you want, but I used php since it is more commonly used
<?php $target_path = "uploads/"; $tmp_name = $_FILES['fileToUpload']['tmp_name']; $size = $_FILES['fileToUpload']['size']; $name = $_FILES['fileToUpload']['name']; $name2 = $_GET['filename']; $target_file = $target_path.$name; $complete =$target_path.$name2; $com = fopen($complete, "ab"); error_log($target_path); $in = fopen($tmp_name, "rb"); if ( $in ) { while ( $buff = fread( $in, 1048576 ) ) { fwrite($com, $buff); } } fclose($in); fclose($com); ?>
Github : https://github.com/imalhasaranga/VideoRecorderJs