How it works

This section contains various nitty gritty explanations about how Media Explorer is put together.

MVC

Media Explorer is broadly based on a Model-View-Controller architecture.

  • Model: Media Explorer has a single root model (an instance of MexAggregateModel). A plugin loaded by Media Explorer's plugin manager can push models, each associated with a category, into the root model. A model pushed by a plugin can be a simple MexModel or another MexAggregateModel .

  • View: The top-level view element is an MexExplorer instance. This is a horizontally-expanding, single-row MexResizingHBox, filled with MexColumns; a new column is added each time a new model is added to the explorer; the column title is set to the model's category. Focus moves between columns in response to UI events (e.g. key presses).

    The columns are populated via the controller classes (see below).

  • Controller: A MexContentProxy instance (an implementation of MexProxy) is responsible for generating UI elements for each model. Each time a new model is added to the explorer, a new column is created, and an MxWidget generated and added to the column for each MexContent item in the model (currently hard-coded to a maximum of 10 items per column).

    The default behaviour is for each content item to be represented by a MexContentBox. This is an expanding widget which displays one line of the content item's title, expanding on click to display the full title.

The class hierarchy diagramin the next section should help you identify how the classes mentioned above relate to each other; the API reference gives more detail about the specific methods supported by each class/interface.

Class hierarchy

The diagram below shows libmex's class hierarchy.

Content discovery

Media Explorer enables browsing, discovery and playback of media content; to do this, it needs to have media sources available. The Grilo framework for media discovery and browsing is used to provide those media sources.

Grilo provides a uniform API for accessing content and its metadata. Several Grilo plugins exist for adapting media for well-known sources (Vimeo, Flickr, YouTube etc.) so they can be presented via the Grilo API.

However, due to various licensing issues, these plugins are not enabled by default in Media Explorer. The only plugin which is enabled is grilo-tracker. This uses a Tracker service, running in the same environment as Media Explorer, to make media indexed by Tracker available through the Grilo API.

Tracker itself is a collection of data mining and indexing services, typically used for searching the local filesystem. By default Tracker comes with several indexing services called miners. The most widely used miner is the filesystem miner, responsible for indexing local files. Media Explorer makes use of the UPnP miner, if available, which additionally indexes UPnP servers.

The diagram below gives a high-level overview of the components involved:

The arrows between the nodes in the diagram represent media data from UPnP servers and the local filesystem being scanned, indexed and presented by higher-level components.

Debugging content discovery

This section gives a few tips about how to check that everything is working properly in the content discovery stack.

  • Check tracker is indexing. You can follow the status of Tracker and its miners from the command line with:

    $ tracker-control -FS
                  

    The output should look something like this:

    Store:
    06 Apr 2011, 14:54:52:  ✓     Idle
    
    Miners:
    06 Apr 2011, 14:54:52:  ✓     UPnP                  - Idle (ESMITH5-MOBL1: esmith5:)
    06 Apr 2011, 14:54:52:  ✓     File System           - Idle
    06 Apr 2011, 14:54:52:  ✓     Applications          - Idle
    Press Ctrl+C to end follow of Tracker state
                  

    Note that the UPnP miner is reporting the ID of a Windows laptop running Windows Media Center (which is UPnP compatible).

    If a miner has an "X" against it, there may be something wrong with Tracker's configuration.

  • Check Tracker is indexing the right directories. If your local media aren't showing up in Media Explorer, it may be that they aren't being indexed by Tracker.

    Check that Tracker is indexing directories where some media exists: see these instructions for configuring Tracker.

  • Check Grilo can browse your media. Tracker's directory settings might look right, but media may still not appear in Media Explorer. In this case, ensure that Tracker has actually indexed your media using the grilo-test-ui command. This runs a basic Grilo media browsing interface:

    If your media files have been indexed, they should show up in this interface. If not, Grilo is probably failing to communicate with Tracker correctly.

  • Check detailed logs for Tracker, Grilo and GUPnP. If you haven't identified the issue by following the above steps, you can enable more verbose logging for the various Media Explorer components as follows:

    • Tracker. Set this environment variable:

      TRACKER_VERBOSITY=3

      This turns on all debug messages.

    • Grilo. Set this environment variable:

      GRL_DEBUG=*:debug

      NB this produces a lot of messages; other less verbose debug levels are available (see the Grilo API docs).

    • GUPnP. Set this environment variable:

      GUPNP_DEBUG=true

Binding keys to actions

