Felix Schwarz Diplom-Informatiker
Software-Entwicklung und Beratung

Français | Deutsch

MediaCore – an extensible video platform

In the last five years, web videos became more and more popular. Obviously YouTube has a big market share and provides a lot of functionality for the user. However many companies, associations and organizations want to host their videos on a dedicated platform. The reasons I hear most often are:

  • Pages should blend in the main company site (styles, integration)
  • Show custom ads to make money
  • More flexibility, the ability to add custom features whenever you like

/posts/2011/mediacore/france.png Merci à Quentin Theuret pour avoir traduit cet article en français.

About MediaCore

MediaCore is an open source video and podcast hosting software, first published in January 2010. Even the stock distribution package contains a lot of interesting functionality:

  • web videos using Flash or "HTML5", including popular players like Flowplayer and JW Player
  • embed videos from YouTube, Vimeo or Google Video
  • Support for podcasts
  • sophisticated storage backends (e.g. store media in the Amazon S3 cloud)
  • Social media integration (sharing on Facebook, twitter etc)

/posts/2011/mediacore/MediaCore_Website.png

The main development work is done by Simple Station, a Canadian design studio. However development happens transparently with a github repository, a user forum and a developer mailing list.

One thing to keep in mind with MediaCore is that it is currently not a turn-key solution for everyone. Some commonly requested features which are not implemented yet include:

  • automated video encoding, e.g. encode uploaded videos to a format suitable for web viewing)
  • user permission system, restrict uploading ability, show videos only to some (paying?) users
  • In-video advertising support

Also installation on very cheap web space without shell access is quite hard, sometimes even impossible. Many of these problems will be solved by plugins after the release of MediaCore 0.9 (mid March 2011) or will be worked on in later releases. It's just not there yet.

Customization

So far MediaCore customizations required always changes to the actual source code which makes updates much harder because you need to change the source code for every new release. With the upcoming 0.9 release MediaCore supports plugins so you can do a lot more customization without actually modifying the MediaCore source code. Examples for plugins:

  • Change the overall style in arbitrary ways by overriding templates
  • Add new players
  • Trigger custom code after certain events (e.g. "new video uploaded")

With MediaCore 0.9 you can develop custom changes as plugins so it's way easier to update the stock MediaCore without having to change your code. See the next section for technical details.


MediaCore plugins

Currently (March 06 2011) there is no public documentation how to write MediaCore plugins so I decided to share my experience with you. However this won't/can't be a complete guide for newcomers. I assume that you're familiar with Python basics.

Generally plugins are developed using Python (backend code), Genshi (templating) and the usual web technologies (HTML, CSS, Javascript) for the frontend. For the Python side, you also might want to check the homepage of Pylons which is the underlying framework used in MediaCore. There is also The Definitive Guide to Pylons (online version) by James Gardner.

Structure

First of all, let's see the structure of a typical plugin (you can download this skeleton as well):

/posts/2011/mediacore/mediacore_plugin_structure.png

  • sample is the name of your Python module, so you can change that to any valid Python name.
  • mediacore_plugin.py is an arbitrary name but I like to use that as a central entry point where I import all my code.
  • If your plugin needs static resources like Javascript files, style sheets or additional images, you need a folder named public below "sample" (or however you named your module). Obviously the static resources can have arbitrary names, I just added a CSS file named sample-style.css.
  • If you want to add new pages to your MediaCore, create a folder templates below "sample" (or however you named your module). Inside you put your Genshi templates, again my-page.html is just an example.

