# Implementing Rygel Server Plugins

## Implementing Server Plugins: Overview

This library may be used to create Rygel server plugins by implementing the RygelMediaServerPlugin class.

The RygelMediaServerPlugin reference documentation and these examples explain how to implement these plugins.

## Implementing Server Plugins: Simple Example

This example source code shows how to implement a Rygel Server plugin.

This example implements a root RygelMediaContainer by deriving from RygelSimpleContainer and adding some hard-coded items. A real Rygel server plugin's root container, or its child items, would typically populate themselves dynamically. For instance, they might add and remove items based on some source such as a file system or database. See, for instance, the Rygel Tracker Plugin or the Rygel MediaExport Plugin plugins, implemented in Vala.

## Implementing Server Plugins: Full Example

In addition, the external rygel-gst-0-10-plugins project provides a Rygel Server plugin that uses an older GStreamer version and is an example of an external Rygel Server plugin implemented in C. Its media-export plugin exposes the contents of a directory via UPnP.

The `module_init` function first checks that the plugin has not been disabled and then creates an instance of its RygelMediaExportPlugin, which it adds to the provided RygelPluginLoader instance.

The RygelMediaExportPlugin class, derived from RygelMediaServerPlugin, simply instantiates its RygelMediaExportRootContainer class, derived from RygelMediaContainer, providing it to the base class as the root container.

The RygelMediaExportRootContainer creates an instance of a RygelMediaExportMediaCache class and a RygelMediaExportHarvester class. The harvester finds files on the filesystem, and stores them in the media cache, which uses SQLite to keep track of them.

RygelMediaExportRootContainer informs the media cache that it should have a child container for the media content as organised on the filesystem, and additionally some virtual folders for Music, Pictures, Video and Playlists, with further sub-divisions under these, for instance by publication year. These containers are added to the media cache via instances of the RygelMediaExportNullContainer class, but that is just to simplify the media cache API and these instances then serve no further purpose. The virtual folders are re-added whenever the filesystem's container is updated, so that they can show the updated content, though that is not particularly efficient.

RygelMediaExportRootContainer then delegates its RygelMediaContainer virtual function implementations to this media cache, which in turn uses the RygelMediaExportObjectFactory to instantiate new containers for each request based on their ID. For instance, it returns a RygelMediaExportDBContainer if the requested ID indicates a virtual container, using the definition in the rest of the ID to build a suitable SQL query.

The root container derives from TrackableDbContainer, which in turn implements the RygelTrackableContainer interface, to implement the change tracking profile of the UPnP ContentDirectory:3 specification. Therefore, whenever the root container, or its child items, have changed, we call the `rygel_trackable_container_updated()` function.

Any filesystem folders are implemented as UPnP containers via the RygelMediaExportWritableDbContainer class, which implements the RygelWritableContainer interface to allow new files to be uploaded to the filesystem via UPnP.