Using JavaScript to control the HTML5 video player

The HTML5 video object provides methods, properties, and events that you can use to control playback from JavaScript.

  • How do I make my own buttons?
  • Can I play this format?
  • How can I change files?
  • What if something goes wrong?
  • What else can I do with video properties?
  • Related topics

The HTML5 video element as described in Adding an HTML5 video control to your webpage, gets you started using video elements on your webpages. With the addition of JavaScript, you can programmatically create custom playback controls, get and set the current playing position, and change the current video. Here we talk about some of the basic methods and properties that you can use to control the video object.

How do I make my own buttons?

The HTML5 video element has its own built-in controls to play, pause, and seek the video playback. The following example uses the play and pause methods to start and stop the video, the currentTime property to seek within the video, and the paused property to get the current playing state of the video player.

<script type="text/javascript">

    function vidplay() {
       var video = document.getElementById("Video1");
       var button = document.getElementById("play");
       if (video.paused) {
          video.play();
          button.textContent = "||";
       } else {
          video.pause();
          button.textContent = ">";
       }
    }

    function restart() {
        var video = document.getElementById("Video1");
        video.currentTime = 0;
    }

    function skip(value) {
        var video = document.getElementById("Video1");
        video.currentTime += value;
    }      
</script>

</head>
<body>        

<video id="Video1" >
//  Replace these with your own video files. 
     <source src="demo.mp4" type="video/mp4" />
     <source src="demo.ogv" type="video/ogg" />
     HTML5 Video is required for this example. 
     <a href="demo.mp4">Download the video</a> file. 
</video>

<div id="buttonbar">
    <button id="restart" onclick="restart();">[]</button> 
    <button id="rew" onclick="skip(-10)">&lt;&lt;</button>
    <button id="play" onclick="vidplay()">&gt;</button>
    <button id="fastFwd" onclick="skip(10)">&gt;&gt;</button>
</div>         

This example uses the HTML5 video element with the source element to set up the player and video content on the webpage. The video element has only an id attribute, leaving the playback control to the buttons and JavaScript functions. The buttons provide play/pause, skip forward and back, and restart control of the video.

The Play is also the Pause button. Rather than have separate buttons, the Play button's text changes to reflect the function. When you click the Play button, it calls the "vidplay()" function, which checks the paused property. The paused property returns true when a video is paused (or has just loaded), and false when a video is playing. If the video is paused, the "vidplay()" calls the play method, and changes the Play button's innerHTML to "||", the symbol for "pause." If the video is playing when the Play button is clicked, the pause method is called and the innerHTML changes to ">", the symbol for "play."

The Restart ("[]"), Back ("<<"), and Forward (>>) buttons all use the currentTime property. The currentTime property represents the current playback position in seconds. The Play and Forward buttons call the "skip()" function. The "skip()" function takes a parameter that either adds or subtracts 10 seconds from the current time. If you set the currentTime to a value of either less than zero, or greater than the duration of the video, the video player will set it to the beginning or end of the video. The restart ("[]") button calls the" restart()" function, which simply sets currentTime to zero.

Can I play this format?

Figuring out which format to use from JavaScript is a little more complicated than using the source element as shown in Adding an HTML5 video control to your webpage. However, because the video element's support won't change, after you determine what support is available, you can make format assumptions for the rest of the browsing session.

To find a browser's format capabilities, the video object's canPlayType method is used. The canPlayType method takes a video mime type, and an optional codec parameter, and returns one of three strings: "empty", "maybe", or "probably".

  if (myvideo.canPlayType) {
    // CanPlayType returns maybe, probably, or an empty string.
    var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
    if ("" != playMsg) {
      msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
    }
    playMsg = myvideo.canPlayType('video/ogg; codecs="theora"');
    if ("" != playMsg) {
      msg.innerHTML += "ogg is " + playMsg + " supported<br/>";
    }
    playMsg = myvideo.canPlayType('video/webm; codecs="vp8, vorbis"');
    if ("" != playMsg) {
      msg.innerHTML += "webm is " + playMsg + " supported<br/>";
    }
  }
  else {
    msg.innerHTML += "no video support";
  }
}

The difference between "maybe" and "probably" is often that the canPlayType method doesn't have enough information. For example, if the codecs parameter is missing, the method can return a "maybe" for mp4 support. This is because there might be mp4 codecs that aren't supported. The codecs parameter narrows the support to a more specific version of mp4 files.

