• No results found

JavaScript API

4.5 Custom Controls

The JavaScript API's foremost use case will be to roll your own controls with a style that looks identical across all browsers. Because this is such a common use case, we provide you with an example on how to do so. This includes a skeleton of the HTML code, some CSS, and the required JavaScript calls to control it.

We want to build the player displayed in Figure 4–19. It is inspired by an accessible YouTube player implemented by Christian Heilmann and available at http://icant.co.uk/easy-youtube/.

Figure 4–19. A custom video player using the JavaScript API

The player consists of several interface elements. It has a progress display (the bar underneath the video), behind which it shows the seconds played and the video duration. Below that is a collection of buttons to start playing (a play/pause toggle), rewind by 5sec, stop playback (and reset to file start), increase volume by 10 percent, reduce volume by 10 percent, and mute/unmute. To the right of the video is the volume display. It is grayed out when muted, and the volume level is shown as a percentage in height.

We start implementing this player by providing a skeleton of the HTML code that creates this player.

Listing 4–22 shows the skeleton.

Listing 4–22. An HTML markup skeleton for the video player in Figure 4–19 <div id="player">

<div id="video">

<video width="400" height="225">

<source src="video2.mp4" type="video/mp4">

<source src="video2.webm" type="video/webm">

<source src="video2.ogv" type="video/ogg">

</video>

http://freepdf-books.com

131 <div id="positionview">

<div id="transportbar"><div id="position"></div></div>

<div id="time">

<span id="curTime">00:00</span>/<span id="duration">00:00</span>

</div>

</div>

</div>

<div id="volumecontrol">

<div id="volumebar"><div id="volume"></div></div>

<div id="vol"></div>

</div>

<div style="clear: both;"></div>

<div id="controls">

<div><input id="play" type="image" src="0.gif" alt="Play"></div>

<div><input id="repeat" type="image" src="0.gif" alt="Repeat"></div>

<div><input id="stop" type="image" src="0.gif" alt="Stop"></div>

<div><input id="louder" type="image" src="0.gif" alt="Louder"></div>

<div><input id="quieter" type="image" src="0.gif" alt="Quieter">

</div>

<div><input id="mute" type="image" src="0.gif" alt="Mute"></div>

</div>

</div>

A <div> encapsulates the complete player code such that we can later give it a style that shows it as an entity. Inside the #player div are three main divs: #video, #volumecontrol, and #controls. The

#video part contains the video element, as well as the transport bar and time displays. The

#volumecontrol contains the volume bar and volume number display. The #controls contains all the buttons.

Note that the video element does not have a @controls attribute—as we want to run these controls ourselves. Also notice how the <input> elements that represent the buttons have been made accessible by making them of type “image” and giving them an @alt attribute value. Since we are going to provide the actual buttons in CSS through a single PNG, we have to put a placeholder 1x1 px GIF into the @src attribute of the <input> elements so that they do not show up as broken images.

Next, we move on to styling this HTML skeleton. Listing 4–23 shows an extract of the CSS in use.

Listing 4–23. CSS for the HTML skeleton in Listing 4–22 and the video player in Figure 4–18 <style type="text/css">

#player {

132

background:url(buttons.png) no-repeat top left;

border:none;

The player div gets a nice border, rounded corners, and a shadow to make it stand out. For the position display we have an outer <div> and an inner <div>, where the outer one provides the box into which the playback position can grow and the inner one grows with the playback speed of the video. The buttons all use the same PNG with an offset and a 60x60 px cropping area.

Finally we add the JavaScript that will make it all work in Listing 4–24.

Listing 4–24. JavaScript for the HTML skeleton in Listing 4–22 and the video player in Figure 4–19 <script type="text/javascript">

video = document.getElementsByTagName("video")[0];

position = document.getElementById("position");

curTime = document.getElementById("curTime");

duration = document.getElementById("duration");

volume = document.getElementById("volume");

quieter = document.getElementById("quieter");

mute = document.getElementById("mute");

http://freepdf-books.com

133 video.addEventListener("loadedmetadata", init, false);

function init(evt) {

duration.innerHTML = video.duration.toFixed(2);

vol.innerHTML = video.volume.toFixed(2);

}

video.addEventListener("timeupdate", curTimeUpdate, false);

function curTimeUpdate(evt) {

curTime.innerHTML = video.currentTime.toFixed(2);

position.style.width = 300*video.currentTime/video.duration + "px";

}

video.addEventListener("volumechange", dispVol, false);

function dispVol(evt) {

vol.innerHTML = video.volume.toFixed(2);

}

play.addEventListener("click", togglePlay, false);

function togglePlay(evt) {

repeat.addEventListener("click", rewind, false);

function rewind(evt) {

video.currentTime = video.currentTime - 2.0;

}

stop.addEventListener("click", restart, false);

function restart(evt) { video.pause();

play.style.backgroundPosition = "0 0";

video.currentTime = 0;

}

louder.addEventListener("click", volInc, false);

function volInc(evt) {

changeVolume(video.volume+0.1);

}

quieter.addEventListener("click", volDec, false);

function volDec(evt) {

changeVolume(video.volume-0.1);

}

mute.addEventListener("click", toggleMute, false);

function toggleMute(evt) { video.muted = !video.muted;

http://freepdf-books.com

134

The full JavaScript for the player is replicated here. Take a minute to go through the code. Note how every button has an onclick event handler and there are extra event handlers for the loadedmetadata, timeupdate, and volumechange events. You will notice many familiar IDL attributes: video.duration, video.volume, video.currentTime, video.paused, and video.muted are all used here to provide the functions behind the buttons. Finally, you will also notice the play() and pause() control methods.

4.5 Summary

In this chapter we introduced the JavaScript API of the <video> and <audio> elements.

We have approached this in a structured way, starting with the IDL attributes that represent the content attributes from the HTML markup, such as @src, @width, and @height. Then we discussed the IDL attributes that represent resource features, such as @currentSrc, @duration, and @volume. Then we looked at the playback related IDL attributes such as @currentTime, @paused, and @ended.

After the IDL attributes, we introduced the states of a media resource, including networkState, readyState, and played, buffered, or seekable TimeRanges.

After the states came the control methods load(), play(), pause(), and canPlayType().

We finished analyzing the JavaScript API with a listing of the events that the media elements fire.

There is a fair number, including loadedmetadata, canplay, playing, pause, seeking, volumechange, durationchange, and ended.

We concluded the chapter with a practical use case of the JavaScript API: running your own custom controls.

We now have all the tools at hand to successfully use <audio> and <video> in HTML5 applications.

The next chapters will analyze how <audio> and <video> interact with other elements and JavaScript functionalities in HTML5, including SVG, the Canvas, and WebWorkers.

http://freepdf-books.com

■ ■ ■

135