Showing posts with label EOLAS. Show all posts
Showing posts with label EOLAS. Show all posts

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.

Tuesday, 1 September 2009

Opera 10

Opera 10 installation

Even though Opera counts for a tiny percentage of the traffic on my main sites its still a level 1 supported browser along with IE, Firefox, Chrome and Safari and therefore when new versions come out some time is spent investigating the browser and checking how our sites look and hunting down any bugs caused by new features being added or old ones being removed from the script engine.

Today it was Opera 10's turn and I must say the whole experience of just installing the browser was very disheartening. It took a long time just for the download opera button to actually do anything and then you have to pick a mirror to download from which took ages in itself and it was a good half hour before the 3 of us all had installed the browser.

One of the new features is its Turbo option which apparently helps speed up delivery of sites on slow networks through compression techniques. There are 3 options on, off and automatic which detects the speed of the connection and enables or disables the feature. I found that I couldn't actually get the option to enable for the first few attempts as it kept coming back with "could not connect to server" errors, which server I do not know as the actual site I was viewing loaded okay.

Once enabled however I found that on sites where flash is used you will be met with some hilariously over sized play buttons depending on the size of the flash movie. We have a peel over advert on some sites and the play button that appeared was almost a third of the page! It seems with Turbo enabled Opera will only download the bare minimum required to get the page to load and then if you want flash to play you have to hit the over sized buttons. Javascript as well takes a very long time to load with this feature enabled which I suppose it because it is also one of the last things to be loaded so that the page loads quickly, or appears to.

I also didn't realise that the EOLAS patenting issue hadn't been resolved in Opera like it had in Internet Explorer as unless you output flash with Javascript or use a script to reinsert the flash objects you will have to click the object before it will play. I was under the impression this had been resolved but apparently only IE has sorted this so if you are serving flash server side you will need some JS code to re-insert the OBJECT / EMBED tags into the DOM.

Opera seems like a nice browser however there are much better ones in my opinion and they shot themselves in the foot for so long by charging for it and I doubt there market share will ever rise above Firefox, Safari, Chrome or IEs. However it just has enough of a share that warrants me having to spend time getting my sites to work in it so until it drops off the chart I will be having to do these checks quite regularly.

Tuesday, 7 October 2008

Is there any point anymore using Javascript to output Flash?

Using Javascript to load Flash.

Because of the well known Eolas patent issue regarding Internet Explorer and users having to click to activate Flash content a number of Javascript libraries has emerged to get round this problem e.g swfobject, UFO. The reason being that any Flash content loaded up through script was not affected by this patent issue and the user did not have to click anything.

I along with many others implemented generic functions to get round the "click to activate" problem. However since March of 2008 the issue has been resolved and current versions of Internet Explorer and any previous versions that have had patches applied to them do not have this issue. Therefore I am wondering whether there is any point in having Flash content delivered through Javascript rather than Server side code?

The main reason for doing it this way has been removed and by using Javascript to load all Flash you are narrowing your user base. More and more users are crawling the web with Javascript de-activated and I imagine that in this security conscious times we live in that this percentage will only increase. Checking my logged traffic statistics for today I can see that 10% of my sites non crawler users have Javascript disabled so this is quite a large number of users that won't be able to see all those Flash adverts and banners that your customers have paid £££ to place on your site.

Therefore in any new sites that I create I am reverting back to generating the Flash HTML server side unless there is a need for client side user interaction such as when I use flash for text counters. I am using the same XHTML that SWFobject and others have started doing which checks the users browser type and outputs the relevant OBJECT code accordingly i.e classid and codebase for IE and type for the others. This removes the need for embed tags and is still XHTML compliant plus its done server side so there is no issue when users turn Javascript off.

<object type="application/x-shockwave-flash" data="/images/Banner.swf" id="BANNER643" align="middle" width="468" height="60">
<param name="movie" value="/images/Banner.swf">
<param name="allowScriptAccess" value="sameDomain">
<param name="quality" value="high" />
<param name="wmode" value="transparent">
</object>


If the users browser is Internet Explorer I output a Javascript function call at the bottom of the page that will "fix" any OBJECT tags so that any users that don't have patched versions of IE and so still ask the user to "click to activate" will not have this problem as long as they have Javascript enabled.

A simple version of the EOLAS fix code is below although I am currently using a more advanced option that handles complex OBJECT params alot better.

objects = document.getElementsByTagName("object");for (var i = 0; i < objects.length; i++){objects[i].outerHTML = objects[i].outerHTML;}


All my users should get this content and only the unpatched Internet Explorer users who have Javascript disabled will have the inconvenience of being asked to "click to activate".

It would be nice to be able to detect whether Internet Explorer users had patched or unpatched versions so that I could only run the Javascript fix code if it was absolutely necessary but I cannot think of a way to determine this. I was thinking of maybe trying to access the first flash movie on a page and check the PercentLoaded property which must be unavailable if the flash movie is unactivated. However using the multiple IE version hack to run IE 6, 5 etc you always get a pop up saying "Press okay to continue loading content" when a page contains Flash so I cannot test this out. Either way this seems the best way to code Flash for the future as it ensures the maximum user coverage and still handles the EOLAS patent problem for those IE users who have not updated.

If anyone can think of any other reasons to be using Javascript and limiting your user coverage then please let me know.