Getting started: OSMF Plugins

In the past media players have had a problem. They all have custom implementations. When building a media player the developer encounters multiple services to load content, track analytics & quality of service information as well as handle advertising & custom user interactions among other things. The Open Source Media Framework (OSMF) provides a solution to these issues by introducing a flexible plugin system that can integrate multiple plugins to solve these problems without the media player developer needing to write a bunch of extra code.

What is an OSMF plugin?

An OSMF plugin is an easily distributable extension for an OSMF based player that can unobtrusively provide or adjust the functionality of that player. At its most basic, a plugin is a class or set of classes (static plugin) or a SWF (dyanamic plugin) file that is loaded into the media player by the MediaFactory. The plugin is built to a specific API that adheres to a contract that OSMF has created so the media player knows what plugins are interested in which MediaElements and can pass them the necessary data for the plugin to do its job.

Types of plugins

There are 3 types of plugins that you can create, and each one has a different type of purpose Standard, Proxy & Reference.

  1. Standard plugins are responsible for creating either built-in or custom MediaElements.
  2. Proxy plugins are responsible for changing MediaElements that have been created by the MediaFactory.
  3. Reference plugins are responsible for adding functionality to the MediaElements created by the MediaFactory.

*NOTE: The MediaFactory must be used for plugins to work correctly. When a MediaElement is created by the MediaFactory, the MediaFactory references a list of MediaFactoryItems defined in the PluginInfo class to be notified if a plugin can handle a specific media resource.

Building an OSMF plugin

Initially I like to develop a plugin as a static or class based plugin. This allows for easier debugging and keeps things simpler when testing and/or refactoring. And it is pretty easy to convert a static plugin to a dynamic plugin, so don’t be worried about that.

The PluginInfo class is the first class you will need to be familiar with when building plugins. This class provides the API and information for the MediaFactory to access and provide the necessary data for the plugin to function correctly.

To create your PluginInfo class, you will need to extend OSMF’s PluginInfo class. The definitions for what and how a plugin can handle a MediaElement as well as what type of plugin is being loaded are specified using a collection MediaFactoryItems. In the constructor of your PluginInfo class you will need to define a MediaFactoryItem for each type of MediaElement you plan to handle and/or create in your plugin and add this to an ArrayCollection that is passed to the super’s constructor.

package com.realeyes.osmf.plugin
{
	import com.realeyes.osmf.plugin.element.WatermarkElement;

	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactoryItem;
	import org.osmf.media.MediaResourceBase;
	import org.osmf.media.PluginInfo;
	import org.osmf.metadata.Metadata;
	import org.osmf.net.NetLoader;

	public class WatermarkPluginInfo extends PluginInfo
	{
		public function WatermarkPluginInfo()
		{
			// Add MediaFactoryItems
			var items:Vector.<MediaFactoryItem> =  new Vector.<MediaFactoryItem>();

			var loader:NetLoader = new NetLoader();
			items.push( new MediaFactoryItem(
				"com.realeyes.osmf.plugins.WatermarkPlugin",
				canHandleResource,
				createWatermarkElement
			) );

			super( items );
		}

		public function canHandleResource( resource:MediaResourceBase ):Boolean
		{
			return true;
		}

		public function createWatermarkElement():WatermarkElement
		{
			// Create the watermark element
			var newWatermarkElement:WatermarkElement = new WatermarkElement()
			return newWatermarkElement;
		}
	}
}

The sample class above shows the basics to defining a Standard plugin that creates a WatermarkProxyElement for any type of resource. The constructor defines a single MediaFactoryItem that creates a WaterMarkElement via the createWatermarkElementI() method. This plugin will be used for any type of MediaElement that the MediaFactory creates because the canHandleResource() method returns true. If we wanted this plugin to only handle RTMP streams we could adjust the canHandleResource() method to look something like the following:

