Radio Pop: social radio listening from BBC Radio Labs

Radio Pop homepage

Today we launched Radio Pop, a social network around BBC radio. Its a project which has been around for over a year now and its great to finally get it out for people to start playing with. Listening to BBC radio through Radio Pop gives you some (hopefully) interesting information and what you’ve been listening to and what your friends have been listening to. When you hear something you really like you can ‘pop’ it - that’s Radio Pop vernacular for bookmark ;)

The Radio Pop site is about displaying your listening, your friends’ listening and everyone’s listening. Your profile displays your recent activity along side your favourite stations and programmes (or brands to be more specific). Here’s my profile:

Radio Pop profile

It also displays what you’re currently listening to so anyone visiting the site can see what you’re up to.

Radio Pop listening to

At the moment, we’re not doing all that much with all this listening data but in the future we are looking to provide recommendations and personalisation (no self-respecting web app can be without them!) and perhaps more integration with other BBC services. In fact its a good point to make that Radio Pop would not be the service it is without our excellent BBC programmes catelogue which provides us with schedule data and unique IDs for every programme, series and brand. While we’re not using the data in interesting ways as yet, we set out to make Radio Pop accessible and extensible so you can use your data for your own apps and mash ups.

For example, here’s my profile (including what I’m currently listening to): http://www.radiopop.co.uk/users/fridayforward.xml.
And here’s my recent listening:
http://www.radiopop.co.uk/users/fridayforward/listens.xml.
Its also available as an RSS feed.

I built an example app using user profile data so you can tell your blog readers what you’re listening to:

Check out the API documentation for more information on our feeds. The blog badge is available from the extras page where you can find an OS X widget which allows you to listen to BBC radio through Radio Pop from the comfort of your desktop.

Radio Pop desktop widget

So that’s Radio Pop. But how does it all work?

Radio Pop is a Ruby on Rails application (because that’s where our experience lies) which runs on nginx with the fair proxy balancer module and memcached caching (because its needs to handle a large number of requests). We support OpenID for login (along side a standard username and password) as well as OAuth for communication between Radio Pop and any clients which post data to it (including the desktop widget). This means we have an input API as well as an output API, should you want to build an on-demand Radio Pop player… ;)

Tracking your listening is done quite simply, through a ‘pulse’ sent every 60 seconds. When you change the station you are listening to or listen over a programme boundary, the pulses are combined into a single ‘listen event’. Once this happens it will appear on the graphs on your profile and in your listening history. When you stop listening (and therefore stop sending pulses) a listen event is created after 5 minutes of inactivity.

I should point out that a lot of the initial development for this version of Radio Pop was done by Mint Digital, who worked from our initial internal prototype. Thomas from Mint also advanced my Rails and nginx knowledge ten-fold. At least.

Please check it out, sign up and start listening.

Run-time class and asset sharing across multiple SWFs in Flex (AS3)

I have recently ported some Flash 8 widgets to AS3 for use in a prototype site we will be launching in the next few weeks. The widgets are all quite simple, displaying graphs, but became fairly heavy due to an embedded font and graphics. All told the four SWFs totalled over 300K so I decided to do some optimisation.

Sharing library assets and classes at run-time means the user can download (and cache) the library SWFs once and use them across the visible SWFs in the page. Doing so has reduced the total footprint to under 100K and has the added bonus of meaning I can change the font for example without having to re-compiled the visible SWFs.

Sharing simple assets

For some of the widgets, access to remote assets was required from more than one class. To achieve this, I wrapped the asset and embedded font classes in classes with static access:

Shared assetsThe static asset access class looks something like this:

package com.fridayforward.sharedAssets {

    public class Library {

        private static _callback:Function;
        private static _assets:LoaderInfo;

        public static function init(callback:Function, url:String="../sharedassets.swf"):void {

            // set callback function
            _callback = callback;

            // load assets
            var request:URLRequest = new URLRequest(url);
            var loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
            loader.load(request);
        }

        private static function onLoaded(event:Event):void {

            // retrieve assets
            _assets = LoaderInfo(event.target);

            // callback
            _callback();
        }

        public static function getAsset(id:String):Sprite {

            // return asset class
            var c:Class = _assets.applicationDomain.getDefinition(id) as Class;
            return Sprite(new c());
        }
    }
}

The assets are loaded in the application constructor, with a callback to continue once assets are available:

package {

    import com.fridayforward.sharedAssets.Library;

    public class Application    {

        public function Application():void {

            // load assets
            Library.init(init);
        }

        private function init():void {

            // now have access to asset library
            // continue with application...
        }
    }
}

The assets can then be accessed from anywhere within the application:

var myAsset:Sprite = Library.getAsset("MyAsset");
addChild(myAsset);

This worked nicely for sharing simple assets but I also wanted to share embedded fonts used in TextFields. To do this, I created a separate AS3 application which contains a class that embeds any fonts I want to share and creates TextFields using them. This class is then made available through a static class to all parts of my applications.

The static Text class looks something like:

