Showing posts with label embed. Show all posts
Showing posts with label embed. Show all posts

Sunday, 21 November 2010

Auto Resizing OBJECT and EMBED videos for display on import

Importing Videos from feeds into blogs

I have done a lot of work lately updating the popular WP-O-MATIC wordpress plugin that auto imports content into Wordpress blogs from feeds.

Mainly this is because the plugin is no longer supported having been taken over by the product WP Robot which seems to be based on the original source but with a lot more features.

One of the main things I find myself doing is having to resize videos so that they fit into my content which is 520 px wide. If you are importing content from various other blogs you can never guarantee that the videos will always be of a similar size and if you want your blog to look nice and not have scrollbars everywhere then the best way is to reformat the imported content so that any videos are resized to your desired dimensions.

As Wordpress and WP-O-Matic is PHP I use the preg_replace function to accomplish this using the callback function to handle the formatting. It looks for OBJECT or EMBED tags where the width is over 500px and if any are found I resize to 500 * 375 (4*3 ratio).

The function is below.

$content = preg_replace_callback("@(<(?:object|embed|param)[\s\S]+?width=['\"])(\d+)(['\"][\s\S]+?>)@i",
create_function(
'$matches',
'if($matches[2] > 500){
$res = preg_replace("@ height=[\'\"]\d+[\'\"]@i"," height=\"375\"",$matches[1] . "500" .$matches[3]);
}else{
$res = $matches[1] . $matches[2] .$matches[3];
}
return $res;'),$content);




Saturday, 27 February 2010

Handling YouTube Videos in Feeds

Reformatting HTML to include YouTube video links

If you use XML feeds to import content into your site or blog you may have experienced the problem that your blogging software or add-on tries to err on the side of caution for security reasons or just messes up the import and in doing so any EMBED or OBJECT tags are stripped in the process.

This is especially annoying when the content is for a blog or news site and the imported content was linking to YouTube videos as it means you have to go through all the posts by hand and reformat the HTML so that the original video is shown.

Luckily even though the actual OBJECT tag gets removed you are usually left with a link to the video on YouTube's site. This can be utilised in a simple regular expression so that you can reformat your content and replace this link with the actual OBJECT HTML.

The regular expression is pretty simple and looks for any anchors pointing to YouTube's site and captures the video ID in a sub group. This sub group is then used in the replace statement as the value for the PARAM and EMBED values that require it.
// use preg_replace to replace anchors with OBJECT/EMBED
// $input is the source HTML

$html = preg_replace("/<a href=\"http:\/\/www\.youtube\.com\/watch\?v=([A-Z1-9]+)\">[\s\S]+?<\/a>/i","<object width=\"425\" height=\"344\"><param name=\"movie\" value=\"http://www.youtube.com/v/$1&hl=en_GB&fs=1&\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://www.youtube.com/v/$1&hl=en_GB&fs=1&\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"425\" height=\"344\"></embed></object>",$input);

I am using PHP as an example here but the regular expression would be the same across all languages.

Either wrap a call to this function in your own import procedure or if you are using an add-on like Wordpresses WP-o-Matic then you should utilise it in the rewrite section when setting up a new feed import.


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, 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.