public function canHandleResource( resource:MediaResourceBase ):Boolean
{
	var canHandle:Boolean;
	var urlResource:URLResource = resource as URLResource;
	if( urlResource.url.indexOf( "rtmp" ) )
	{
		canHandle = true;
	}

	return canHandle;
}

The WaterMarkElement is then returned to the MediaFactory and passed on to be handled by the media player.

Standard Plugin details

Standard plugins are used to create MediaElements. This means that they should concentrate on the resource being passed in and create the appropriate MediaElement based on that resource.

A proxy plugin

If we wanted to create a Proxy plugin we can keep the same PluginInfo class, but we’ll need to add in a 4th parameter to the MediaFactoryItem to let the MediaFactory know that it will be working with a proxy plugin and to call the proxiedElement setter on the WatermarkElement created via the createWatermarkElement() method. This would look like:

public function WatermarkPluginInfo()
{
	// Add MediaFactoryItems
	var items:Vector.<MediaFactoryItem> =  new Vector.<MediaFactoryItem>();

	var loader:NetLoader = new NetLoader();
	items.push( new MediaFactoryItem(
		"com.realeyes.osmf.plugins.WatermarkPlugin",
		canHandleResource,
		createWatermarkElement,
		MediaFactoryItemType.PROXY
	) );

	super( items );
}

Proxy Plugin details

Proxy plugins allow a developer to non-invasively alter the MediaElement’s behavior. For example, you could use a proxy plugin to disable the seek or pause functionality in a media stream. You can also use proxy plugins to alter the type of MediaElement after the plugin is loaded. In this case you could create a SerialElement, add a pre-roll VideoElement to the serial element and then the original MediaElement for simplified pre-roll advertising.

A reference plugin

A reference plugin is created by adding a mediaElementCreationNotificationFunction() method to the plugin and then passing that method to the super() call with the MediaFactoryItems collection. These additions would change the PluginInfo class to look like:

public function WatermarkPluginInfo()
{
	// Add MediaFactoryItems
	var items:Vector.<MediaFactoryItem> =  new Vector.<MediaFactoryItem>();

	var loader:NetLoader = new NetLoader();
	items.push( new MediaFactoryItem(
		"com.realeyes.osmf.plugins.WatermarkPlugin",
		canHandleResource,
		createWatermarkElement
	) );

	super( items, mediaElementCreated );
}

protected function mediaElementCreated( element:MediaElement ):void
{
	trace( "MediaElement created!" );
}

Reference Plugin Details

Reference plugins rely on having a reference to the MediaElement’s created by the MediaFactory. Unlike the proxy plugin, which receives the created MediaElements after it has been loaded a reference plugin receives a notification for each MediaElement that has been created, even those before the plugin was loaded. Reference plugins are good containers for tracking as well as interaction control.

The Power of OSMF Plugins

The Open Source Media Framework & the Plugin system provides a flexible and powerful solution to some common problems that media player in the past have had – the need to communicate with many, disparate services and content providers and the custom code implementations around these communications.  OSMF makes it easy to integrate plugins that have been built by these service and content providers as well as create plugins that extend the functionality of players built using OSMF.

Below is the presentation that I gave with David Hassoun to the Rocky Mountain Adobe Users Group on August 8th, 2010 about OSMF & Plugins.

Resources

Sample Code Download

http://www.thekuroko.com/wp-content/plugins/downloads-manager/img/icons/winzip.gif download: OSMF Plugin Samples (722.43KB)
added: 25/08/2010
clicks: 106
description: Samples from the RMAUG presentation on OSMF plugins.

Posted in featured, presentations | 13 Comments

REOPS Part 1 – The ADC Article is Live

Adobe just launched the first article in a series on ADC about the REOPS or Realeyes OSMF Player Sample.

This article is an introduction to REOPS, a player sample built using the Open Source Media Framework (OSMF), and should get you playing media and working with OSMF in a hurry. As an introduction to the OSMF, David Hassoun and I review where you can get the code, what is included with REOPS and the OSMF and the basics of setting up a fairly flexible media player using these resources.

