Archive for the ‘Javascript’ Category

Building a Video Library with FFMPEG

Tuesday, January 26th, 2010

The video above is imported from http://www.centerforclinicalexcellence.com, for whom I’ve recently constructed a Buddypress Video Library using FFMPEG and the JW Player.

The owners of the site had originally wanted to use a third party like Vimeo or Twistage for this solution, but I persuaded them that they’d achieve a lot more flexibility and functionality if they went with a bespoke solution.

This would allow them to integrate seamlessly with their Buddypress User Database, which was not something that was going to happen very easily with a third party API.

I’m pretty happy with the finished product. Users can upload video, rate videos, comment on videos, embed videos in other sites, and linkback to videos through Facebook and Twitter.

FFMPEG isn’t for the faint hearted, however. It generally doesn’t come installed on hosting platforms, and has a long list of dependencies about which it is very particular when installing.

Normally, you can overcome this by installing through a package manager like yum on CentOS, which I have used before, but the current version of FFMPEG uses a version of libmp3lame (3.98.2, which is used for encoding audio) that contains a nasty little bug that prevents the duration of a clip being embeded in Flash encoded videos.

This in turn plays havoc with Flash players, who don’t know who long the video they are playing will run.

Unfortunately, there is no easy way in yum to specify the version of dependencies you want to use, so you have to go through all of FFMPEG’s dependencies and install them manually, just so you can install a downgraded version of libmp3lame (3.97) which doesn’t contain the bug.

You then need to comile FFMPEG from source.

This is a tricky process, but thankfully I found this article which gives a pretty good summary of what you have to do (there are one or two typos in it, but you’ll catch them as you proceed; and install lame 3.97, not 3.982 as listed). You also need to pay close attention re. the linking of libraries as described, and be sure to run ldconfig.

You can also leave 1 or 2 of the slightly less common codecs if they are giving your errors. The ones you really need are lame, faad, faac and vorbis.

JW Player by comparison is a breeze to install. The license and FB and Twitter plugins were purchased for the very reasonable sum of €77. Its a great player, and I’d recommend it to anyone.

Google Maps and Dynamic IFRAMEs

Wednesday, July 29th, 2009

I recently created an application that displayed a Google Map in an IFRAME in the main page.

The IFRAME itself was created by running a small piece of javascript to populate innerHTML in a specific DIV container.

For some reason, several of the tiles were missing from the page when it first rendered.

After tricking around with this for ages, I eventually came up a solution.

When you insert a Google Map in a page, either in a standard page or in an IFRAME, the map will display according to the geometry of the page. For standard page, the geometry is straightforward, and you generally won’t encounter any problems.

In a page containing an IFRAME things are a little different, particularly when you create the IFRAME on the fly.

Consider this:

A page starts to render. Its a long page, and half way down, some javascript runs to create an IFRAME. This IFRAME then goes off and pulls down a Google Map, but this process starts before the parent page is fully rendered.

Result: Google Map is wonky.

So what’s the solution?

Basically, you just need to insert a little delay into your Javascript to allow the parent page fully render before the Google Map create begins:

eg

setTimeout(js_viewGoogleMap,1000);

If you need to pass co-ords to your map rendering function, just
create an inner function in your primary function:

eg

function js_viewGoogleMap(x,y) {

function loadMap() {

load(x,y);

}

setTimeout(loadMap,1000);

}

Hope this helps.

Variables in Javascript Nested Functions

Thursday, March 19th, 2009

Like many programming/scripting languages, Javscript provides the ability to nest one function inside another function, a bit like this:

function outside () {

function inside() {

window.alert(’Hello World’);

}

}

This behaviour is most commonly seen when a developer needs to assign a function to an event that is created inside another function, for instance:

function outside () {

var menu =document.createElement(’SELECT’);

menu.onchange = function () {

window.alert(’Hello World’);

}

}

One of the difficulties that can arise here is that quite often it is necessary to pass a variable to the inner function. Say for instance, you want to create a 3 SELECTs, each having an onChange event which displays an alert unique to that SELECT. Would this work?

function outside () {

for (i=1;i<4;i++) {

var menu =document.createElement(’SELECT’);

menu.id = i;

menu.onchange = function (i) {

window.alert(’Menu’ + document.getElementById(i).id);

}

}

}

The simple answer is that no, it won’t.

What this execution will do is run the inner function at the same time as the outer function and assign the return value of the inner function to the ‘onchange’ property of the SELECT object, even if nothing is returned.

This isn’t what we want. What we want is for the inner function to be assigned to the onChange event of the SELECT.

There are couple of ways to do this, 3 of which are very well explained in this article.

Here’s one of them. What we do in this case is create a new property for the SELECT object, to which we assign the necessary variables, which we can then reference with the this object reference.

function outside () {

for (i=1;i<4;i++) {

var menu =document.createElement(’SELECT’);

menu.menuid = i;

menu.onchange = function () {

window.alert(’Menu’ + this.menuid);

}

}

}

This method isn’t without its problems either, but it will work in the majority of cases. If you want the Gold Standard solution, check out the referenced article above, preferably from a quiet, well-aired room with a nice view of distant snow-capped mountains (ie its a little complicated…)

The Scriptalizer

Thursday, November 6th, 2008

