Summer of Code 2008/N-Tube FLV Browser
From The Neuros Technology Wiki
Contents |
[edit] Abstract
This project is to design and implement a universal FLV video site browser for the Neuros OSD. Currently there is a YouTube player on the OSD, but this works by hard coding the interface for YouTube into the player itself. N-Tube will instead aim to create a browser and framework for generally interfacing with flash video sites, as well as being extendable to other forms of content providers (last.fm or flickr for example).
The general idea is to provide a browser program with a well defined and suitably non-specific API such that pluggable modules can be easily produced to provide the actual content to be browsed. These modules will be source specific, depending on a content source's specific API, aggregation service, or screen scraping to provide content for browsing. The browser program will then provide a standardized interface designed for use with the OSD hardware, while the pluggable modules will allow endless customization and streamlined content retrieval.
[edit] Description
The primary effort for this project will be designing the API, and the browser around it. While the framework design is the most important element, building the browser around it will be more useful both for the OSD and for the quality of design for the API. To ensure the usability of the API, both with run in parallel after the initial design phase.
The design of the framework will be based loosely on this post by Steven Robertson about an abstract content browser: http://groups.google.com/group/Neuros/msg/05493b52da5dd21e?&q=n-Tube
Specifically I will try to implement the following features:
- Provides a single API for browsing many content sources.
- Supports tree and parameter browsing, as well as searching
- Allows new sources to be supported in days
- Provides a streamlined interface designed for ease of use with OSD hardware.
To begin with I will explore the features and interfaces of several flash video sites and determine the most generally applicable interface for a plugin to easily move information from any of the sources to the browser API, whether they have their own API for a source or need to resort to screen scraping. Then I will flesh out the API design focusing on flash video but attempt to leave it open to extending to other forms of media sources as well.
After this initial design phase, I will begin work on the actual browser application and iteratively tweak the design as it is implemented. When I am satisfied that the API is nearing a finalized version I will begin working on implementing a more extensive example module based on YouTube. If necessary I may also implement a basic screen scraping module for another source. With a well designed API these should only take a few days each to get working examples to showcase the features of the browser and provide demo code for the API.
In addition to having modules that can plug into the main application, I'd like to explore the idea of including a probably less sophisticated, but lighter weight and easier to install web-service component to the API. This could streamline the process for people to offload more processor intensive work (such as customized recommendation, certain rule based filtering etc) to other servers that then get queried in a standard way by the browser, needing only the address and a few parameters. While this would be perfectly possible without any specific built in interface for it, streamlining the process can encourage much more interesting applications.
[edit] Development
[edit] Browser
Thus far all work implementing the nTube browser has been simply working with a Qt4 desktop application consisting of a dialog with a QListWidget which accepts various key events. The general flow of the program can be seen in the diagram. It starts with a selection of the plugins that are installed (found by reading the files in a plugins folder). From here the user chooses a plugin to use and moves forward to the top level/home list of the plugin. This could be something like browsable categories for Youtube or a top level directory for a file browser plugin. From here, depending on the interfaces that the plugin implements, the user will have different options. The entries for any results page will be marked showing whether it is playable or expandable. Ex: Top level youtube categories would be expandable but not playable, while individual videos would be playable and expandable (if the plugin allows) to show related videos. If the plugin implements the search interface, the user can launch a search from any result page, and this will open a simple text entry to issue the request. The parameter page is likewise accessible from any plugin display (anything but the plugin selection screen). This will show a list of available parameters supplied by the plugin, and allow the user to select values from a limited set also provided by the plugin or enter text. While intended to allow implementation of the parameterized browser as described above, this can effectively work as a simple setting interface for any sort of plugin. Those are all the options provided by the browser. While it is a very limited set, creative use of context aware forward and back, as well as generalized parameters and search should allow a large degree of power and freedom for plugins.
[edit] Plugin Structure
By taking advantage of Qt's built in plugin system, creating plugins for the nTube browser will be extremely easy and require minimal effort to get rudimentary functionality working. Plugins communicate with the browser through the defined interface, mainly using two data structures: parameters and results.
Parameter
- QString name; name for the parameter
- QStringList values; possible values for parameter (if not textual)
- QString description; description telling user what the parameter means
- bool text; whether the parameter should allow arbitrary text input
- bool togglable; whether user can turn parameter on and off
- bool on; current state of parameter
Result
- QString title; displayed title for result
- QString description; description to display for result
- QString thumbnail; url of thumbnail for result
- QString uri; identifying string for result
- bool expandable; whether result can be expanded
Plugins must implement a small number of basic functions to be functional with the browser.
class PluginInterface
{
public:
virtual ~PluginInterface(){}
virtual QString plugin_name() = 0;
virtual QList<Result> expand(QString &uri) = 0;
virtual QList<Result> back(QString &uri) = 0;
virtual QList<Result> home() = 0;
virtual void play(QString &uri) = 0;
signals:
void result_ready(QList<Result>&);
};
The essential functions here are plugin_name, expand, back, and home. plugin_name tells the browser what to call your plugin, expand returns the subsequent result list for an expandable entry, back returns the result list when a user chooses to back out of an entry, and home provides the initial result list when the plugin is started. play asks the plugin to launch whatever is associated with the selected result.
Because the expand and back functions which amount to tree navigation can be utilized by just about any plugin (and those that dont wish to use them can just leave them as stubs), this has replaced the tree interface.
The result_ready signal is for asynchronous plugins that cannot immediately return their result list. Instead the browser waits for this signal to update the result list. A similar function is used for parameters.
class ParameterInterface
{
public:
virtual ~ParameterInterface(){}
virtual QList<Parameter> parameters() = 0;
virtual void toggle_parameter(QString&, bool) = 0;
virtual void set_parameter(QString ¶meter, QString &value) = 0;
signals:
void parameters_ready(QList<Parameter>&);
};
class SearchInterface
{
public:
virtual ~SearchInterface(){}
virtual QList<Result> search(QString &query) = 0;
};
The parameter interface simply provides functions to get the list of parameters and inform the plugin of changes to their values coming from the user. And the search interface just provides a call to request the results of a search for an arbitrary string.
class LoginInterface
{
public:
virtual ~LoginInterface(){}
virtual bool login(QString &username, QString &password) = 0;
virtual void logout() = 0;
};
The login interface simply provides login and logout functions for services that require user authentication.