Check out the article on ADC and let us know what you think.

Posted in articles, featured | Leave a comment

OSMF 1.0 has been released!

The Open Source Media Framework (OSMF) was released today. If you don’t know what OSMF is:

Open Source Media Framework (OSMF) simplifies the development of media players by allowing developers to assemble components to create high-quality, full-featured video playback experiences. This open framework enables development focused on web-based video monetization, with lower costs and faster turnaround.

The 1.0 release can be downloaded from http://opensource.adobe.com/wiki/display/osmf/Downloads

Also announced was the Strobe Media Playback pre-release. The Strobe Media Playback is an opensource and free playback component built using the OSMF that:

  • Has a predefined user interface
  • Supports all the same video features as OSMF, including Progressive Download, RTMP streaming, Live Streaming, HTTP Dynamic Streaming
  • Supports content protection with Flash Access 2.0.
  • Supports controlling the interface through HTML embed tags, including player dimensions, setting auto start and auto hide behaviors & full screen support and more.

Download the Strobe Media Playback

Now that OSMF 1.0 has been released, we’ll be working on the REOPS (The Realeyes OSMF Player Sample) code samples, documents and source so it is up to date with this 1.0 release. You can download the code and samples from the Google Code project and make sure to follow @reops on Twitter or check out the REOPS stream for updates.

Posted in news | Leave a comment

Git-ing Started: My Git Journey

I have finally made some time to check out Git. For the past couple of days I’ve been experimenting with Git to see if it is something that we should use at Realeyes Media. The following is my Git story as well as some of the resources that I gathered along the way.

First things first, “git” initiated if you don’t know what Git is.

Now, our requirements to switch over to Git:

  1. A quick learning curve
  2. A simple shared development model – Less branch and merge pain than SVN
  3. We need a central location for all major projects and we would like to host it
  4. It needs to work with a Continuous Integration tool – we use currently Hudson
  5. We needed a reason – Is it simpler? Is it faster? Basically does it solve any problems we had with SVN?

Requirement #1: The learning curve
Yep, no problem. If you are used to SVN, you’ve got it made. Retrieving project code, making changes and committing are all pretty straight forward. Managing the repository does require a bit of a perspective shift though. With SVN the HEAD of the repo lives in one place – on the server. Git is a “distributed” system so each developer has a local copy of the development history. It is an easy perspective to change to and Git is flexible enough to fit into the central repository schema (more on this later).
Sample Git commands:
1. Get project code

$ git clone git://git.server.com:projectName.git

[Make some changes]
2. Commit changes

$ git add /path/to/file

then

$ git commit -am 'Your commit message.'

Requirement #2: A flexible shared development model
Getting project code is simple and straight forward. Making changes and committing to your local repository is easy. Now how does a developer handle sharing changes and integrating others changes into their local repository? There are a few ways to set up shared development. Two that Realeyes is considering are (for more info on share development check out the Git documentation):

  1. Patch-based collaboration where patch files are sent via email and then integrated into the repository by the maintainer. Because the patches are read and reviewed by many people (everyone on the mailing list hopefully) this can provide a “first line of defense” against bugs.
  2. Repository-based collaboration where changes are pushed and pulled from a centrally located repository. This can decrease the overhead for the maintainer, but can also add some overhead for the maintainer as well as overhead for any continuous integration systems.

Branching and merging are two important concepts of shared development. With Git these operations are part of hte daily work-flow and are simple and accurate. Git is smart. It handles much of the heavy lifting having to do with merges for you because the development history is tracked with every branch – even with changes across branches that are being merged into master (trunk for you svn’ers).