Given the extended use of Javascript in today’s web applications, one of the best ways to improve site performance is to obfuscate your javascript before it is loaded into the browser.

Trimming white space and new lines can shave as much as 50% from your script file sizes, which can make as significant difference to the initial load delay of your site.

http://www.scriptalizer.com is as good a solution as I have found for this.

You upload your files, hit the button, and wham, all your beautifully formed javascript is compressed into a congealed, but wonderfully efficient, blob in a single file.

Only thing is that you have to insert a bit of logic into your code to load your human readable files in development and the single obfuscated file in Production, because you don’t wanted to have to repeat the obfuscation process every time you want to test a new piece of code, and you certainly don’t want to try and edit the obfuscated file by hand.

Dynamic creation of Flash content

Thursday, March 13th, 2008

Here’s a subject that gets a lot of press in the web development world.

Given the popularity of music and movies on the web, developers need to be able to deliver dynamically created and configured players as a matter of course.

There are a couple of challenges in this. For instance, creating DOM Objects with Javascript isn’t too hard, but creating DOM Embeds is a real nightmare, not least because IE won’t let you append an Embed to any other element, and because IE likes you to re-initialise these objects when you update their parameters.

Then you have the Eolas v. Microsoft issue, which is why you have to click twice on Flash objects in IE before they work.

Finally, you have to deal with all the various browser plugins that attempt to act on media content before any of their competitors, which makes them get up to all sorts of crazy behaviour.

From what I’ve seen, developers approach the dynamic Flash conundrum in one of two ways: they either try and accomplish everything with very long, hopelessly complex innerHTML strings, or they use the SWFObject Javascript library kindly provided by Geoff Stearns who is a Flash engineer with Youtube.

http://blog.deconcept.com/swfobject/

Having tried both myself, I would have to say that SWFObject is the only way to fly.

Its simple to use, its free, its stable in pretty much every browser and it starts Flash objects with a single click in IE, which is really sweet.

You can see it in action on the homepage of www.downloadmusic.ie.

All of the music buttons in the chart are created with SWFObject, but better still, the music buttons in the BATTLE BOX are dynamically created with AJAX and SWFObject. Creating Flash objects with AJAX is all but impossible without SWFObject.

Use it and spend more time with your kids (and thanks to Geoff).

Debugging Javascript with Firebug

Thursday, August 23rd, 2007

Javascript interests me for 2 reasons:

Firstly, in involves a different mindset, in that its client focused, rather than server focused, as is the case with most scripting languages.

Secondly, because its client focused, it involves challenges in terms of browser variations that simply don’t exist with server-side scripting.

The upshot of this is that you have to code Javascript with extended terms of reference, or in other words, ensuring that something works is only half the battle; you also have to ensure that it works everywhere.

That’s why you really need a good debugger, and why the Firebug Add-on for Firefox is a must have for any developer with an interest in Javascript and/or AJAX.

There are a number of issues to deal with when debugging Javascript. Firstly, errors in your Javascript code occur in your browser, so (paradoxically) that can’t be displayed in your browser window like PHP errors, which the PHP parser on your server can create for you and send to you in the HTTP conversation. That’s why Javascript errors generally end up as an icon in your status bar, which, particularly in the case of IE, are as good as useless.

Then there are the errors that are errors in some browsers but not in others, which indicate a use of the DOM which is not necessarily incorrect, just not universally supported.

This is where Firebug comes into its own. Firebug basically lifts the bonnet on everything that is going on behind the scenes in your Firefox browser. For instance, if Firefox makes an XMLHttpRequest as part of some AJAX functionality, Firebug will show what the response was generated by that request.

Firebug will also show you a hierarchical representation for the entire DOM of any given page, and allow you to expose every property and attribute, including CSS attributes, of any DOM element simply by right-clicking on that element in your web page.

Furthermore, Firebug will let you analyse the performance of your page, by clocking the load time if every HTTP request, including images, css files, javascript files and whatever else you page calls.

All of this is achieved in an easily accessed and ergonomic interface which fits neatly into your window when active and into your status bar when inactive.

Of course, the question is how does this help with IE, in that Firebug isn’t available for IE and that errors can occur in the IE DOM that don’t show up in Firefox. An example of this would be where Firefox allows you to set a DOM event like ‘onClick’ with the setAttribute function whereas IE doesn’t (IE is probably more correct in this regard; Firefox is just being nice).

One answer to this question could be: “Why not get an IE Javascript debugger?”, but as with the answer to most IE development questions, you’re going to have to get our your credit card, which is a really big ask when you know that Firebug is Open Source and probably a far better debugger than anything you can buy for IE.

A better answer is that you can use Firebug/Firefox in parallel with IE. Basically, this involves testing pages in IE and Firefox at the same time. Where universal errors occur, Firebug will pick them up and allow you to fix them for both broswers, and where browser specific errors occur, you can at least examine what is going on via the Firebug interface, which, most of the time will point you to where your browser specific error is occuring.

Another point to bear in mind is that IE 7 is a lot closer to Firefox/Mozilla than any other IE browser when it comes to DOM and Javascript issues, so having Firebug in the bag is just about a no-brainer at this stage.

You can get Firebug (and read a bit more) from here:

http://www.getfirebug.com