Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / HTML5, CSS3, and JavaScript /

Working with HTML5 multimedia components – Part 3: Custom controls

by Ian Devlin

Ian Devlin
  • www.iandevlin.com

Content

  • Getting started
  • Adding play and pause functionality
  • Adding volume and mute buttons
  • Adding a progress bar
  • Listening for Events
  • Adding a playlist
  • Where to go from here

Created

7 November 2011

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
audio CSS Dreamweaver HTML5 JavaScript video

Requirements

Prerequisite knowledge

Familiarity with HTML and JavaScript.

User level

Intermediate

Sample files

  • custom-controls.zip (15.1 MB)

This is Part 3 in a three-part series of tutorials on HTML5 multimedia. In Part 1 and Part 2, I covered the video and audio elements, respectively, and briefly showed how adding the controls attribute to these elements informs the browser to add a set of default controls to the media element in question. If you tried out the sample applications for those tutorials, you may have noticed that the controls look different depending on the browser you are using.

If you want to achieve a uniform look across browsers for your media controls, you can use the handy HTML5 media element API. You can create and style your own media control set using standard HTML and CSS and then use the media element API to hook it up to the audio and video elements you want to control.

This tutorial describes the steps needed to gradually build up a custom media player, adding various features and functionality in the process, and using different API attributes, events, and methods. You can see the completed media player by downloading and exploring the sample files for this article.

Note: This tutorial uses a video example, but the steps can be easily adapted to handle audio.

Getting started

To begin with, you'll need to define a video element to use with the yet to be created media player:

<video id="video" controls> <source src="grass-in-the-wind-sma.mp4" type="video/mp4"> <source src="grass-in-the-wind-sma.webm" type="video/webm"> </video>

You'll notice that the controls attribute has been defined for the video, even though you're going to create your own. Since your custom controls will be built in JavaScript, you're going to turn the default controls off via JavaScript. That way, if a user has JavaScript turned off, they'll still be served with the browser's default control set.

To turn the default controls off, you simply set the video element's controls attribute to false:

<script> // Grab a handle to the video var video = document.getElementById("video"); // Turn off the default controls video.controls = false; </script>

And with that, you're ready to move on!

Adding play and pause functionality

The first and most basic requirement for any media player is the ability to play and pause the media in question. For this example, you'll use a single button, which will serve as a play button when the video is paused (or stopped) and a pause button when it's playing.

<div id="controls"> <button id="playpause" title="play">Play</button> </div>

Next you need to create a JavaScript function that will do the work of changing the button title and starting or pausing the media.

In this example, the function is named togglePlayPause(). Take a look at the full implementation below; a line-by-line explanation follows.

function togglePlayPause() { var playpause = document.getElementById("playpause"); if (video.paused || video.ended) { playpause.title = "pause"; playpause.innerHTML = "pause"; video.play(); } else { playpause.title = "play"; playpause.innerHTML = "play"; video.pause(); } }

To have this function invoked every time the play/pause button is clicked, you add it to the onclick event of the button:

<button id="playpause" title="play" onclick="togglePlayPause()">Play</button>

The first line of the togglePlayPause() function obtains a handle to the play/pause button itself, and assigns it to the variable playpause:

var playpause = document.getElementById("playpause");

Next, it checks the status of the video to see if it's paused or ended, via the two attributes paused and ended. If the video is in either of these states, it then sets the button's title and innerHTML attributes to "pause" and calls video.play() to start playing the video.

If the video is not currently paused or ended, then you can assume it is already playing. In this case, the function sets the button's title and innerHTML to "play" and calls video.pause() to pause the video.

The button's default text is "play." When the button is clicked for the first time, the video will start playing and the button's text will be changed to "pause." Subsequently, when the pause button is clicked, the video will pause and the button's text will be changed back to "play."

As you'll see, the remaining functionality that you'll add in this tutorial follows the same basic format: listen for an event from the video element, check the element's status, and then act on it via API methods.

Adding volume and mute buttons

Another vital piece of functionality for a media player is the ability to control the volume, including the ability to mute it altogether.