This vagueness of the three states that the canPlayType method returns can make it challenging to determine whether a browser supports the file format. While not the rule, if a browser returns "maybe", it often can support it. The following statements return either a Boolean true if the returned string is "maybe", or "probably", or false if the string is empty.

var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
if ("" != playMsg) {
  msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
}

The first line in the previous example calls the canPlayType method with the parameter "video/mp4; codecs="avc1.42E01E"". The "if" statement then checks to see if the result is anything other than an empty string. If it is, it then displays the message and result.

This next example tests for three video formats, mp4, ogv, and webm.

<!doctype html>
<html>
<head>
    <title>Using multiple file formats in JavaScript</title>
    <!-- Uncomment the following meta tag if you have issues rendering this page on an intranet site. -->    
    <!--  <meta http-equiv="X-UA-Compatible" content="IE=edge"/> --> 
</head>
<body>
  <h1>CanPlayType test for multiple files</h1>
    <div>The canPlayType method tests for specific video formats and codecs. <br />It returns probably, maybe, or an empty string (no support).</div> 
    <br />
    <div>
        <button onclick="checkVideoCompat();">
            Test for video format type
        </button>
    </div>
    <div id="display"> </div>

    <script type= "text/javascript">
      function checkVideoCompat() {
        var myvideo = document.createElement('video');
        var msg = document.getElementById("display");
        msg.innerHTML = "";
        if (myvideo.canPlayType) {
          // CanPlayType returns maybe, probably, or an empty string.
          var playMsg = myvideo.canPlayType('video/mp4; codecs="avc1.42E01E"');
          if ("" != playMsg) {
            msg.innerHTML += "mp4/H.264 is " + playMsg + " supported <br/>";
          }
          playMsg = myvideo.canPlayType('video/ogg; codecs="theora"');
          if ("" != playMsg) {
            msg.innerHTML += "ogg is " + playMsg + " supported<br/>";
          }
          playMsg = myvideo.canPlayType('video/webm; codecs="vp8, vorbis"');
          if ("" != playMsg) {
            msg.innerHTML += "webm is " + playMsg + " supported<br/>";
          }
        }
        else {
          msg.innerHTML += "no video support";
        }
      }
    </script>


</body>
</html>

When you use HTML5 elements and features in Windows Internet Explorer, it's a good best practice to test for the features you use. In this example, the createElement method is used to create a video object. If the video object was created successfully, the statement "if (myvideo.canPlayType)" returns true, and the execution continues to test for specific file types.

How can I change files?

In the previous examples, the video source file is specified by using the source tag in the HTML portion of the code. To play more than just that one file, you can use the src property to specify a URL of a video file with JavaScript.

In this example, the src property is set to the value of text input field. You can type or paste a URL of a compatible video file into the field, and then click the Load button.

<div id= "inputField" style="display:none;" >
    <input type="text" id="videoFile" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
    <button id="loadVideo" >Load</button>
</div>

When the Load button is clicked, the "getVideo()" function gets the value from the input field (URL), and assigns it to the src property. The "getVideo()" function then calls the click method on the "play" button so the file starts playing.

                //  load video file from input field
                function getVideo() {
                    var fileURL = document.getElementById("videoFile").value;  // get input field                    
                    if (fileURL != ""){
                       video.src = fileURL;
                       video.load();  // if HTML source element is used
                       document.getElementById("play").click();  // start play
                     } else {
                        errMessage("Enter a valid video URL");  // fail silently
                     }
                }

When you click the Play button, it calls the "vidplay()" function to play or pause. Unlike the previous example where it only had a single file to play set by the source element, "vidplay()" first checks the src property. If it's empty, as it would be when the page first loads, the "getVideo()" function is called to load the URL from the text field. The "getVideo()" gets the URL from the input field, calls the load video method, and then fires the play button's click event, which plays the file. If the page is already playing a video, and a new file is pasted into the input field, click the load button to change files.

                 //  play video
                 function vidplay(evt) {
                    if (video.src == "") {  // on first run, src is empty, go get file
                        getVideo();
                    }
                    button = evt.target; //  get the button id to swap the text based on the state                                    
                    if (video.paused) {   // play the file, and display pause symbol
                       video.play();
                       button.textContent = "||";
                    } else {              // pause the file, and display play symbol  
                       video.pause();
                       button.textContent = ">";
                    }                                        
                }

In the following example, the body element's onload event is used to call the "init()" function, which encapsulates all the functionality of the example.

