About a year ago I have posted a blog post on how to get started with OSMF (see here). Since than the framework have gone a long way. OSMF 1.0 was released recently and I have given it a second look.
I want to give credit to Brian Riggs and David Hassoun for helping with the content of this blog entry.
OSMF is an open source AS3 media framework that supports the workflow around video playback and monetization. Video players have different features set. The skins are different, and the integration and architecture workflow are. They essentially do the same thing and can be created using the OSMF framework. The framework is based on the quality of the video player (OVP) and addresses the common challenges.
The foundation of the framework is Qos (quality of service) which focuses on Open Video Player (OVP) and provides a quick start for playing videos (smallest buffer size needed to start the video), efficient connection logic, and switching bitrates dynamically (recall the metric monitor service in OVP).
The framework can be used as follows:
- Create a component user interface for integration of audio, videos, and images.
- Plugin architecture for integration of the following: CDN, ad partners, publishers, analytics, social networks, and developers.
The framework by itself is not powerful without having partners embracing the frameworks – e.g. CDNs, publishers, ad analytics, social networks, and developers. This type of pluggable component can allow publishers to easily switch and test performance and service across different services.
Advantages:
- Reduce the barrier of entry for new publishers – By offering a framework to integrate the different pieces of the video player, new publishers can get started quickly and with fewer resources and can scale up as requirements increase.
- Provide flexible framework – OSMF provides an easy way to extend each component and allows these components to act as Lego pieces that can be compositable and extensible.
- Leverage existing code – The OSMF framework uses the Flash Player from Open Video Player (OVP). No need to have duplication of efforts to solve basic problems.
- Drive Standard and allow custom workflows – Many of the elements that connect to a video player are not standard yet, and Adobe OSMF will help standardize these components and allow them to be configured.
- No runtimes or framework dependency – The framework is based on Flash 10 AS3 and is not dependant on any framework such as Flex SDK, Cairngorm, or others. With that said, some integrated elements may be created using a framework, but these are loosely coupled and can be replaced if needed.
- Partners focus – There are two partners: publishers and CDNs. Each can focus on their expertise. CDN can focus on services and integration, and publishers can focus on user experience.
- Integration with existing Adobe tools – Adobe OSMF will be integrated with other Adobe Suite tools and services such as Catalyst, Illustrator, FMS 3.5 and FMRMS.
- Optimize – By having the ability to separate the core framework and each element as a separate SWC, you can increase performance by keeping file size to the minimum and remove components not used.
The Adobe OSMF framework consists of the following building blocks:
MediaPlayer - MediaPlayer class represents the controller class for media playback. You can play any type of media (video, audio, images, SWFs, etc.). Instead of using DisplayObject – use MediaPlayerSprite. To use the the media you can use the following methods: play(), pause(), seek() as well as the following properties: volume, autoRewind, loop. The events for the media are: seekingChange, volumeChange, complete
MediaElements & Traits – MediaElement class represents a unified media presentation (video, image, or a grouping of media that’s shown together). It takes a resource (URL, array of dynamic streams, etc.). You can than presents/plays the media using one or more MediaTraitBase. MediaTraitBase represents an intrinsic capability of a piece of media (ability to play, ability to seek, audio, etc.). This class is dynamic in nature, can come and go over the life of the media Trait APIs, it is also media-type-agnostic. Keep in mind that not all traits apply to all media types. For instace AudioElement doesn’t have DisplayObjectTrait and ImageElement doesn’t have PlayTrait.
Rules of thumb – A trait represents a media capability or characteristic. Trait cannot apply to every piece of media and must be something that a player developer might act upon. For instance: LoadTrait, PlayTrait, SeekTrait, DisplayObjectTrait.
As an example, take a look at the VideoElement traits in Figure:

Composite Elements – ParallelElement class represents a set of MediaElements that are presented in parallel. It is a media composition whose elements are presented in parallel. SerialElement class represents a set of MediaElements that are presented one after the other. These classes used together create two composite MediaElements that can represent complex, “tree-like” media experiences.
To better understand how it works take a look at Figure:

