Showing posts with label video tag. Show all posts
Showing posts with label video tag. Show all posts

15 November 2010

Getting JW HTML5 Player to work on IE, Part II

In part 1, we talked about getting the player working on IE with the beta version of the JW HTML5 Player. Now that version 1.0 of the JW Player is out, let's revisit the issue of getting it working on various browsers, including IE.

First off, the full release has a different syntax for initialization of the player. This code demonstrates how to set up the player for all video tags on the page as well as for IE. Don't forget to include the jwplayer.js file on the page.

$(document).ready(function(){

$("video").each(function(){
if (jQuery.browser.msie){
var vidFile = "";
$(this).parent().find("source").each(function(){
if (jQuery(this).attr("src").indexOf("m4v") != -1 ||
jQuery(this).attr("src").indexOf("mp4") != -1){
vidFile = jQuery(this).attr("src"); //.substring(jQuery(this).attr("src").lastIndexOf("/")+1);
//alert("vidFile: " +vidFile);
}
$(this).remove();
});
$("[id="+$(this).attr("id")+"]").attr("src",vidFile);
}

jwplayer($(this).attr("id")).setup({
events: {
onPlay: function() {videoEventHandler(1)},
onComplete: function() {videoEventHandler(0)}
},
//debug: "console",
players:
[
{ type: "html5" },
{ type: "flash", src: "global/vid/player.swf" }
],
components: {
controlbar: {
position: 'bottom'
}
}
});
});


});

function videoEventHandler(type){
switch(type){
case 1:
stopSlider();
break;
case 0:
startSlider();
break;
default:
return;
}
}
You should try the above code without the if (jQuery.browser.msie){...} to see if it works for you on IE; it didn't for me so I've thrown that in. The code pulls the MP4/M4V video source and applies it to the main video tag as a src attribute. This took quite a bit of trial-and-error to discover.

Note that in the version I was using, there was a bug in Firefox: FF doesn't like the console object being called when without the Firebug window being open. IE has the console object available by default. So if you set debug: "console", you might get errors on Firefox.

In addition, when creating your video tags, ensure that the MP4 source tag comes before OGV: Chrome chokes if you have OGV first, perhaps because it can play both video types via its HTML5 implementation. Also note the event handlers attached to the video player; these are called for the AnythingSlider to stop and start.

14 July 2010

Opera and the OGG video - source location matters