<script type="text/javascript">
    // Master function, encapsulates all functions
    function init() {
        var video = document.getElementById("Video1");                                               
        if (video.canPlayType) {   // tests that we have HTML5 video support
            // if successful, display buttons and set up events
            document.getElementById("buttonbar").style.display = "block";
            document.getElementById("inputField").style.display = "block";

            //  button events
            //  Play
            document.getElementById("play").addEventListener("click", vidplay, false);
            //  Restart
            document.getElementById("restart").addEventListener("click", function(){
                setTime(0);
             }, false);
            //  Skip backward 10 seconds
            document.getElementById("rew").addEventListener("click", function(){
                setTime(-10);                
            }, false);
            //  Skip forward 10 seconds
            document.getElementById("fwd").addEventListener("click", function(){
                setTime(10);
            }, false);                
            //  set src == latest video file URL
            document.getElementById("loadVideo").addEventListener("click", getVideo, false);
                            
            // fail with message 
            video.addEventListener("error", function(err) {
                errMessage(err);
            }, true);

            //  button helper functions 
            //  skip forward, backward, or restart
            function setTime(tValue) {
            //  if no video is loaded, this throws an exception 
                try {
                    if (tValue == 0) {
                        video.currentTime = tValue;
                    }
                    else {
                        video.currentTime += tValue;
                    }
                    
                 } catch (err) {
                     // errMessage(err) // show exception
                 errMessage("Video content might not be loaded");
                   }
         }
             //  play video
             function vidplay(evt) {
                if (video.src == "") {  // on first run, src is empty, go get file
                    getVideo();
                }
                button = evt.target; //  get the button id to swap the text based on the state                                    
                if (video.paused) {   // play the file, and display pause symbol
                   video.play();
                   button.textContent = "||";
                } else {              // pause the file, and display play symbol  
                   video.pause();
                   button.textContent = ">";
                }                                        
            }
            //  load video file from input field
            function getVideo() {
                var fileURL = document.getElementById("videoFile").value;  // get input field                    
                if (fileURL != ""){
                   video.src = fileURL;
                   video.load();  // if HTML source element is used
                   document.getElementById("play").click();  // start play
                 } else {
                    errMessage("Enter a valid video URL");  // fail silently
                 }
            }
            //  display an error message 
            function errMessage(msg) {
            // displays an error message for 5 seconds then clears it
                document.getElementById("errorMsg").textContent = msg;
                setTimeout("document.getElementById('errorMsg').textContent=''", 5000);
            }

        } // end of runtime
    }// end of master         
</script>

</head>
<body onload="init();">        

<video id="Video1" style="border: 1px solid blue;" height="240" width="320">      
     HTML5 Video is required for this example
</video>

<div id="buttonbar" style="display: none;")>
    <button id="restart" >[]</button> 
    <button id="rew" >&lt;&lt;</button>
    <button id="play">&gt;</button>
    <button id="fwd" >&gt;&gt;</button>
</div>     
<div id= "inputField" style="display:none;" >
    <input type="text" id="videoFile" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
    <button id="loadVideo" >Load</button>
</div>
<div id="errorMsg" style="color:Red;" ></div>

This example uses JavaScript addEventListener methods to provide click handlers for the buttons, rather than onclick events on each button element in HTML. The Rewind, Forward, and Restart buttons, each call the "setTime()" function, which sets the currentTime video property based on the value passed. The Play button calls the "vidplay()" function to play the file.

Note  

If you paste a video link from an online video site, be sure it's an actual video file (has an .mp4, .ogv, or similar extension). There are many sources for test video files on the web, but some websites provide URLs that are searches, rather than links to files.

 

What if something goes wrong?

Writing error-free code is difficult. This example includes areas designed to avoid or catch errors. When the example runs, the buttons are not displayed if HTML5 video support doesn't exist. However, if video is supported, some actions do throw exceptions. See Using HTML5 video events for an example that uses the oncanplay event to prevent the buttons from being used until video content is loaded.

One action that causes an exception is setting the currentTime property when no video is loaded. In the previous example, the "setTime()" function code is executed in a try/catch block that displays an error message if an exception is thrown. In the example, a helpful message is displayed, but you can remove the comment for the raw exception display instead.

   //  skip forward, backward, or restart
   function setTime(tValue) {
   //  if no video is loaded, this throws an exception 
       try {
           if (tValue == 0) {
               video.currentTime = tValue;
           }
           else {
               video.currentTime += tValue;
           }
           
        } catch (err) {
            // errMessage(err) // show exception
        errMessage("Video content might not be loaded");
          }
}