Requirement #3: Central Location and Hosting
This is partially addressed in #2 if we use repository-based collaboration. Setting up a remote Git server can be as simple as setting up a server with SSH and creating repositories from there. You can also set up repository access with the GIT protocol as well as HTTP and WebDAV for public and restricted access – so we have options. This is where I spent a bunch of time (just because I thought it was fun), setting up different servers and configurations (Windows & Ubuntu, SSH, HTTP etc) to make sure that we could host our own Git remote repositories without issue. Here are a few of the resources that got me going quickly:

Requirement #4: Continuous Integration
This one was simple, I found plenty of information to confirm that Git will work with Hudson as well as CruiseControl (another CI system we’ve used in the past).

Requirement #5: We Need a Reason
Now that I’ve had a couple of days to play with Git, experienced its flexibility and discover the improvements it has over SVN, I think that we have plenty of reasons to start using Git. Here are some of the standout reasons in my mind:

  • Git operations are just as easy (if not easier) to learn and remember as SVN commands
  • Simplified shared development: Every developer has a copy of the development history – they can work no matter what the status of their internet connection is.
  • Branches and merges are simpler and easier because branches come along with their entire history
  • Cleaner project directories: There are no ‘.svn’ directories in every project folder, everything is stored in one ‘.git’ directory at the root of your repository
  • SSH Security as well as multiple delivery options: HTTP, GIT WebDAV
  • Performance: Git is fast

In short, I really like Git. It is a lighter, more efficient and a simpler workflow than SVN. So, SVN old friend, you have treated us well (except for the merges), I think it is time to step back and make a little room for Git.

Following is the list of links that I’ve used in this post as well as to get me up to speed for my “Git Expedition”.
Guides and Docs:

Tutorials and Resources:

Git GUIs:

Posted in R&D, featured, news | Tagged , | Leave a comment

Domain name switch (Does Google own the internet?)

I’ve moved to http://thekuroko.com – why? Do read on.

Google decided to list our domain (realeyes.com) as a BadWare site – no warning – no notice – just list us as evil and then let us deal with the fallout. What happened was some unsavory person decided they could hack into or site and plant some nasty JavaScript. Google picked up on it and added our site to their BadWare list. They didn’t try to contact anyone at realeyes.com via email or phone (it isn’t difficult to find contact information on our site).We have 3 of the emails listed in their Webmasters/site Owners Help – nothing was received from them.

Now, don’t get me wrong, if this was it and we could contact google, tell them that the issue has been resolved and they would remove our domain from the BadWare list, I’d be totally cool with Google. That wasn’t the case however. We immediately remove the issue, worked with teh hosting company to batten down the hatches and make sure there weren’t any open holes and promptly sent a ‘Request for Review’ to google. We received a prompt response to the request, but it was basically a don’t call us, we’ll call you.

We’ve received a request from a site owner to reconsider how we index the following site: http://realeyes.com/

We’ll review the site. If we find that it’s no longer in violation of our Webmaster Guidelines, we’ll reconsider our indexing of the site. Please allow several weeks for the reconsideration request. We do review all requests, but unfortunately we can’t reply individually to each request.

Really Google? I’m imagining it could be a pretty automated system to receive a request for review, go scan the site again (targeting the pages that you Google have indexed as having Badware), and fix the listing if the site is found to be clean. But, no we have to wait (I’ve heard stories that it can take up to a month) until Google deems our site worthy for the Internet.

<rant>Hrm, Google – do no evil? I think that is a little evil. How did Google get into the position of being able to tell everyone that our site is bad without a way to get our site of the bad list in an expedited manner? Every major browser references Google and throws a ugly error page. Our site was listed once in the last 90 days has having an issue. One strike your out? WTF? So, our site is relegated to the evil malicious site is going to take your soul list without so much as a courtesy call? Google I think you need to work on your system, help people out, not hinder them for a hackers lack of respect and inconsideration.</rant>

So, hopefully Google will re-index our site and we’ll stop having to un-check the ‘Block reported attack sites’ preference. Until then I’ll be here at http://thekuroko.com and http://www.thekuroko.com.

Posted in featured, news | Tagged , | 4 Comments