Html5
Imal Perera  

HTML5 Video + Audio Recording and Uploading

Spread the love

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

 

Leave A Comment