Note  F12 developer tools lets your report back from specific areas of your code for debugging by letting you send messages to the F12 toolsConsole or Script tab. When you send messages to the console, it doesn't interrupt the code execution like calls to the alert method do. To debug pages when creating Windows Store apps using JavaScript, use Microsoft Visual Studio . For more info about using the F12 tools console, see How to use the F12 Developer Tools.

 

What else can I do with video properties?

The video properties playbackRate, volume, and muted let you add playback speed control and volume control of the soundtrack. The following example adds buttons to increase and decrease the playback rate to get an old time movie look, or a slow motion playback. There are also buttons to change the volume or mute the audio track completely.

// volume buttons
document.getElementById("volDn").addEventListener("click", function () {
    setVol(-.1); // down by 10%
}, false);
document.getElementById("volUp").addEventListener("click", function () {
    setVol(.1);  // up by 10%
}, false);

// playback speed buttons
document.getElementById("slower").addEventListener("click", function () {
    video.playbackRate -= .25;
}, false);
document.getElementById("faster").addEventListener("click", function () {
    video.playbackRate += .25;
}, false);
document.getElementById("normal").addEventListener("click", function () {
    video.playbackRate = 1;
}, false);
document.getElementById("mute").addEventListener("click", function (evt) {
    if (video.muted) {
        video.muted = false;
        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
    } else {
        video.muted = true;
        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
    }
}, false);

The playbackRate property represents a multiplier of the video's intrinsic or normal playback rate, with the default setting of 1. If you set the property to 2, it doubles the playback speed, while .5 will play at half speed. If playbackRate is set to a negative value, in Windows Internet Explorer 9, it rounds it back to zero, essentially pausing playback. In Internet Explorer 10, negative values for playbackRate cause the video to play in reverse. The W3C spec doesn't recommend an upper limit, but Internet Explorer limits playbackRate up to 8x speed.

The volume property lets you control the volume of the video's soundtrack. The volume property accepts floating point values from 0 to 1. The volume property must be between 0 and 1 or it throws an exception. The following example shows one way to set the volume property without throwing an exception. The volume function adds the passed in value of .1, or 10% (positive or negative) to the current volume. If the value is outside the allow range of 0-1, it is set to the closest allowed value to avoid the exception.

// change volume based on incoming value 
function setVol(value) {
    var vol = video.volume;
    vol += value;
    //  test for range 0 - 1 to avoid exceptions
    if (vol >= 0 && vol <= 1) {
        // if valid value, use it
        video.volume = vol;
    } else {
        // otherwise substitute a 0 or 1
        video.volume = (vol < 0) ? 0 : 1;                        
    }
}

The muted property immediately quiets the soundtrack when set to true, or restores the soundtrack to the volume level set by the volume property when false. The following example shows the Mute button event handler that toggles the muted property, and switches the image the button displays.

document.getElementById("mute").addEventListener("click", function (evt) {
    if (video.muted) {
        video.muted = false;
        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
    } else {
        video.muted = true;
        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
    }
}, false);

The following is the complete code listing of all previous examples:

