Sunday, 8 November 2009

Displaying Flash and Video content

The various methods of outputting flash and video content

I was looking at some YouTube videos earlier and the code that they use to allow users to embed the movies into other HTML has changed. I know it changed quite a while back actually but it got me thinking about the various methods for displaying video content on the web.

I am pretty sure that they used to use the old combo method which used to use an outer OBJECT tag designed to work in IE with classid and codebase attributes and then some PARAM tags and then an EMBED tag to handle all other browsers. Even though EMBED works across browsers its not a standard compliant method for displaying content however because it works across all browsers its used everywhere.
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" data="http://www.youtube.com/v/FrYlNNy929Y&hl=en&fs=1" align="middle" width="425" height="344" >
<param name="movie" value="http://www.youtube.com/v/FrYlNNy929Y&hl=en&fs=1" />
<param name="allowFullScreen" value="true"></param>
<param name="allowScriptAccess" value="sameDomain" />
<embed src="http://www.youtube.com/v/FrYlNNy929Y&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>

The way they do it now is to have a very bare outer OBJECT tag and then some PARAMS and an EMBED tag. Rather than reference the movie source in the OBJECT's data attribute its only referenced in the PARAM and EMBED tags.
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/FrYlNNy929Y&hl=en&fs=1"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/FrYlNNy929Y&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>

Now I know there are a multitude of ways of delivering movie content on the web and you can deliver it server-side or client-side with one of the libraries such as SWFObject or UFO or the new combination of those two and Adobe SWFObject 2.

I tend to do my delivering server-side mainly for the reason that at least 10% of users have Javascript disabled when they surf the web therefore that is quite a large audience to skip over. To keep to standard XHTML I was going down the route of copying what the Javascript libraries do but server-side e.g
  • Check for browser type e.g IE, a known standard compliant browser or Unknown
  • For IE deliver the OBJECT method with classid and codebase
  • For non IE deliver the OBJECT method with type application/x-shockwave-flash
  • For unknown deliver the nested method OBJECT and EMBED
  • Load some Javascript to handle the EOLAS patent issue for Opera (IE has fixed this)
Therefore we keep to the standards and get maximum audience coverage. For users of Opera with Javascript enabled they will play normally but those without they will have to click them to play. Although an annoyance this is a smaller percentage than the 10% who would have no flash play due to Noscript being enabled etc.

Another introduction to the current myriad of ways to deliver movie content is the new VIDEO tag which is now being supported by Firefox 3.5, SeaMonkey 2, Thunderbird 3 and Chrome 3. Currently it supports limited filetypes such as Ogg Theora which is an open format and you can reference a movie pretty simply which the following syntax shows.
<video id="video6" src="http://www.dailymotion.com/cdn/OGG-320x240/video/x9euyb?auth=1269605698_a8b629faf0d043e1b538971997ff9ba5" width="425" height="344"></video>

Accessing video content through Javascript

If you are loading all your video content through Javascript which a lot of people do then although you may be missing 10% of your audience you won't have to worry about the EOLAS issue in Opera and you will have a variety of functions in your chosen library to access the movie and manipulate it.

However if you are loading your flash server side like me you still may need some Javascript functionality to access the movie and check whether it has loaded or not.

The following code contains two functions which can be used to access a movie delivered by an OBJECT, EMBED or VIDEO tag cross browser and should handle very old browsers as well as it has an extensive fallback.

The other function lets you check whether a movie has loaded yet which you may want to do before making controls available to manipulate the movie or as I do with my flash bullet counter starting the movie and moving it to a certain frame.

function getMovie(movie){      
var r = null;
// try for standards way of accessing movie through OBJECT tag if you use the new ADOBE/SWFObject JS library
// to create your flash then this will work.
var o = document.getElementById(movie);
if(o){
if (o.nodeName == "OBJECT") {
// check SetVariable this could return undefined, unknown or function depending on browser
if (typeof o.SetVariable != "undefined") {
r = o;
}else{
var n = o.getElementsByTagName("object")[0];
if (n) r = n;
}
// handle the new VIDEO tag which plays Ogg files and can handle multiple fallbacks
}else if(o.nodeName == "VIDEO"){
r = o;
}
}
// if we still have no flash movie revert back to old tried and tested methods.
// these are used when you deliver your flash server sides in certain browsers
if(!r){
// access the window or document object
r = (document[movie]) ? document[movie] : window[movie];
if(r) return r;

// last resort use the embeds collection
if(document.embeds){
r = document.embeds[movie];
}
}
// return either null or a reference to our movie
return r;
}

// function to test whether a movie has loaded yet
function isMovieActive(movie){
movie = typeof(movie)=="string" ? getMovie(movie) : movie;
// if we have no reference quit
if(!movie) return false;

// default our percent loaded variable to 0 = not loaded
var pl=0;

// for VIDEO tags we can check the readyState property https://developer.mozilla.org/En/nsIDOMHTMLMediaElement
// readyState 3 video can be played a bit
// readyState 4 video can be played to the end without interuption
if(movie.nodeName=="VIDEO"){
return (movie.readyState>=3) ? true : false;
}else{
//if movie not loaded then this will raise an error but if its loaded we can check the PercentLoaded property
try{
pl=movie.PercentLoaded();
}catch(e){}
return (pl==100) ? true : false;
}
}

The following test page has been created to show all the numerous methods of outputting OBJECT and EMBED tags with a test to show which Javascript methods allow access of the movie. Test it in various browsers to see the differences and when viewing in Chrome be prepared to wait a while for the VIDEO content to load which will give you a chance to see the isMovieActive function work both ways. Also the movie is pretty funny anyway so its worth watching as its a fight between a Yoga master and two kung fu fighters.

Labels: , , , , , , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

Links to this post:

Create a Link

<< Home