14 - Phonegap Multimedia - Control Audio and Video with JavaScript

Introduction

We can control the media files we embed using HTML5 elements, that is <audio> and <video> elements, with the help of JavaScript. In other words, JavaScript allows you to develop custom controls instead of using built-in controls. In this tutorial, we will create an app that handles a video using custom controls. As the API of both audio and video are identical, you can control an audio exactly same as controlling a video.

Create an App

Create an iOS mobile app named iOSControlVideo on the desktop. Once the project is created on the desktop, open the folder and double click the iOSControlVideo.xcodeproj icon to launch the project in the XCode environment. Again go back to the project folder on the desktop, open the index.html file inside the www folder using your favourite text editor and clean it up. Change the title to “Control Video”.

Download and keep an .mp4 file in the www folder of your project. Add the following lines of code inside the <body> tag.       

         <video id="song" width="500" height="500">
            <source src="myVideo.mp4" type="video/mp4" />           
         </video><br />
         <button id="btnPlay">Play</button>
         <button id="btnPause">Pause</button>
         <button id="btnStop">Stop</button><br/>

The name of my file is myVideo.mp4. We are going to use the three buttons, Play, Pause and Stop to play, pause and stop the video respectively.

Add the following lines of code inside the <head> section to check whether the device is ready. Once the device is ready, we will add the event listeners for the three buttons for their click events.

<script>
        window.onload = function()
        {
            document.addEventListener("deviceready", init, false);
        }
        function init()
        {
            document.getElementById("btnPlay").addEventListener('click', playVideo, false);
            document.getElementById("btnPause").addEventListener('click', pauseVideo, false);
            document.getElementById("btnStop").addEventListener('click', stopVideo, false);
        }
</script>

Next we have to write the playVideo, pauseVideo and stopVideo functions. We need the <video> element in different functions. So, add the following line of code just below the starting <script> tag to make it a global variable.   

       var myMedia;    

Next, add the following line of code inside the init function.

       myMedia = document.getElementById('song');

myMedia = document.getElementById('song');

Now you can call the play and pause methods inside proper functions easily. Add the following lines of code after the init function.

        function playVideo()
        {
            myMedia.play();
        }
        function pauseVideo()
        {
            myMedia.pause();
        }
        function stopVideo()
        {
            myMedia.pause();
            myMedia.currentTime = 0;
        }        

In fact, HTML5 video/audio API does not provide a stop method. But it has a property called currentTime to set or get the current playback position in the audio/video. Thus, to stop a video, we pause the video first using the pause method and then set its current playback position to 0, that is the beginning. So, in effect, the video will be stopped and started from the beginning.

This time, I am planning to test it from a local browser. How can you make your index.html file ready to test on a local browser? You just have to remove the line that checks whether the device is ready. Modify the anonymous function invoked on window.onload like this:

window.onload = function()
        {
            // document.addEventListener("deviceready", init, false);
            init();
        }       

I have called the init function directly from the anonymous function. Save the index.html file. Open it with your local browser. You will see your video and three buttons Play, Pause and Stop below the video. Try clicking the buttons to play, pause and stop the video.

Next let us add a control that shows the current position of the video, as you see in normal video files. Of course, it is a slider that moves automatically as the video continues. How will we update the position of the slider? We are going to use JavaScript's setInterval method to update the slider in regular intervals. We need to pass the name of the function that needs to be executed at regular intervals as the first parameter and the interval in milliseconds on how often the function needs to be called as the second parameter of the setInterval method. We are using a <range> element to display the position. Add the following line of code just below the Stop button inside the <body>

       Position: <input type="range" id="position" min="0" value="0" /><br />

The value of the max attribute will be the length of the video. We do not know it at this point of time. So, we will set the value of max using JavaScript. It should be positioned at 0 when the page loads: that is why we have set 0 to the value attribute.

As explained before, the setInterval method acts like a timer; it executes a specified function at specified intervals. In fact, this method uses our system resources continuously to execute the function until we clear this timer. So, clearing the timer as and when we are done with it is highly recommended. We need to have a global variable, say myPosition, to set the value returned by the setInterval method and later to pass as an argument to the clearInterval method. So, add the following line of code just below the starting <script> tag to make it a global variable.

       var myPosition;

Add the following line of code inside the init function to set the max value (maximum length) of the position slider.

       document.getElementById('position').max = myMedia.duration;

Add the following line of code that creates a timer using the setInterval method inside the play() function.

       myPosition = setInterval(updatePosition, 100);