package com.fridayforward.sharedFonts {

    public class Text {

        private static _callback:Function;
        private static _textField:Object;

        public static function init(callback:Function, url:String="../embeddedFonts.swf"):void {

            // set callback function
            _callback = callback;

            // load assets
            var request:URLRequest = new URLRequest(url);
            var loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
            loader.load(request);
        }

        private static function onLoaded(event:Event):void {

            // retrieve assets
            var tfClass = event.target.applicationDomain.getDefinition("EmbeddedTextField") as Class;
            _textField = new tfClass();

            // callback
            _callback();
        }

        public static function textField(text:String, size:uint, color:uint=0, ...):TextField {

            // pass to EmbeddedTextField object
            return TextField(_textField.textField(text, size, color, ...));
        }
    }
}

The root class of the EmbeddedText application simply acts as a wrapper to allow access to the contained EmbeddedTextField class:

package {

    import com.fridayforward.sharedFonts.EmbeddedText;

    public class EmbeddedText extends Sprite {

        public var embeddedTextField;

        public function EmbeddedText():void { }
    }
}

The EmbeddedTextField class provides the functionality to create TextFields:

package com.fridayforward.sharedFonts {

    import flash.text.AntiAliasType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;

    public class EmbeddedTextField {

        [Embed(source="...VAG Rounded BT.ttf", fontName="VAG", mimeType="application/x-font")]
        private var vagFont:Class;

        public function EmbeddedTextField():void { }

        public function textField(text:String, size:uint, color:uint=0, ...):TextField {

            var format:TextFormat = new TextFormat();
            format.font = "VAG";
            format.size = size;
            format.color = color;

            var tf:TextField = new TextField();
            tf.text = text;

            return tf;
        }
    }
}

This is then accessed in the same way as before:

package {

    import com.fridayforward.sharedFonts.Text;

    public class Application {

        public function Application():void {

            // load assets
            Text.init(init);
        }

        private function init():void {

            // continue with application...
            addChild(Text.textField("Application Title", 20, 0));
        }
    }
}

If you have a large library of assets you need to load it might be a good idea to display a preloader while waiting for them to download.

Resonate

Last month, Tom Kershaw and I worked on a project for Silent Studios called Resonate. Resonate represents the studio’s music services and the web site showcases it very nicely, accompanied by some beautiful illustrations.

Resonate logo

The site is written in AS3 and uses a page template structure so that any additional pages or structure changes can be done very easily. If you look closely when you load the site or resize your browser window, you should spot my favourite feature: the lines slowly redraw to the edges :-)

BBC Content API

I haven’t written anything for a while because I have been busy getting into the swing of things at BBC Radio & Music. But it is now appropriate to talk about the last project I was involved in at BBC R&D.

The navigation team are concerned with all things to do with finding content and navigating in and around it. A lot of work over the last few years has involved the standardisation of TV-Anytime, a rich method for describing content. Through this we produce a fairly stable stream of live programme data. It seemed a logical progression to make this data available to the public to play with through BBC backstage.

I thought it would be another logical step to build a service around out data, to allow more developers to get their hands on it and to make it as accessible as we possibly could. The BBC Web API (beta) was born.

Before I continue to should point out the scope of this project. We set out to build a simple web API, borrowing the package structure of Flickr and built on a solid foundation of TV-Anytime data. The current offering is very much beta and no guarantees are made as to its stability or accuracy but the core is there to build on. It has been noted that TV listings are possibly the next data feeds to make their way in to the mash-up mainstream and I believe the BBC should be the first to offer a suitable API.

The API offers a handful of methods which return channel, programme, genre and grouping information. You can also retrieve programme and channel stream locations where available. Methods return XML but all results have been wrapped up in XSLT to make them more human-readable. Have a look at this example for getting what’s on now and next. You can also get the full-blown TV-Anytime response if you would like even more information.

As part of the project I set about creating some demo applications to show off the API functionality. I tried to write the documentation in such a way as to offer help to bedroom developers unsure about using the API and these demos are a good place to start. These are not polished applications and I’m sure the team will be keen to see what people can do with the data (good, wholesome non-commercial use only of course).

With the BBC iPlayer currently in development and the creative archive being made publicly available, access to BBC content will become wider and deeper. This API is another step in the right direction.

ProgrammableWeb.com have since catelogued and written up the API

Overall, it’s a good looking, straightforward API. Will be interesting to see what sorts of mashups folks build with this.

I couldn’t put it better myself.

Annotatable Audio project

I have been part of a very exciting project in BBC Radio & Music interactive. The project was lead by Tom Coates and the team was made up of myself, Tristan Ferne, Helen Crowe, Paul Clifford and Bronwyn Van Der Merwe. The project is best summed up by Tom at plasticbag.

I am resposible for the Flash interface part of the project and am very pleased with the feedback it has got from fellow Flash developers and the wider web community. I learned a great deal in the short amount of time I spent developing the app and there isn’t a significant amount of work which needs to be done before it is a fully usable interface. Helen’s JavaScript skills allowed us to use Flash only where necessary and provides communication from the database, through Flash, to the page. As a team we recognised the power of Flash but also that it should not be over-used.