To add a volume control, you'll use one of the new HTML5 input types: range. This input type is usually rendered by the browser as a slider, which the user can move from left to right and vice versa, so it's ideal for a volume control. You specify the minimum and maximum values for the range input via the min and max attributes. You use the step attribute to set the amount you want the slider's value to change when the slider's position changes. To create a volume control slider with a range between 0 and 1, and a step size of  0.1, you can use the following code:

<input id="volume" min="0" max="1" step="0.1" type="range" />

When the slider is moved, you want to invoke a JavaScript function that will adjust the volume, so add an onchange event handler:

<input id="volume" min="0" max="1" step="0.1" type="range" onchange="setVolume()" />

Next, create a JavaScript function named setVolume():

function setVolume() { var volume = document.getElementById("volume"); video.volume = volume.value; }

This simple function obtains a handle to the volume slider and assigns its value to the video element's volume attribute.

Note: Firefox 7 doesn't support the range input type and displays a text field instead. Typing a new value in this text field (between 0 and 1) and moving the focus away from the text field will alter the volume in this browser.

Adding a mute button is just as easy. Again you start by defining a new button, this time with an onclick handler:

<button id="mute" onclick="toggleMute()">Mute</button>

Next, create a function named toggleMute():

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

This function simply sets the video element's (Boolean) muted attribute to be the opposite of its current value. This toggles the mute status of the button. Easy!

Adding a progress bar

When a video is playing, users are accustomed to checking the progress bar to see how much has played and how much is left to play.

To add a simple progress bar to your media player, you can use a div element and a span element. Specifically, you increase the width of the span element as the video progresses, using it to represent the amount played.

<div id="progressBar"><span id="progress"></span></div>

Of course, you'll want to style these elements with simple CSS so that the progress can be seen easily:

#progressBar { border:1px solid #aaa; color:#fff; width:295px; height:20px; } #progress { background-color:#ff0000; // red height:20px; display:inline-block; }

Next, define a function that will update the progress bar by changing the width of the span element:

function updateProgress() { var progress = document.getElementById("progress"); var value = 0; if (video.currentTime > 0) { value = Math.floor((100 / video.duration) * video.currentTime); } progress.style.width = value + "%"; }

The first line of this function obtains a handle to the progress span element itself. It checks the value of the video element's currentTime attribute, which defines the current playback position, in seconds. If currentTime is greater than 0, and therefore the video has advanced, it calculates the current progress as a percentage using the video element's duration attribute, which contains the video's total length in seconds. Finally, it sets the CSS width of the progress span to this calculated value.

With the play, pause, mute, and volume controls you used events such as onclick and onchange to invoke the appropriate functions. You can't use this approach with a progress bar, because it updates in response to video progress, not user interaction.

The HTML5 media element API, however, raises a number of events that you can listen for and act upon instead. One of these is the timeupdate event, which fires every time the media's currentTime attribute is changed. (This attribute changes as the media is played.)

In the JavaScript initialization code of your web page, add an event listener that invokes the updateProgress function when the timeupdate event fires:

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

Now your progress bar will be updated as the video plays.

Listening for Events

The media element API defines a number of events that you can use in implementing a media player. For a complete list, see the W3C's summary of media element API events. Table 1 shows several of the more commonly used events.

Table 1. Media element API events.

Event name

Description

playing

Raised when playback of media is ready to start after having been previously paused

ended

Raised when the media has stopped playing as it has finished

timeupdate

Raised when the media's current playback position has changed

play

Raised when the media that was previously paused is no longer paused and playback has resumed

pause

Raised when the pause() method has returned and the media has been paused

volumechange

Raised when the media's volume or muted attribute has changed

When you're adding custom controls, it's good practice to listen for some of the available events to make sure your controls are always synchronized with the state of the video.

How might the controls lose synchronization? Recall that you removed the default control set via JavaScript. It is possible, however, for a user to reenable these controls and use them to interact with the video. For example, in Firefox, a user can right-click the video, select Show Controls, and click Play or Pause. If a user did this and started a video playing, then the text on the play/pause button that you created would no longer accurately reflect the media's current state.

