Creating a Custom HTML5 Video Player

Now most people looking to build an HTML5 video player can get away with a basic player or use a simple service like Vimeo to show their content. I've covered the different ways to display your video online here and I recommend giving it a read first.

This is going to cover how to make sure you're videos never preload in any browser, using javascript to pause and play your videos, and how to use Flowplayer and the Flowplayer API to play and pause your flash fallback using javascript.

I'll be using jQuery for this demonstration.

Your Basic HTML5 Player

If you only have one video this should work just fine for you:


<video id="example_video_1"  class="video-js" width="525" height="296" poster="poster.jpg" controls >
  <source src="test.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
  <source src="test.webm" type='video/webm; codecs="vp8, vorbis"' />
  <source src="test.ogv" type='video/ogg; codecs="theora, vorbis"' />
<!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. -->
<object id="flash_fallback_1" class="vjs-flash-fallback" width="525" height="296" type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
  <param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
  <param name="allowfullscreen" value="true" />
  <param name="wmode" value="opaque" />
  <param name="flashvars" value="config={"playlist":["poster.jpg", {"url": "http:/absolute_pate.com/test.m4v","autoPlay":false,"autoBuffering":true}]}" />
<!-- Image Fallback. Typically the same as the poster image. -->
  <img src="poster.jpg" width="525" height="296" alt="Poster Image" title="No video playback capabilities." />
</object>
</video>

The only issues with this player is that it will preload in safari which slows the page load. So what we are going to do, is we going to remove the HTML5 video and replace an image with the video player when click using javascript.

First, we just have an image.


<div class="video_box" >
  <img src="poster.jpg" width="525" height="296" class="preview_image" />
</div>

Now we just have to add the javascript to hide the image and add the necessary video code. We also want to immediately play the video so the user doesn't have to click it twice.


$(".preview_image").click(function() {
        //Append the Video
	$(this).parent('.video_box').prepend('<video id="example_video_1" class="video-js" width="525" height="296" poster="poster.jpg" controls style="height:296px !important"><source src="test.m4v" type=\'video/mp4; codecs="avc1.42E01E, mp4a.40.2"\' /><source src="test.webm" type=\'video/webm; codecs="vp8, vorbis"\' /><source src="test.ogg" type=\'video/ogg; codecs="theora, vorbis"\' /></video>');
        //Hide the image
	$(this).css({'display':'none'});
        //Play the Video
	$(this).siblings("video").trigger("play");
	return false;
});

You'll notice that I'm not appending the flash fall back above. The reason I'm doing this is to use the Flowplayer API later in order to use javascript to play/pause the flash player. If you don't need to be able to play/pause the flash player by clicking on a page element, then you can just add the flash fallback code as well.

Be sure to keep the append code all on one line because it javascript will break if you put them on separate lines without concatenating them.

This should fix any issues with speed or browsers trying to preload the videos because they aren't there when the page is loaded. If there are multiple videos on the page, you'll have to modify the code slightly by changing the class of "video_box" and "preview_image" the something unique for each video. This will load the video/s individually.

I did have a small issue with the duration of the video not getting pulled and the play tracker was always at 100%, but the video tag can take a duration argument which seemed to fix it although you'll have to set it each video individually.

Playing and Pausing your Videos

And if you wish to create a custom button to pause your video this little snippet of jQuery will pause all videos if you click on something with the class="pause".

$(".pause").click(function() {
  $("video").trigger("pause");
  return false;
});

The only issue with this player at the moment is if you are using a browser the doesn't support HTML5 (IE) then then pause button isn't going to function.

In order to use the flowplayer api to pause/play your flash fall back, you'll need to Download Flowplayer.js and include it on your website. Now that that is done, include this block of jQuery. The first if statment only targets IE, because all other browsers support HTML5 video.


if ( $.browser.msie ) {
  //Hide the original image
  $(".preview_image").css({'display':'none'});
  $(".preview_image").parent('.video_box').prepend('<a class="flash_player" href="http://mysite.com/test.m4v" style="background:url(http://mysite.com/poster.jpg)"><img src="http://mysite.com/poster.jpg" />');
  flowplayer("a.flash_player", {src: 'http://releases.flowplayer.org/swf/flowplayer-3.2.7.swf', wmode: 'opaque'}, {
  // use the first frame of the video as a "splash image"
    clip: {
	autoPlay: false,
	autoBuffering: false
    }
  });
}

This will add an a tag that will then get populated with the flowplayer flash fall back. For some reason, if you don't dynamically generate the Flowplayer like this, it won't pause when you try to pause it using the Flowplayer API commands. The video will play whatever the value of the href attribute of the a tag.

I also slightly modified my pause javascript as well to use the Flowplayer API is the browser is IE.


if ( $.browser.msie ) {
    $(".pause").click(function() {
	$f().pause();
	return false;
    });
} else {
    $(".pause").click(function() {
      $("video").trigger("pause");
       return false;
     });
}

And that's pretty much it. There's a whole lot of other things you can do with the Flowplayer API that you can read about here.

Keep in mind that if you plan on having multiple videos, you're going to have to make all your classes unique somehow.