We have three video related MediaElements: (Episode), (Mid-Roll Ad) and (Episode, Continued). Together they create a media experience and are grouped as serialElement. Once you create the serialElement you can add that group to a parallelElement with other serialElement.
Composite Elements – A composite MediaElement is a MediaElement that exposes composite traits. Composite traits aggregate multiple traits of the same type. For instance, you can take two VideoElement and create a SerialElement and than have access to both playTrait properties from each VideoElement. Together these playTraits are CompositePlayTrait.
Proxy Elements – ProxyElement class wraps up (proxies) with another MediaElement. These class expose the same API. The class signature is as follow:
public function ProxyElement(wrappedElement:MediaElement)
By default, all methods, properties and events are passed through subclasses and can change. This can be used to modify the behavior of another MediaElement. Clients think they’re working with a VideoElement, when they’re actually working with a ProxyElement that wraps a VideoElement. This is incredibly useful for plugins.
Here are two examples of ProxyElement:
- User Analytics – ProxyElement, which listens for changes to the wrapped MediaElement and reports them to a server.
- Seamless Video Switching – ProxyElement, which wraps up two VideoElements, and switches from one to the other without rebuffering.
Take a look at the example in Figure below. Here we created a AnalyticsProxyElement element. The proxy listens to events from wrapped MediaElement and can reports the data back to Omniture API. The AnalyticsProxyElement does that by wrapping an UnseekableProxyElement that prevents seeking of the wrapped MediaElement.