Every folder of your plugin should contain an (empty) file __init__.py (this is because of how Python's setuptools/zipimport works). In the root folder, you need a setup.py file.

Example: Adding a New Page

To add a new page, you need a controller, a specific exposed method in that controller and a template. Let's see an example

# File: sample/mediacore_plugin.py

# ------------------------------------------------------------
# -*- coding: UTF-8 -*-

from mediacore.lib.base import BaseController
from mediacore.lib.decorators import expose

class MyController(BaseController):
    @expose('sample/my_page.html')
    def my_page(self, tag_name, **kwargs):
        # do your backend work here
        # …
        return {'tag_name': tag_name}
# ------------------------------------------------------------

__controller__ = MyController

If you use this example code (and fill in the missing pieces) in your plugin, your new page would be available as http://<mediacore>/sample/my_page?tag_name=Something. Please note that the sample part of the URL is depend on your settings in setup.py (see section about installation below), not the name of your Python module (however it makes sense to keep them the same).

In your template you can reference your static resources using ${h.url_for('/sample/public/<filename>')}.

If I remember correctly, every plugin can have only one controller. However a controller can have multiple exposed functions of course.

Example: Adding a New Player

MediaCore supports different types of players, especially HTML5 players (using the <video> tag and Javascript) and Flash players. The two important classes to check are mediacore.lib.players.AbstractHTML5Player and mediacore.lib.players.AbstractFlashPlayer.

I'll show you an example how to build a custom player based on the FlowPlayer:

# File: sample/player.py
from mediacore.lib.players import FlowPlayer

class MyPlayer(FlowPlayer):
    name = u'my_player'
    display_name = u'Custom Player based on Flowplayer'

    # you could override flashvars() for example to add player some options

Afterwards you need to register your class, so add this to your mediacore_plugin.py:

# …
from mediacore.lib.players import AbstractFlashPlayer
from sample.player import MyPlayer
AbstractFlashPlayer.register(MyPlayer)
# …

If you installed your plugin after you initialized the main MediaCore database (paster development.ini setup-app, you need to register your player via SQL:

insert into players (name, enabled, priority, created_on, modified_on, data) VALUES ('my_player', false, max(priority)+1, now(), now(), '{}');

Now your player should be visible in the admin settings ("Players" section) and you just need to activate it. All videos will use that player (if possible).

Installing your Plugin

MediaCore uses setuptools to find plugins. All found plugins are enabled automatically, there is no way to disable a plugin (currently).

So that's why your plugin needs a setup.py file which looks like this (roughly):

#!/usr/bin/env python
from setuptools import setup, find_packages

setup(
      name='SamplePlugin',
      version='1.0',

      author='Felix Schwarz',
      author_email='info@schwarz.eu',
      license='GPL v3 or later',
        
      packages=find_packages(),
      entry_points = {
          'mediacore.plugin': [
              'sample = sample.mediacore_plugin',
          ],
      }
)

Besides some meta information, The interesting point is the entry_point 'mediacore.plugin':

  1. The first part ('sample = …') defines the URL prefix where your new pages/resources are found (http://<mediacore>/sample/….
  2. Besides that the line tells MediaCore where to look for the plugin (sample/mediacore_plugin.py). This file is executed when MediaCore loads its plugin, and you may use the __controller__ attribute here to add new pages.

Before you can use your new plugin, you need to install it (don't forget to activate your virtualenv before!):

python setup.py install

For development you'll likely want to use the 'develop' mode instead of 'install' so that you don't have to install your plugin every time you made a code change.

That's my very rough primer on MediaCore plugins. I just left out one topic: Events. That's because I think the API design makes them basically pointless.

I hope you liked this paragraph anyway. In case of errors, please send an email. Also remember, you can download the basic skeleton.


My Contributions and Adaptations

I contributed several patches to MediaCore, for example:

  • Basic internationalization (i18n) infrastructure and large parts of the German translation
  • Support for Python 2.6
  • Better diagnostics for plugin problems

These patches were created while I modified MediaCore according to the needs of my customers.

Commercial Customization Examples

While I can't share all the commercial customizations I did for customers, I like to give two examples for modifications to give you an idea what can be done:

/posts/2011/mediacore/One_Goal.png

A German NGO launched a campaign during the Soccer World Cup 2010 in South Africa. The wanted a web platform where users (mostly schools) can upload videos and images. I needed a German site and the ability to manage images in a MediaCore instance.


/posts/2011/mediacore/carousel_with_ads.png

A commercial portal hosts a lot of videos with MediaCore but lacked the ability to display in-video advertisements using OpenX. I developed a custom MediaCore player which shows a pre-roll advertisement. Also I developed a video carousel which can be embedded into other sites (also showing the ads). All of this functionality is contained in plugins so MediaCore can be updated easily.



Further Questions?

As always, if you have more questions about MediaCore, check out the user forum. If you want to ask about commercial support, remote installation and modifications, just send an email to info@schwarz.eu.