Next we need to write the updatePosition function. This function will just update the position of the slider. Add the following lines of code after the stopVideo function.

function updatePosition()
        {
            document.getElementById('position').value = myMedia.currentTime;
        }

In effect, the updatePosition function will be executed every 100 milliseconds once the Play button is clicked. As we discussed before, we should clear the timer when we do not need it. We do not have to update the position when the video is stopped or paused. So, add the following line of code inside both pauseVideo method and stopVideo method.

       clearInterval(myPosition);

Save the index.html file and open it using your browser. You will see a slider below the three buttons which moves when the video is playing.

Let us also add two more sliders to increase or decrease the volume and speed of the video. We will be using the volume and playbackRate properties of the video API to change the volume and speed. Add the following lines of code just below the position slider inside the <body> section.

- Volume + <input type="range" id="volume" min="0" max="1" step=".1" value="1" /><br />
- Speed + <input type="range" id="speed" min="0" max="2" step=".2" value="1" />

Add the following lines of code inside the init function to add event listeners for sliders’ change events.

document.getElementById("speed").addEventListener('change', updateSpeed, false);
document.getElementById("volume").addEventListener('change', updateVolume, false);

Next we have to write updateSpeed and updateVolume functions. We will just get the value of the corresponding sliders and set the value of playbackRate and volume. Add the following lines of code inside the <script>.

        function updateSpeed()
        {
            var currentSpeed = document.getElementById('speed').value;
            myMedia.playbackRate = currentSpeed;
        }
        function updateVolume()
        {
            var currentVolume = document.getElementById('volume').value;
            myMedia.volume = currentVolume;
        }  

Save the index.html file and open the file using your browser. You can try changing the volume and speed sliders to see how it affects the video. If you want to check this app on your iOS simulator, you just need to remove the comment inside the anonymous function and run the project from the XCode environment.

I know we have done a lot of things in this tutorial. To make sure that you wrote the code correctly, cross check it with the complete index.html code given below.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <script type="text/javascript" src="cordova.js"></script>
        <title>Control Video</title>
        <script>
        var myPosition;
        var myMedia;
        window.onload = function()
        {
            //document.addEventListener("deviceready", onDeviceReady, false);
            init();
        }
        function init()
        {
             myMedia = document.getElementById('song');
             document.getElementById("btnPlay").addEventListener('click', playVideo, false);
             document.getElementById("btnPause").addEventListener('click', pauseVideo, false);
             document.getElementById("btnStop").addEventListener('click', stopVideo, false);
             document.getElementById("speed").addEventListener('change', updateSpeed, false);
             document.getElementById("volume").addEventListener('change', updateVolume, false);
            document.getElementById('position').max = myMedia.duration;
       }
       function playVideo()
        {
            myMedia.play();
            myPosition = setInterval(updatePosition, 100);
        }
        function pauseVideo()
        {
            myMedia.pause();
            clearInterval(myPosition);
        }
        function stopVideo()
        {
            myMedia.pause();
            myMedia.currentTime = 0;
            clearInterval(myPosition);
        }
        function updatePosition()
        {
            document.getElementById('position').value = myMedia.currentTime;
        }
        function updateSpeed()
        {
            var currentSpeed = document.getElementById('speed').value;
            myMedia.playbackRate = currentSpeed;
        }
        function updateVolume()
        {
            var currentVolume = document.getElementById('volume').value;
            myMedia.volume = currentVolume;
        }
        </script>
    </head>
    <body>
        <video id="song" width="500" height="500">
            <source src="myVideo.mp4" type="video/mp4" />           
        </video><br />
        <button id="btnPlay">Play</button>
        <button id="btnPause">Pause</button>
        <button id="btnStop">Stop</button><br />
        Position: <input type="range" id="position" min="0" value="0" /><br />
        - Volume + <input type="range" id="volume" min="0" max="1" step=".1" value="1" /><br />
        - Speed + <input type="range" id="speed" min="0" max="2" step=".2" value="1" />
    </body>
</html>

Summary

In this tutorial, we have seen how we can control a video file using JavaScript. That is, we have developed our own custom controls to handle the video, instead of using the built-in controls. We can use the same methods to handle an audio file as well because the both the video and audio APIs are exactly the same. In addition to these custom controls, you can also develop controls to mute/unmute, jump to a specific position, repeat the audio/video again and again and so on. In short, use of JavaScript provides you lot more control over the media compared to built-in controls.

Like us on Facebook