Plugins – The real challenge is the third party integration. There are many 3rd party vendors that make a player such as CDNs, Ad Servers/Networks, Analytics Providers, “Social” Providers and many others.
To allow integration between the Player and the vendors OSMF created Player/Plugin contract, which declare what the plugin capabilities are.
Plugins don’t have free rein over the player. Meaning that the Players can load plugins, but Players don’t integrate with custom plugin APIs directly. The way it works is that OSMF acts as the broker between the player and the plugin.
There are ranges of different plugin types:
- Media Plugins – declares new media types. For examples: Video plugin, image plugin
- Loader Plugins – declare new ways of “loading” media. For example: Akamai plugin for connection authentication.
- Proxy Plugins – declare ways to modify (or listen to) the behavior of media. For example: Plugin, which prevents seeking of all videos, Omniture reporting plugin.
- eference Plugins – Declare the range of media they’d like to reference – example: Plugin, which creates an overlay ad SWF that can pause the main video when displayed.
R
For info about creating plugins, check ASDOC PluginInfo:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/org/osmf/media/PluginInfo.html
Metadata – There are two types of metadata: Resource-level Metadata and MediaElement Metadata.
Resource-level Metadata was created to address the challenge of how do I know what “http://example.com/myvideo” represents. MediaResourceBase.addMetadataValue method can be used to further qualify a resource with “static” data (e.g. MIME type). For instance, let’s say we want to assign the “video/x-flv” MIME type to the resource with a URL so we can know that it’s a video.
MediaElement Metadata was created to address the challenge of representing custom information about what’s playing. MediaElement.addMetadata method used to model metadata during playback.
For instance, let’s say that we have a dynamically generate “ad” vs. “episode” metadata, we want to be able to know that so we can have the UI update the chrome during ad breaks.
The OSMF Code is available here: www.osmf.org
To read more see the resources listed in this page: http://forums.adobe.com/message/2392184#2392184
Hello World example
To create a simple Hello Wrold visit the OSMF wesite:
http://blogs.adobe.com/osmf/2009/09/building_a_helloworld_app_with_osmf.html
Below is a minimalistic example of loading an image using Flex 4. We create sprite that contains a MediaPlayer to manage the display and control of the MediaElements we will be using. We then create and set the MediaElement (in our case ImageElement) with a resource and path. Lastly, we add the sprite to the UIComponent.
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="1024" minHeight="768"
creationComplete="creationCompleteHandler()">
<fx:Script>
<![CDATA[
import org.osmf.elements.ImageElement;
import org.osmf.elements.VideoElement;
import org.osmf.media.MediaPlayerSprite;
import org.osmf.media.URLResource;
//path of media to be displayed: Image
private static const MEDIA_PATH:String = "http://mediapm.edgesuite.net/strobe/content/test/train.jpg";
protected function creationCompleteHandler():void
{
//sprite that contains a MediaPlayer to manage display and control of MediaElements
var playerSprite:MediaPlayerSprite = new MediaPlayerSprite();
//creates and sets the MediaElement (ImageElement) with a resource and path
playerSprite.media = new ImageElement( new URLResource( MEDIA_PATH ) );
//Adds the sprite to the UIComponent defined in MXML
mediaHolder.addChild( playerSprite );
}
]]>
</fx:Script>
<mx:UIComponent id="mediaHolder" />
</s:Application>
Below is a minimalistic example of creating a progressive download video player using OSMF and Flex 4. Just as in the image example we create a sprite that contains a MediaPlayer to manage the display and control of the MediaElements we will be using. We then create and set the MediaElement (in our case VideoElement) with a resource and path. Lastly, we add the sprite to the UIComponent.
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600"
creationComplete="creationCompleteHandler()">
<fx:Script>
<![CDATA[
import mx.core.UIComponent;
import org.osmf.elements.VideoElement;
import org.osmf.media.MediaPlayerSprite;
import org.osmf.media.URLResource;
//path of media to be displayed: Progressive Video
private static const MEDIA_PATH:String = "http://mediapm.edgesuite.net/strobe/content/test/AFaerysTale_sylviaApostol_640_500_short.flv";
protected function creationCompleteHandler():void
{
//sprite that contains a MediaPlayer to manage display and control of MediaElements
var playerSprite:MediaPlayerSprite = new MediaPlayerSprite();
//creates and sets the MediaElement (VideoElement) with a resource and path
playerSprite.media = new VideoElement( new URLResource( MEDIA_PATH ) );
//Adds the sprite to the UIComponent defined in MXML
var component:UIComponent = new UIComponent();
component.addChild( playerSprite );
mediaHolder.addElement( component );
}
]]>
</fx:Script>
<s:Group id="mediaHolder" />
</s:Application>
In case we want to serve an audio file via progressive download, just use AudioElement instead of VideoElement.
Here is a minimalistic example of streaming a video using OSMF and Flex 4. The URL points to a streaming server and the OVP player will be able to recognize that and provide streaming instead of progressive download.
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="1024" minHeight="768"
creationComplete="creationCompleteHandler()">
<fx:Script>
<![CDATA[
import org.osmf.elements.ImageElement;
import org.osmf.elements.VideoElement;
import org.osmf.media.MediaPlayerSprite;
import org.osmf.media.URLResource;
//URI of connection/media to be displayed: RTMP - Streaming Video
private static const MEDIA_PATH:String = "rtmp://cp67126.edgefcs.net/ondemand/mediapm/strobe/content/test/SpaceAloneHD_sounas_640_500_short";
protected function creationCompleteHandler():void
{
//sprite that contains a MediaPlayer to manage display and control of MediaElements
var playerSprite:MediaPlayerSprite = new MediaPlayerSprite();
//creates and sets the MediaElement (VideoElement) with a resource and path
playerSprite.media = new VideoElement( new URLResource( MEDIA_PATH ) );
//Adds the sprite to the UIComponent defined in MXML
mediaHolder.addChild( playerSprite );
}
]]>
</fx:Script>
<mx:UIComponent id="mediaHolder" />
</s:Application>
Here is an example of dynamic streaming using FMS server. We set the host URL for the steaming server and than we can add the profile files for the videos and the dynamic switching will be handles automatically by the OVP player based on the user’s bandwidth.
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="1024" minHeight="768"
creationComplete="creationCompleteHandler()">
<fx:Script>
<![CDATA[
import org.osmf.elements.VideoElement;
import org.osmf.media.MediaPlayerSprite;
import org.osmf.net.DynamicStreamingItem;
import org.osmf.net.DynamicStreamingResource;
//URI of host RTMP/E connection for streaming server
private static const HOST:String = "rtmp://cp67126.edgefcs.net/ondemand";
protected function creationCompleteHandler():void
{
//sprite that contains a MediaPlayer to manage display and control of MediaElements
var playerSprite:MediaPlayerSprite = new MediaPlayerSprite();
//Resource containing the pointers, bitrate, width, and height of each DynamicStreamingItem to be in the set
var dsr:DynamicStreamingResource = new DynamicStreamingResource( HOST );
dsr.streamItems.push( new DynamicStreamingItem( "mp4:mediapm/ovp/content/demo/video/elephants_dream/elephants_dream_768x428_24.0fps_408kbps.mp4", 408, 768, 428) );
dsr.streamItems.push( new DynamicStreamingItem( "mp4:mediapm/ovp/content/demo/video/elephants_dream/elephants_dream_768x428_24.0fps_608kbps.mp4", 608, 768, 428) );
dsr.streamItems.push( new DynamicStreamingItem( "mp4:mediapm/ovp/content/demo/video/elephants_dream/elephants_dream_1024x522_24.0fps_908kbps.mp4", 908, 1024, 522) );
dsr.streamItems.push( new DynamicStreamingItem( "mp4:mediapm/ovp/content/demo/video/elephants_dream/elephants_dream_1024x522_24.0fps_1308kbps.mp4", 1308, 1024, 522) );
dsr.streamItems.push( new DynamicStreamingItem( "mp4:mediapm/ovp/content/demo/video/elephants_dream/elephants_dream_1280x720_24.0fps_1708kbps.mp4", 1708, 1280, 720) );
//Creates the MediaElement (VideoElement) adding the DynamicStreamingResource to it, and setting to as the mediaElement on the MediaPlayerSprite
playerSprite.media = new VideoElement( dsr );
//Adds the sprite to the UIComponent defined in MXML
mediaHolder.addChild( playerSprite );
}
]]>
</fx:Script>
<mx:UIComponent id="mediaHolder" />
</s:Application>
You can download these examples from here:
http://www.eladelrom.com/blog/Flex/OSMF/OSMFExample.fxp
Last example (more advanced) shows you how to create a streaming video player and listen to events to recognize once the video is ready to play, as well as access properties in the video player and the net stream:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="1024" minHeight="768">
<fx:Script>
<![CDATA[
import org.osmf.elements.VideoElement;
import org.osmf.events.DisplayObjectEvent;
import org.osmf.events.MediaPlayerCapabilityChangeEvent;
import org.osmf.media.MediaPlayer;
import org.osmf.media.URLResource;
private var playerContainer:Sprite = new Sprite;
private var mediaPlayer:MediaPlayer = new MediaPlayer();
private function playVideoURL(url:String):void
{
mediaPlayer.addEventListener( MediaPlayerCapabilityChangeEvent.CAN_PLAY_CHANGE, onVideoLoadedAndReady );
mediaPlayer.addEventListener( DisplayObjectEvent.MEDIA_SIZE_CHANGE, onDimensionChange );
var videoElement:VideoElement = new VideoElement( new URLResource( url ) );
mediaPlayer.media = videoElement;
mediaHolder.addChild( playerContainer );
}
private function onVideoLoadedAndReady(event:MediaPlayerCapabilityChangeEvent):void
{
if (event.enabled && mediaPlayer.canPlay)
mediaPlayer.play()
}
private function onDimensionChange( event:DisplayObjectEvent ):void
{
mediaPlayer.displayObject.width = event.newWidth;
mediaPlayer.displayObject.height = event.newHeight;
mediaHolder.addChild( mediaPlayer.displayObject );
}
]]>
</fx:Script>
<s:Rect top="0" width="660" height="365"
x="0" y="0">
<s:fill>
<s:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
<mx:UIComponent id="mediaHolder" />
<s:TextInput id="mediaPath" width="400" x="48" y="330"
text="rtmp://cp67126.edgefcs.net/ondemand/mediapm/strobe/content/test/SpaceAloneHD_sounas_640_500_short"/>
<s:Button x="456" y="331" label="Play" click="playVideoURL(mediaPath.text)"/>
<s:Button x="534" y="331" label="Pause" click="mediaPlayer.pause()"/>
</s:Application>
Where to go from here:
The toolkit and documentation is available for download at:
www.OpenSourceMediaFramework.com
OSMF developer forums:
http://forums.adobe.com/community/opensource/osmf/developers
OSMF User Group:
http://groups.adobe.com/groups/7af970e6e4/summary