Regardless of what mechanism is used to control the video, the appropriate events will still be raised. So you can listen for the pause and play events and act on them accordingly to keep your buttons in synch; for example:

video.addEventListener('play', function() { var playpause = document.getElementById("playpause"); playpause.title = "pause"; playpause.innerHTML = "pause"; }, false); video.addEventListener('pause', function() { var playpause = document.getElementById("playpause"); playpause.title = "play"; playpause.innerHTML = "play"; }, false);

You should also listen for the ended event, so that when the video ends, the play/pause button is also kept up to date. You can do this by calling the pause() method on the video when the ended event is raised:

video.addEventListener('ended', function() { this.pause(); }, false);

Note: The reason you call the pause() method here is that it automatically causes the pause event to be raised which will in turn cause the code we've written above for the pause event handler to be called. You could indeed duplicate the code in the ended event handler, or, if you wanted to do something different or extra, you would define it here.

Adding a playlist

The final feature to add is a media playlist, which the user can use to change the video played in the media player. This is actually quite simple. First of all you define your playlist; for example:

<ul id="playlist"> <li><a href="#" onclick="playlistClick('grass-in-the-wind-sma');">Grass blowing in the wind</a></li> <li><a href="#" onclick="playlistClick('tree-in-the-wind-sma');">Trees blowing in the wind</a></li> </ul>

There are two items in this playlist, and each calls a function named playlistClick() when clicked. This function takes a single argument: the stem of the video file it is to play (that is, the file name without the file extension). This function is defined as follows:

function playlistClick(file) { var v = document.createElement("video"); if (v.canPlayType("video/mp4") != "") { changeSource(file + ".mp4"); } else if (v.canPlayType("video/webm") != "") { changeSource(file + ".webm"); } return false; }

This function first creates a temporary video element and then calls the canPlayType() method for each of the supported video types, which in this case are MP4 and WebM. After determining which file type the browser is capable of playing, it calls changeSource()with one argument, the file stem that was passed into the function concatenated with the appropriate file extension. This function also returns false to prevent the element from following the link to the value of its href attribute.

The changeSource() function is defined as follows:

function changeSource(src) { resetPlayer(); video.src = src; video.load(); }

This function calls resetPlayer(), which you'll look at next, and then sets the video element's src attribute to the new video file that has been passed as an attribute. Finally, it calls load()to load the new video source into the video element.

Note: Not all browsers require the load() method to be called, but Safari does. Therefore it's a good idea to call it.

The resetPlayer() function resets a few of the player's components in preparation for loading a new video:

function resetPlayer() { var playpause = document.getElementById("playpause"); playpause.title = "play"; playpause.innerHTML = "play"; if (video.currentTime > 0) video.currentTime = 0; updateProgress(); }

First, it sets the play/pause button text to "play." Next it resets the video element's currentTime variable to 0 if it's not already at 0. Finally it calls the updateProgress() function, which will reset the progress bar back to the start. (The progress bar uses the video element's currentTime attribute, which was just set to 0.)

Where to go from here

That's it! You've seen all the steps necessary to create a simple HTML5 media player. It is admittedly not the most attractive player available, but you can use CSS to style it and improve its appearance.

To see more of the media element API, its events, and its properties in action, check out the W3C's HTML5 Video Events and API demonstration page, which plays videos with basic controls and displays API properties and events.

You can read more about creating custom controls for HTML5 video and audio in my upcoming book, HTML5 Multimedia: Develop and Design.

More Like This

  • Introducing the HTML5 storage APIs
  • Introducing theexpressiveweb.com beta
  • Adobe, standards, and HTML5
  • Developing HTML5 games with Impact JavaScript game engine and Dreamweaver CS5.5
  • Using the Geolocation API
  • CSS3 basics
  • Real-time data exchange in HTML5 with WebSockets
  • JavaScript object creation: Learning to live without "new"
  • Object types in JavaScript
  • Pseudo-classical object-oriented programming in JavaScript with Minion

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement