Exploring the Universal Plug and Play Architecture

Install and Configure

To install the BRisa UPnP framework on your computer:

  1. Download the latest BRisa framework package [7].
  2. Decompress the BRisa framework package as root:

    tar zxvf brisa-{version}.tar.gz
  3. Go to the BRisa source code directory:

    cd brisa-{version}
  4. Run the BRisa installation:

    python setup.py install

It is also a good idea to install the BRisa configuration tool, which is available at the BRisa website. The configuration tool will save you from having to edit configuration text files by hand.

After configuring the BRisa media server, you can start it by simply executing the command brisa-media-server on a terminal, regardless of the current directory you are in. Similarly, you can start the BRisa media renderer with the command brisa-media-renderer. The configuration tool allows users to change their media server default parameters and the installed plugins. (Plugins provide additional functionality not found in the default media server. For example, the Filesystem plugin lets you set up filesystem directories in which the BRisa media server will share your audio, video, and image files.)

If the BRisa media server starts correctly, you'll see the message shown in Listing 1. If you don't see this message, check the brisa.log file to see if you can detect the problem. If the problem persists, contact the BRisa team [9] or try the troubleshooting section of the BRisa documentation [10].

Listing 1

BRisa Media Server Startup Message


Developing a UPnP Control Point

After you have installed the BRisa UPnP framework, you can use the framework to develop a simple command-line UPnP control point. The control point API lets you create a control point class and inherit from either the brisa.control_point.control_point.ControlPoint or the brisa.control_point.control_point_av.ControlPointAV class, depending on your purpose. The control point example shown in Listing 2 searches UPnP devices, browses for multimedia items in a given media server, and asks for a media renderer to play an audio file shared by the media server.

Listing 2

Command-Line Control Point


In line 5 of Listing 2, the class CommandLineControlPointAV inherits from the BRisa class brisa.control_point.control_point_av.ControlPointAV. All available multimedia methods specified by the UPnP AV specification and provided by the class brisa.control_point.control_point_av.ControlPointAV are thus also used by the CommandLineControlPointAV class. This example creates the run() class method that reads continuously from the command line using the Python built-in raw_input() function (line 55).

Depending on the command line typed by the user, the application takes a specific action (lines 57 to 76). The possible actions are associated with the user commands start_search, stop_search, list_devices, set_server, set_render, browse, play, exit, and help.

The start_search and stop_search user commands just delegate a simple call to the respective methods available in the brisa.control_point.control_point_av.ControlPointAV class. When the user types the command list_devices in the prompt, the method CommandLineControlPointAV.cmd_list_devices() (line 22) is invoked. This method prints the list of the UPnP devices discovered since the first time the start_search command was run by the user.

BRisa's UPnP framework provides four important bits of information about the discovered devices: the device's UDN, which is an exclusive identifier for the UPnP device in the network; the device type, which tells whether the device is a media server, a media renderer, or some other UPnP device; a list of services provided by the device; and the Friendly Name, a short, more convenient name for the device.

The set_server and set_render commands specify the media server and media renderer, respectively. While you are using the control point infrastructure of the BRisa UPnP Framework, the BRisa Control Point API can notify your application about any new UPnP device that connects to the network.

In Listing 2, lines 9 and 10, I have used the brisa.control_point.control_point_av.ControlPointAV.subscribe() method to tell the BRisa Control Point API to notify the CommandLineControlPointAV class when a new UPnP device has been discovered and also to notify this same class when a UPnP device has left the network. The notification for both events is performed by the BRisa Control Point API by calling the subscribed callback functions CommandLineControlPointAV.on_new_device() and CommandLineControlPointAV.on_remove_device(). Note that because of Python's inheritance mechanism, the class CommandLineControlPointAV inherits the subscribe() superclass method.

The browse command allows the application to browse a specific item in the media server, and the play command sends a play request to the media renderer. The class method CommandLineControlPointAV.cmd_browse() is invoked when the command browse is typed. The cmd_browse() command makes use of the browse() superclass method to retrieve information on the item from the current media server.

A similar process occurs with the play() superclass method, which makes use of a media renderer previously selected by the user to play the specified multimedia item. Listing 3 shows how to use this UPnP control point.

Listing 3

Using the Command-Line Control Point


Developing a BRisa Plugin

The BRisa framework comes with a ready-made media server. Rather than create a new one from scratch, you can adapt the BRisa media server with the use of plugins. Next, I will show you how to develop a simple YouTube plugin for the BRisa media server. A full implementation of a YouTube plugin is provided by the BRisa Project.

The BRisa media server plugin architecture (Listing 4) allows the addition of new plugins based on the abstract class called Plugin. Once you have created your own classes that inherit from the brisa.services.cds.plugin.Plugin class, your class becomes a BRisa media server plugin, and you should provide the implementation for the abstract methods load(), unload(), browse(), search(). The most important methods are the last two, which make the plugin capable of responding to remote browsing or searching for multimedia items.

Listing 4

BRisa Plugin Structure


The BRisa UPnP framework provides a configuration API that allows retrieval of values from a configuration .ini--style file. The default configuration file for all parameters used by the BRisa UPnP Framework and its applications is stored in the file ~/.brisa/brisa.conf. Therefore, if you need to store and retrieve configuration parameters, you should use the BRisa configuration API.

BRisa's Content Directory subsystem detects and loads the plugin. The Content Directory also delegates the browsing and searching requests when the BRisa media server receives a request from a remote control point to retrieve the multimedia items shared by any installed plugin.

To deploy your plugin after you finish implementing it, simply create a folder named my_plugin under the directory $PYTHON_DIR/site-packages/brisa/services/cds/plugins and save your plugin class in a file called implementation.py directory. The BRisa media server will automatically load and export the content shared by your plugin through the BRisa Content Directory subsystem. This mechanism is illustrated in Figure 2.

Figure 2: The BRisa Content Directory subsystem manages information on available data.

As shown in Figure 2, the plugin can use any kind of storage mechanism to store its contents. When a browsing action arrives from the network (step 1), the BRisa Content Directory subsystem redirects the browsing to the correct plugin (steps 2 and 3).

The plugin properly handles the browse request and returns the multimedia items to the BRisa Content Directory subsystem (step 4). The Content Directory subsystem gets the returned list of multimedia items and formats them into an XML-specific standard known as DIDL (Digital Item Declaration Language) (step 5). DIDL is used to represent complex digital objects [11].

Finally, the BRisa media server gets DIDL-XML content, wraps it up into a SOAP message, and sends it back to the remote control point that formats the output in the device screen. On the basis of this extensible architecture, the BRisa media server offers the deployment of third-party plugins that can share multimedia data from a specific source. For more about plugin development, see Section 10 of the BRisa developer documentation [10].

Listing 4 presents a simple plugin class stub. Note that the class MyOwnBRisaPlugin inherits from the class brisa.services.cds.plugin.Plugin. As an example of a real plugin for the BRisa media server, Listing 5 shows the most important part of the YouTube BRisa media server plugin. In Listing 5, a third-party module is used to retrieve YouTube items from the YouTube website. The youtube_api and youtube_dl modules are imported in lines 1 and 2 and are used to retrieve video information and download the .fla file. Around lines 30 and 33, the class YoutubePlugin inherits the BRisa plugin class (as in Listing 4). A BRisa media server plugin has three important attributes: an id that uniquely identifies a plugin, the name that is a short description of the plugin, and a usage that indicates to the BRisa media server whether it should load the plugin automatically.

Listing 5

BRisa YouTube Plugin


The class method _register_plugin(), line 39, is used to register a plugin folder (formally known as a UPnP media server container) in the browse tree of the BRisa media server. Note that in Listing 3, the browse command is executed three times: browsing folder 0 (root folder), then browsing the video folder (id 2), and then the videoBroadcast folder (id 5), where the YouTube folder plugin is registered.

Line 40 (Listing 5) registers the YouTube plugin folder under the folder VideoBroadcast. Note that the YouTube plugin uses the BRisa RootPlugin to register its folder. The RootPlugin is a special Content Directory subsystem plugin that creates the default containers of the BRisa media server (Audio, Video, and Pictures), as shown in Figure 3.

Figure 3: Using the Canola control point to browse the YouTube plugin folders.

Each item of the default containers is statically identified by an id. The id for VideoBroadcast is 5, which corresponds to the third parameter passed to the method add_container() provided by the RootPlugin. From line 41 to 50, the plugin method load() loads all the user's uploaded videos and stores them in the list of videos represented by the videos attribute of the plugin. In line 45, the plugin makes use of the BRisa Configuration API. Finally, the method browse is called by the Content Directory subsystem when the user sends a browse request to youtube:7 and returns the list of videos loaded by the plugin (Listing 3).

To identify the YouTube folder Content Directory, the subsystem combines the plugin attributes id and name, which is why the result produced for the YouTube registered folder is youtube:7. This same idea relates to the YouTube shared items, such as youtube:hDiLH7jmVsU, used in the example shown in Listing 3. In this manner, when the Content Directory Subsystem receives a requests for the tuple youtube:hDiLH7jmVsU, it splits in two parts at the ":" character, which permits it to identify the plugin and the requested item specified by the control point.

After you finish implementing your plugin, you must create the directory my_youtube_plugin under the directory $PYTHON_DIR/site-packages/brisa/services/cds/plugins, put your plugin source code in the file implementation.py, and save it under the directory you created.

The BRisa media server will load your plugin automatically, and you can now use the UPnP command-line Control Point example or create a more elaborate control point to browse your shared items using the Canola Media Player. Figure 3 shows a list of videos shared by the YouTube plugin.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Video Streaming

    Thanks to protocols such as UPnP and DLNA, video, audio, and photos are distributed to TVs, gaming consoles, PCs, and smartphones without the need for configuration. Linux as a central media server is a welcome guest.

  • Seamless Integration Intro

    Yes, you can do that with Linux… Even if you want to live in an open source world, it's still full of Windows. This month we study strategies for Windows integration.

  • Qt for Maemo

    Write your own smartphone apps with Qt's toolkit for the Maemo platform.

  • Media Centers

    Beyond MythTV and VDR are media centers that take a new approach – or at least make the beaten track look a little different.

  • Free Media Centers

    Free and commercial media center programs promise streaming HD videos, television, music, picture galleries, and a few extra tricks for Linux PCs and the Raspberry Pi – all from the comfort of your living room.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More