24 March 2010

One player to rule them all: An MP4 player solution for iPhone and any browser

For a recent project, I needed a video player that would play nice with the iPhone. Part of the solution was provided by the amazing html5media JavaScript library. However, if you'd like to encode only one video format, MP4, and get it working on Opera 10.5+, it will require some more work.

The html5media library is able to detect and replace the <video> tag with the Flowplayer Flash player for almost all browsers; for some reason, it can't do the same for Opera 10.5. And as this page explains, the HTML5 <video> tag on Opera requires an OGV video; it can't play MP4.

Here's a solution that lets you play MP4 video on the latest iPhone, Firefox 3.6, IE 6 - 8, IE Platform Preview 9, Opera 10.5, Safari 4, and Chrome 4.1. I don't know if it's the most elegant, but it gets the job done.

First, download the free Flowplayer library. Unzip the package and then start an HTML document:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Video Test</title>
<script src="http://html5media.googlecode.com/svn/trunk/src/html5media.min.js">
</script>
<script type="text/javascript" src="js/flowplayer-3.1.4.min.js"></script>
<script type="text/javascript">
// Required for Opera to display the MP4 video.
// Removes take the <video> and <source> elements
// from the DOM, but keeps the other children of
// the <video> tag. In this case, it retains the
// <a> tag which will be used for the Flowplayer.
function fallback(video) {
while (video.firstChild) {
if (video.firstChild instanceof HTMLSourceElement) {
video.removeChild(video.firstChild);
} else {
video.parentNode.insertBefore(video.firstChild, video);
}
}
video.parentNode.removeChild(video);
fixForOpera();
}

// Places a Flowplayer Flash player into the item with ID "player".
function fixForOpera(){
flowplayer("player","js/flowplayer-3.1.5.swf");
}
</script>
</head>
<body >
<video id="vid" width="352" height="264" poster="cat.jpg" controls preload>
<source src="cat.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
onerror="fallback(this.parentNode)"></source>
<a
href="cat.mp4"
style="display:block;width:352px;height:264px"
id="player">
</a>
</video>
</body>
</html>

The trick is to catch the error thrown by the <video> tag (using its onerror attribute) and remove the tag (using the fallback() function), ensuring that we keep the anchor tag that will hold the Flowplayer object. The fallback() function also calls fixForOpera(), which places the Flowplayer object into the anchor tag with ID player.

This player works for the browsers listed and the iPhone.

6 comments:

Anonymous said...

Couldn't get the player to work in either I.E. 6 or firefox. The poster image shows, but no sound or video.

Anonymous said...

Couldn't get the player to work in either I.E. 6 or firefox. The poster image shows, but no sound or video.

Alex C said...

Sorry for your problems. Another solution I'm using now is the JW Player for HTML5 (http://www.longtailvideo.com/support/jw-player/jw-player-for-html5). It's currently in beta but will have Version 1.0 in a week or two. It's the best of the HTML5/Flash players out there. The beta has issues on IE but the issues should be resolved by Version 1.0.

mp4 to dvd said...

Hi, Anynymous, why not upgrade you IE 6 and firefox to the latest version. html5media works well for me and has no any problem.

mp4 to mov said...

your solution seems good, however, i think I would like to convertmp4 to mov on Mac for iphone, ipad, and all Mac os media player.

Mark Newton said...

I have followed your steps to convert video to HTML5 and embed it into the webpage. It works flawlessly. Thank you!