A few weeks ago, I finally got around to realising a long-held ambition; I built a media center PC. Hardware has come a long way since the last time I tried to have a PC permanently hooked-up to my TV; Composite TV-out has been replaced by HDMI-out. Analogue TV tuners with pass-through audio have been replaced by digital TV tuners that can dump raw digital video straight into a recorder. Processors are now capable of encoding 720p video while simultaneously playing back other media. And how could I fail to mention Windows Media Center itself, to bring everything together on the big screen? In short, this is a really exciting time to own a media center. It’s also rather an exciting time to look into developing add-ons for Media Center.
Over the next few weeks, i’ll be learning the ins and outs of the Media Center SDK, version 6.0 (for Windows 7), and hopefully producing a few add-ons in the process. Don’t get me wrong, Windows Media Center is a great front-end, but the functionality offered is very focused and targeted. There is an enormous scope for add-on functionality, both to address genuine needs/shortcomings and to provide a richer, more entertaining experience.
Some objectives I have for my media center PC over the long term include:
- Pulling down new media from other networked PCs
- Simplifying the process of tagging and organising the media library
- Playing streaming radio stations (a feature seemingly unavailable to Australian users)
- Displaying song lyrics while music is playing
- Accessing twitter/RSS feeds
The Media Center SDK
First up, the SDK provided by Microsoft for Media Center is .NET-based. If you really wanted to, you could develop a hybrid native/managed assembly using C++/CLI, but it really lends itself to C#. The SDK heavily enforces the MVVM architectural pattern – to the point where it is actually impossible to instantiate Media Center UI objects from code. This creates a heavily sandboxed environment, but there are no restrictions on functionality; only on presentation. All visual elements of a Media Center add-on must be written in the XML-based Media Center Markup Language (MCML). MCML can be thought of as a distant cousin of WPF; the markup consists of visual elements, animations, properties/variables, data bindings and rules to create interactivity. The principal difference is that MCML defines only a small handful of visual primitives and has no built-in controls – everything must be constructed and tailored to the application’s needs.
So, a typical add-on written using the Media Center SDK consists of:
- A .NET assembly (class library) containing the application (and data access) logic. The assembly must be installed in the GAC. The minimum requirement is that a class in the assembly implements the IAddInModule and IAddInEntryPoint interfaces. The Launch() method must navigate to the first MCML page.
- MCML markup representing the page(s) that make up the user interface of the add-on. Since all files are referenced using absolute URIs, it’s reccommended that markup be included inside the add-on assembly as a resource. (Resources can be accessed using special URIs, e.g. resx://Assembly/Assembly.Properties.Resources/Resource)
- A registration file (XML-based), which can be passed to RegisterMCEApp.exe (included with Media Center). This specifies how the add-on is launched from within Media Center.
Note: It’s also possible to write background applications which have no UI and web applications which are entirely markup-based and make use of remote resources.
What you can do with the SDK:
- Add new areas/screens to Media Center
- Use the Media Center environment as the presenter for your application
- Play and control media already supported by Media Center
- Navigate around the existing Media Center UI
- Control and interact with Live/Recorded TV functionality
- Control and interact with CD/DVD burning functionality
- (Indirectly) access the user’s media libraries (the user can supply your add-on with items from the library)
What you cannot do with the SDK:
- Change existing areas/screens within the Media Center UI
- Directly access/control the viewport or audio/video streams
- Add support for formats which Media Center cannot ordinarily play
- Directly access the user’s media libraries (search/browse)
Add-ons which achieve any of the above behaviour typically do so by displaying their own window on top of the Media Center UI.
In addition to Visual Studio, you will typically use the following (included with the SDK):
- XML Schema Definitions (XSD files) for the MCML format – adding these to Visual Studio makes authoring MCML files significantly easier.
- Media Center Preview Tool – can be configured to run after compilation in Visual Studio. The tool previews markup and most basic functionality.
- Windows Media Center – you can set debugging options within Media Center itself. You will need to use the real Media Center app in order to see your markup against a background, and whenever you reference types in the SDK relating to the Media Center environment or add-in host.
Additionally, I find Resource Hacker to be very useful in identifying built-in resources (images, sounds, markup) that can be used in add-ons in order to create the impression of seamless integration.
For my first foray into the world of Media Center development, I am writing an add-on for browsing the network and copying files to the media PC. Although it is possible to add shared locations to the media library, it is often desirable to copy content to the local machine instead – and while this can be done from the remote PC, it’s useful to control and monitor the process from the destination.
The back-end code for the add-on is fairly trivial; I will be using some Win32 API calls in order to enumerate networked computers and shares, but browsing within a share requires only the standard methods on the Path, File and Directory classes in System.IO. Additionally, I will be using the WebClient class in System.Net to actually copy the files, as it supports asynchronous downloading with progress indication.
The real challenge lies in the learning curve associated with MCML. My goal is to match the standard look-and-feel of Media Center as best as possible, however, without any built-in controls I will have to learn how to build appropriate UI elements using the techniques available. In particular, my add-on will need buttons, list items, a busy indicator and a progress bar.
At the time of writing, I have a functioning prototype of the add-on; however, I wish to detail and document its development further before sharing the implementation here.
Stay tuned for the next instalment of the series, where I will be looking at building the controls and visual elements required for my Media Center add-on, with a focus on matching the standard look-and-feel.