I've recently been working on implementing HTML5 video on a new web site. The challenge I ran into yesterday was to get the OGG video to display on Opera 10.54. Using the following error handler, I found out what the problem was, but couldn't get any closer to a solution:
 function failed(e) {
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
alert('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
alert('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
alert('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
alert('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
alert('An unknown error occurred.');
break;
}
}
Here's the video tag:
<video  id="vid-2" width="372" height="209" 
poster="global/img/farmfresh.jpg" controls
onPlaying="stopSlider()" >
<source class="source" src="global/vid/farmfresh.ogg" type='application/ogg'
onError="failed(event)">
<source class="source" src="global/vid/farmfresh.mov">
<source class="source" src="global/vid/farmfresh.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<img src="global/img/farmfresh2.jpg" title="North Carolina Farm Fresh: Monday, April 29 at 9:30 PM"/>
</video>
The problem was the location of the OGG source tag; for Opera, the OGG video has to be the first if you have multiple source elements. Now Opera is happy as well as the other browsers.

08 July 2010

Getting JW HTML5 Player to work on IE

In my continuing adventures with HTML5 video, I arrived at IE testing, and noticed that IE does not like the JW HTML5 Player (mainly because it's in beta right now). But I have to demo my site and can't wait until Version 1.0 of the player; so, I rolled up my sleeves for another non-trivial challenge.

The problem is that the current versions of IE can't display the HTML5 video tag; IE 9 will address this, but we'll be living with lower versions for some years. And the beta JW HTML5 Player doesn't remove the video tag completely from IE. The answer is to do some jQuery coding to find the video tags and replace them with swfobject elements. There are plenty of gotchas along the way as to file paths and filenames.

Here's the finished code:
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>

<script type="text/javascript">
$(document).ready(function(){
// If this is IE...
if (jQuery.browser.msie){
var el = "";
var vidFileName = "";
var posterPath = "";
var videoTag = "";
var boxId = "";
var so = "";
var flashId = "";
var flashVars = "";
var params = "";
var attributes = "";
var anchorId = "";

// For each video element...
$("[id^='vid-']").each(function(){
// Clear out the variables.
el = "";
vidFileName = "";
posterPath = "";
videoTag = "";
flashId = "";
flashVars = "";
params = "";
attributes = "";
anchorId = "";

// Get a handle to the current object.
el = $(this);

// Set some variables we'll shortly.
boxId = this.id + "_flashBox";
flashId = this.id + "_flashPlayer";
anchorId = this.id + "_anchor";

/*
Set the ID of the first DIV element of the current
object's parent's parent. This will allow us to
reference that DIV later.
*/
el.parent().parent().find("div:first").attr("id",boxId);

/*
Loop over each 'source' tag inside the video; check
the 'source' tag's 'src' attribute. If it contains
'm4v' or 'mp4', then it's usable for the Flash
player in IE.
*/
el.parent().children("source").each(function(){
if ($(this).attr("src").indexOf("m4v") != -1 ||
$(this).attr("src").indexOf("mp4") != -1){
/*
We don't need the filename + path of the video,
only the filename. So we remove the path and
fetch only the filename.
*/
vidFileName = $(this).attr("src").substring($(this).attr("src").lastIndexOf("/")+1);
}
});

// Get the poster's filename and path.
posterPath = el.parent().find("img").attr("src");


// Get a reference to the video's containing DIV.
el = $("[id="+boxId+"]");

// Empty the DIV of all contents.
el.empty();

/*
Append an anchor tag with the anchor ID to the DIV.
We'll replace this anchor tag with the Flash player.
*/
el.append("<a id='" + anchorId + "'></a>");

// Set flashvars, params, and attributes.
flashvars =
{
file: vidFileName,
autostart: 'false',
image: posterPath
};

params =
{
allowfullscreen: 'true',
allowscriptaccess: 'always',
wmode: 'opaque'
};

attributes =
{
id: flashId,
name: flashId
};

/*
Embed the Flash player object using the swfobject.
The embedSWF() method replaces the anchorId element
with the Flash player. For more information on the
various arguments, please see the documentation here:
http://code.google.com/p/swfobject/wiki/documentation
*/
swfobject.embedSWF('global/vid/player.swf', anchorId, '372',
'209', '9.0.124', false, flashvars, params, attributes);
});
}
});
</script>
One gotcha with swfobject: You need to ensure the path of the 'file' that you wish to play is relative to the player.swf or you'll get an error saying 'Can't find file or access denied.' This thread talks about the issue.

In addition, you'll need to add the following to the page to prevent IE from throwing an error:
if (!jQuery.browser.msie){
$('video').jwplayer({
flashplayer:'global/js/jwplayer/player.swf',
skin:'global/js/jwplayer/five/five.xml'
});
}
This ensures that the JW HTML5 Player is fired off only on non-IE browsers. My previous post on HTML5 video and the JW Player has links to all my other posts on the subject.

UPDATE: Please see part 2 of this post for how to get the release version of the player working on IE and other browsers.

01 July 2010

YouTube backs Adobe Flash over HTML5

http://www.infoworld.com/d/developer-world/youtube-backs-adobe-flash-over-html5-849
"While HTML5's video support enables us to bring most of the content and features of YouTube to computers and other devices that don't support Flash Player, it does not yet meet all of our needs," said YouTube software engineer John Harding in the post. "Today, Adobe Flash provides the best platform for YouTube's video distribution requirements."

18 June 2010

Event handler for HTML5 video

I'm using the HTML5 video tag inside the AnythingSlider. An interesting problem arose: How do you stop the AnythingSlider when the user starts playing the video? You don't want the slider to keep going in this situation.

Well, here's a solution. The HTML5 video events are described in the "4.8.9.12 Event summary" section of the W3C document. At first, you'd guess that you'd use the onPlay event handler. Nope. That only works when you play the video the first time; on the second play, it won't call the function. The event handler to use is onPlaying.

But how do you stop the AnythingSlider programmatically? The good folks on StackOverflow.com provided the answer.

So here's the video tag:
<video controls preload onPlaying="stopSlider()">
....
</video>
And here's the function to stop the AnythingSlider:
function stopSlider(){
while (1 == 1){
$("div.anythingSlider a#start-stop").trigger("click");
if ($("div.anythingSlider a#start-stop").html().indexOf("Go") != -1)
break;
}
}
Note what appears to be an infinite while loop: Actually, the code is designed to stop the AnythingSlider. It triggers the "click" on the "start-stop" element, checking after each click to see if the HTML of the element contains the word "Go"; if it does, it break out of the loop. Of course, you'll have to modify it if you're using text other than "Go" on the "start-stop" anchor tag.

15 June 2010

OGV/OGG and the HTML5 player in Firefox

I tried playing an OGV video on Firefox using the new HTML5 video tag; the video played fine in the latest versions of Opera, Chrome, and Safari. But Firefox 3.6.3 would only show a big "X" -- no errors, nothing.

Some research revealed the answer: The video is being served as application/octet-stream. The other browsers can detect the type from the extension; Firefox, following good standards, is checking the mime type. The same issue existed on my localhost, with IIS running.

Solution is to add the OGV/OGG mime type to the server; different servers have different ways of doing this. For IIS, it's pretty simple. Follow the linked article, and simply replace the "Extension" with .ogg and the "MIME type" with application/ogg and restart IIS. Additional information on Firefox and mime type configuration can be found here. I recommend the OGG file extension and application/ogg mime type because they're included on Apache servers by default -- so no need to update configuration files and restart your production server.

But there's more to it. The type attribute on the source has to be shorter (this is a known Firefox bug). In addition, the OGG file has to be encoded correctly for it to work in all the browsers supporting the HTML5 video tag. The best encoding tool I've found thus far is FireFogg. It created the OGV that works like a charm on all the appropriate browsers (I just renamed the extension to OGG).

One last gotcha: IE doesn't like the source tag not being closed and will throw JavaScript errors; the other browsers don't care. So simply add a closing tag to the source tag and IE is happy. Now, why use a video tag in IE, when IE doesn't support that yet? Simple: The html5media library automatically replaces the video tag in unsupported browsers, such as IE, with the Flowplayer Flash player.

The final result is this; note the closing source tags; also, the MP4 source has to come first for it to work correctly on the iPhone/iPad:
<video id="vid" width="372" height="209" poster="global/vid/historydetectives-poster.jpg" controls preload>
<source src="global/vid/historydetectives.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></source>
<source src="global/vid/historydetectives.ogg" type='application/ogg'> </source>
</video>