Media Explorer is designed to function as a netbook application or as a UX for a dedicated media centre distribution. This means that the UX is entirely usable without a mouse. However, it also means that it may be used with input devices other than a keyboard (such as a TV remote control). On top of this, the application may also run in environments where a full X environment is not available (for example, where the application is on a different GDL plane from the X server, as might happen when running on a processor like Intel's CE3100).

Terminology and definitions

  • evdev. The "protocol" which reports events from the kernel to userspace. At its core, this "protocol" is reading a well-defined structure from a file descriptor obtained by opening a /dev/input/event/* file.

  • xorg-input-evdev. The Xorg input driver to feed X with evdev events.

  • lirc. Since the 2.6.36 kernel, lirc, a set of InfraRed device drivers, has been integrated into the mainline and lirc devices are exposed as evdev devices. This means that the issue of handling infra-red controls is now reduced to the issue of handling evdev devices. (Previously, binding key events would have involved handling IR devices and evdev devices separately.)

  • key code (keycode). A number assigned to the physical key. These days, on linux, these are defined in <linux/input.h> and are part of evdev key event structures.

  • key symbol (keysym). The logical symbol associated with the keycode. For instance, 'a' is associated with the keycode 38. On standard linux desktops, Xorg is responsible for the mapping between keycodes and keysyms.

  • libxkbcommon. This library provides control over the keyboard, extending the basic facilities available in X. The project has a public git repo.

The trouble with input device keys

Because Media Explorer is a media browser and player, it may be used in contexts outside the traditional netbook or laptop. This in turn means that users may want to control it with input devices beyond the standard mouse and keyboard, such as TV remote controls, for example:

  1. keyboards, even ones with all those fancy "Internet keys"

  2. remotes that are seen as USB HID devices

  3. IR remotes exposed as evdev devices via in-kernel lirc

However, given the variety of input devices, a couple of issues arise:

  • Some Media Explorer actions (show more info. about some content, select some content etc.) naturally map to a a user's experience with modern TVs, DVD players, CD players, portable music players etc. In turn, a user can map those actions onto typical remote control keys (in the above case, onto Info and OK respectively).

    However, these keys don't always have natural equivalents on a standard computer keyboard; but a user with a standard keyboard should still be able to control Media Explorer. So there needs to be some way to map actions (and their keys on a remote control) onto standard keyboard keys.

  • While remote controls are familiar to users, they bring a different set of issues when applied to a UX in a traditional Linux environment. Some of the keys on a TV remote, when pressed, produce events with keycodes greater than 255; however, these events are ignored by X, the window manager likely to be used on Linux. In some cases, remote control keys even produce keycodes which don't have any keysym under X.

    In this case, these exotic keycodes need to be mapped onto keysyms which X does recognise.

Plugin management and configuration

Media Explorer plugins are packaged as standard shared-object libraries or modules. They are then installed into one of the plugin directories for Media Explorer, namely:

  • $INSTALL_PREFIX/lib/mex/plugins

    This is the main directory where most plugins are installed.

  • $USER_CONFIG_DIR/mex/plugins

    $USER_CONFIG_DIR defaults to $HOME/.config on freedesktop.org compliant distros (like MeeGo). Could be used for user-specific plugins.

  • $CURRENT_WORKING_DIRECTORY/plugins

    $CURRENT_WORKING_DIRECTORY is the directory from where mex is being run.

Responsibility for finding and loading plugins lies with the MexPluginManager, assigned as a member variables of the Media Explorer application. Plugin loading works like this:

  1. mex creates a plugin manager (an instance of MexPluginManager).

  2. The plugin manager looks for .so and .la files in the plugin directories. (See above for details of where they are.)

    For each matching plugin file in those directories, the plugin manager does the following:

    1. Loads the file via GModule.

    2. Looks for a mex_get_plugin_type symbol in the module's symbol table.

      If the mex_get_plugin_type symbol is found, the plugin manager creates an instance of the plugin class and puts a reference to it into its plugin list. It also emits a plugin-loaded signal.

  3. Media Explorer responds to the plugin load (through a handler attached to the plugin-loaded signal) according to the type of plugin:

    • ModelProvider: The models provided by the plugin are added into Media Explorer's root model.

    • ToolProvider: The tool is added to the tool area of the interface; when the tool is activated, e.g. by a key press, the ClutterActor associated with the tool is presented. This actor can replace some or all of the Media Explorer UI with its own "sub-interface".

      For example, the Media Explorer search plugin is a ToolProvider: when activated, it presents a "search page", with a text entry widget for entering a search string and an auto-suggest column. The search page replaces the other panels in the user interface.

    • ActionProvider: The actions provided by the plugin are added to Media Explorer's MexActionManager.

      Actions are "things you can do to a piece of content". Media Explorer displays the actions for a piece of content when you press the information key while that content is highlighted. For example, Watch or Add to queue for a video, and View for a picture.

      An ActionProvider plugin can add new actions to particular pieces of content. Each action is defined by an MexActionInfo object returned by the provider; this object specifies the MIME types for which an action is applicable, as well as the action itself (an instance of MxAction).

See the section about extending Media Explorer for more information on plugin development.