<html >
  <head>
    <title>Full player example</title>
    <!-- Uncomment the following meta tag if you have issues rendering this page on an intranet or local site. -->    
    <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"/> -->

    <script type="text/javascript">
        function init() {        // Master function, encapsulates all functions
            var video = document.getElementById("Video1");                                               
            if (video.canPlayType) {   // tests that we have HTML5 video support
                // if successful, display buttons and set up events
                document.getElementById("buttonbar").style.display = "block";                
                document.getElementById("inputField").style.display = "block";

                // helper functions
                //  play video
                function vidplay(evt) {
                    if (video.src == "") {  // inital source load
                        getVideo();
                    }
                    button = evt.target; //  get the button id to swap the text based on the state                                    
                    if (video.paused) {   // play the file, and display pause symbol
                        video.play();
                        button.textContent = "||";
                    } else {              // pause the file, and display play symbol  
                        video.pause();
                        button.textContent = ">";
                    }
                }
                //  load video file from input field
                function getVideo() {
                    var fileURL = document.getElementById("videoFile").value;  // get input field                    
                    if (fileURL != "") {
                        video.src = fileURL;
                        video.load();  // if HTML source element is used
                        document.getElementById("play").click();  // start play
                    } else {
                        errMessage("Enter a valid video URL");  // fail silently
                    }
                }



                //  button helper functions 
                //  skip forward, backward, or restart
                function setTime(tValue) {
                //  if no video is loaded, this throws an exception 
                    try {
                        if (tValue == 0) {
                            video.currentTime = tValue;
                        }
                        else {
                            video.currentTime += tValue;
                        }
                        
                     } catch (err) {
                         // errMessage(err) // show exception
                     errMessage("Video content might not be loaded");
                       }
             }
                //  display an error message 
                function errMessage(msg) {
                // displays an error message for 5 seconds then clears it
                    document.getElementById("errorMsg").textContent = msg;
                    setTimeout("document.getElementById('errorMsg').textContent=''", 5000);
                }
                // change volume based on incoming value 
                function setVol(value) {
                    var vol = video.volume;
                    vol += value;
                    //  test for range 0 - 1 to avoid exceptions
                    if (vol >= 0 && vol <= 1) {
                        // if valid value, use it
                        video.volume = vol;
                    } else {
                        // otherwise substitute a 0 or 1
                        video.volume = (vol < 0) ? 0 : 1;                        
                    }
                }
                //  button events               
                //  Play
                document.getElementById("play").addEventListener("click", vidplay, false);
                //  Restart
                document.getElementById("restart").addEventListener("click", function () {
                    setTime(0);
                }, false);
                //  Skip backward 10 seconds
                document.getElementById("rew").addEventListener("click", function () {
                    setTime(-10);
                }, false);
                //  Skip forward 10 seconds
                document.getElementById("fwd").addEventListener("click", function () {
                    setTime(10);
                }, false);
                //  set src == latest video file URL
                document.getElementById("loadVideo").addEventListener("click", getVideo, false);

                // fail with message 
                video.addEventListener("error", function (err) {
                    errMessage(err);
                }, true);
                // volume buttons
                document.getElementById("volDn").addEventListener("click", function () {
                    setVol(-.1); // down by 10%
                }, false);
                document.getElementById("volUp").addEventListener("click", function () {
                    setVol(.1);  // up by 10%
                }, false);

                // playback speed buttons
                document.getElementById("slower").addEventListener("click", function () {
                    video.playbackRate -= .25;
                }, false);
                document.getElementById("faster").addEventListener("click", function () {
                    video.playbackRate += .25;
                }, false);
                document.getElementById("normal").addEventListener("click", function () {
                    video.playbackRate = 1;
                }, false);
                document.getElementById("mute").addEventListener("click", function (evt) {
                    if (video.muted) {
                        video.muted = false;
                        evt.target.innerHTML = "<img alt='volume on button' src='vol2.png' />"
                    } else {
                        video.muted = true;
                        evt.target.innerHTML = "<img alt='volume off button' src='mute2.png' />"
                    }
                }, false);
            } // end of runtime
        }// end of master         
    </script>
    
    </head>
    <body onload="init();" >        
    
    <video id="Video1" controls style="border: 1px solid blue;" height="240" width="320" title="video element">            
         HTML5 Video is required for this example
    </video>
    
    <div id="buttonbar" style="display: none;")>
        <button id="restart" title="Restart button">[]</button> 
        <button id="slower" title="Slower playback button">-</button> 
        <button id="rew" title="Rewind button" >&lt;&lt;</button>
        <button id="play" title="Play button">&gt;</button>
        <button id="fwd" title="Forward button" >&gt;&gt;</button>
        <button id="faster" title="Faster playback button">+</button>
        <button id="Button2" title="Mute button" ><img alt="Volume on button" src="vol2.png" /></button>     
        <br />
        <label>Playback </label>
            <label>Reset playback rate: </label><button id="normal" title="Reset playback rate button">=</button>    
        
        <label>  Volume </label>
            <button id="volDn"  title="Volume down button">-</button>
            <button id="volUp"  title="Volume up button">+</button>
            <button id="mute" title="Mute button" ><img alt="Volume on button" src="vol2.png" /></button>        
    </div>   
    <br/>  
    <div id= "inputField" style="display:none;" >
        <label>Type or paste a video URL: <br/>
        <input type="text" id="videoFile" style="width: 300px;"  title="video file input field" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />        
        <button id="loadVideo" title="Load video button" >Load</button>
        </label>
    </div>
    <div title="Error message area" id="errorMsg" style="color:Red;"></div>  
    </body>
</html>

In Using HTML5 video events, you'll see how to use events to check whether content is available, the state of video playback, and how to monitor the current playing position in a video.

Adding an HTML5 video control to your webpage

F12 Developer Tools Guide

Using HTML5 video events

How to use HTML5 to Add an Audio Player to your Webpage

Video object