HTML5 Video & Skinning Tutorial Part 3: Rewind/Fast Forward
June 23, 2010 by Nicholas DavisonYesterday we covered setting up a play/pause button that controls an HTML5 <video> element.
Today we will be expanding that code, adding rewind and fast forward buttons. We will also be looking at the limitations current player implementations provide and how they affect us.
Throughout these tutorials, we will be continuing the concepts/implementation division: Explaining the ideas first, letting those who wish to run ahead do so – then going over a step by step implantation with jQuery.
Concepts
True Rewind/Fast Forward – Not Quite There
HTML5 <video> elements have the read/write attribute playbackRate.
A value of 1.0 means the video plays at normal speed. -1.0 means the video plays backwards. Fractions and multiples mean it plays at fractions and multiples of normal speed. For example: 0.5 is half speed and -4.0 is 4x speed backwards.
True rewind/fast forward buttons should scan through at increased speed so a basic implementation might do something like this:
function rewind() {
document.getElementById("video").playbackRate = -10.0;
return false;
}
function fastForward() {
document.getElementById("video").playbackRate = 10.0;
return false;
}
function play() {
document.getElementById("video").playbackRate = 1.0;
return false;
}
Unfortunately, support for playbackRate is still very poor. In our limited testing, only Safari could handle variable rates in both directions, Chrome joined it in variable forward speed only and Firefox simply ignored playbackRate.
With support this patchy still, unless you are building an app for a very specific browser, we would recommend holding off on using playbackRate until it is better supported.
Step Backward/Step Forward
Whilst playbackRate and true rewind/fast forward may not work yet, jumping to different points is available.
The floating point, read/write attribute currentTime lets us both know how far in to the video we currently are and then set new positions.
It takes a value in seconds, rounding to the closest frame if you specify more decimal points than the video has frames for. So, for example, a 10fps file set to 10.101 would jump to the 101st frame.
To make life even easier for us, giving a value of less than 0 will get caught by the browser and treated as 0. A value off the end of the video will be treated as the last valid position. This means we can add and subtract with relative abandon, never needing to check to see if we’re going out of range.
You can read and write, creating step forward/backward functions, as simply as:
function stepForward() {
var now=document.getElementById("video").currentTime;
document.getElementById("video").currentTime=now+10;
}
function stepBackward() {
var now=document.getElementById("video").currentTime;
document.getElementById("video").currentTime=now-10;
}
Implementation
HTML
All we are adding today are two extra buttons, step rewind and step fast forward to yesterday’s video_buttons list:
<div class="video_controls" rel="myvideo">
<ul class="video_buttons">
<li class="video_steprewind"><a href="#">Rewind</a></li>
<li class="video_play"><a href="#">Play</a></li>
<li class="video_stepfastforward"><a href="#">Fast Forward</a></li>
</ul>
</div>
CSS
Similarly, all today’s CSS does is add CSS sprite states for those two buttons:
.video_steprewind a { background-position: -98px 0px }
.video_steprewind a:hover { background-position: -98px -50px }
.video_steprewind a.active { background-position: -98px -100px }
.video_steprewind a.active:hover { background-position: -98px -150px }
.video_stepfastforward a { background-position: -426px 0px }
.video_stepfastforward a:hover { background-position: -426px -50px }
.video_stepfastforward a.active { background-position: -426px -100px }
.video_stepfastforward a.active:hover { background-position: -426px -150px }
JavaScript
First we create an initialization function and give it a common step size variable _stepSize so stepping forwards and backwards is consistently by the same, easily changeable, amount:
function initVideoDirectionStepButtons() {
var _stepSize = 10.0;
/* Add Code For Stepping Backward */
/* Add Code For Stepping Forward */
}
The step backward code starts the same way as yesterday’s play button, pre-fetching and storing the $_video elements to keep the main bound event faster:
$('.video_steprewind a').each(function() {
var $_video=findVideoForElement(this);
/* Bind Each Button */
});
The binding then stops the link from firing before going through all of the stored videos, setting their currentTime to their current currentTime – the _stepSize:
$(this).click(function(e) {
e.preventDefault();
$_video.each(function(index, _video) {
_video.currentTime=_video.currentTime-_stepSize;
});
});
We then repeat all of this, in the other direction for the stepping forward code:
$('.video_stepfastforward a').each(function() {
var $_video=findVideoForElement(this);
$(this).click(function(e) {
e.preventDefault();
$_video.each(function(index, _video) {
_video.currentTime=_video.currentTime+_stepSize;
});
});
});
Now we just add the function call to the ready function and we’re done.
Tomorrow
Tomorrow we will be looking at interactive progress bars – both showing the video’s progress and allowing users to skip to a visual point along it.
Resources
The W3C spec for HTML5 video is available at:
http://www.w3.org/TR/html5/video.html
However, we would recommend the whatwg version as its linked table of contents makes it slightly more usable (even if the text is just as dense):
http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
Nicholas Davison Director of Web Development
Read more from the Engineering category. If you would like to leave a comment, click here: Comment or stay up to date with this post via RSS, or you can Trackback from your site.
Comments
Post new comment