by Niall Kennedy
Figure 1. Different video players have different controls for the same basic functions.
FLV is the most popular form of video delivery on the web today. Yet each video player takes a slightly different approach to even the most common video actions such as Play/Pause, download and playback progress displayed in the scrubber bar, volume control, full-screen toggle, and more (see Figure 1). Video publishers rely on content delivery networks and their edge servers physically located close to viewers for video delivery via progressive download, RTMP or HTTP dynamic streaming, or Flash Access methods. Video analytics providers hook into video actions to log events to a remote server for every play action, video progress event, or video interaction. Publishers interested in opening up their video content to serial video advertising (preroll and postroll videos) need to build advertising triggers to dynamically add content from a third-party advertising provider and handle serial playback.
The Open Source Media Framework sweats the small stuff so you don't have to. Common player components are built by Adobe and its community with skins, custom components, and integrated plug-ins extended by your site's player. This common video player baseline implementation enables third-party plug-in developers to hook ActionScript 3 code to framework components, providing reliable, well-supported community code created and maintained by the companies behind each product. A switch between CDNs simply involves switching an OSMF CDN plug-in for the same reliable delivery in your delivery method of choice. Need to add an extra analytics provider? No problem. The wide adoption of OSMF, backed by a strong community, means popular analytics providers such as comScore and Quantcast are already compatible with video players built on top of OSMF. Top video advertising networks, including EyeWonder, FreeWheel, and Tremor Media, attach to OSMF serial functions with custom advertising callbacks based on the emerging MAST and VAST standards from the Interactive Advertising Bureau.
VideoPress is a relatively small video network in a world dominated by well-funded products such as YouTube, Vevo, Hulu, and Vimeo. Building a video player on top of OSMF helps VideoPress bring new features to market quickly, support a robust open-source community, and avoid costly custom integrations with third-party service providers. VideoPress rewrote its video player and server-side data services over the course of two months, including adjusting for a changing family of OSMF standards on the road to an OSMF 1.0 release on May 28, 2010 (see Figure 2). VideoPress rode the bleeding edge so you don't have to, which eases your transition to this new and promising platform.
Figure 2. The VideoPress OSMF player for WordPress.com.
The VideoPress player is built on top of the RealEyes OSMF player sample (REOPS), an extension of core OSMF features. The player loads a dynamic configuration file on initialization, allowing a unique player skin, plug-ins, and video assets for each publisher. The VideoPress player progressively downloads MP4 video files containing an H.264 video track and AAC-LC audio track from the CDN provider's global edge servers. Player impressions, playback initiation, and playback progress are tracked through Quantcast and WordPress.com Stats, a custom OSMF plug-in. The player supports timed text transcripts in multiple languages, switching between a low- and high-quality video file, and video sharing features, including embed markup copy and paste as well as direct download of the highest quality raw video files.
The REOPS project includes an extensible control bar skinning system, full-screen support, closed-caption support based on Akamai's contributed TTML plug-in, and dynamic OSMF plug-in support. In the VideoPress player image in Figure 2 only the top bar and logo overlay are custom VideoPress skin components. REOPS supports custom runtime configuration via a remote AMF or XML file. It is possible to load a different skin each time the player loads or to customize skin components. VideoPress alters its player skin color, logo, and top bar controls based on publisher branding and promotional preferences. A sports team using VideoPress has the ability to match the video player to its team colors, display a team logo, or turn off the share menu without the need to recompile a video player for each publisher.
<skinElement elementClass="com.videopress.osmfplayer.controls.TitleFrameLoaderAsset" id="postFrameLoader" initMethod="initPostFrameLoader" autoPosition="true" hAdjust="0" hAlign="LEFT" icon="replay" posterFrameURL="http://videos.videopress.com/OO4thna8/videopress2-web2.original.jpg" scaleMode="FIT" title="Introducing VideoPress for WordPress.com" vAdjust="0" vAlign="CENTER" watermarkURL="http://wptv.files.wordpress.com/2010/07/wptv.png" />
REOPS bundles the Captioning Plugin developed by Akamai and others. VideoPress extends the Captioning Plugin, enabling viewers to select from a list of language transcripts. Additional plug-ins are defined inside the configuration file and loaded at runtime. VideoPress publishers may use their own statistics provider or prefer a custom account identifier at an existing statistics network already used by VideoPress. Dynamic plug-in loading helps VideoPress choose from the growing list of OSMF analytics partners but only load extra SWF files when required by the current video configuration.
Media assets are described using the Flash Media Manifest (F4M) format. Asset information described in F4M includes multiple representations of the same piece of media, DRM authentication information, HTTP streaming bootstrap information, and more.
<manifest xmlns="http://ns.adobe.com/f4m/1.0"> <deliveryType>progressive</deliveryType> <streamType>recorded</streamType> <mimeType>video/mp4</mimeType> <id>OO4thna8</id> <duration>143</duration> <startTime>2009-05-18T17:25:49+00:00</startTime> <media bitrate="1528" width="640" height="360" url="http://videos.videopress.com/OO4thna8/videopress2-web2_dvd.mp4" /> <media bitrate="3160" width="1280" height="720" url="http://videos.videopress.com/OO4thna8/videopress2-web2_hd.mp4" /> </manifest>
REOPS uses more advanced aspects of OSMF such as a custom MediaFactory and a NetConnectionFactory to load defined media elements. REOPS exposes more complex functionality without requiring developers to tackle these more complex aspects of the framework. REOPS also includes a basic playlist system and reconnection system to reestablish a lost server connection.
REOPS provides the ability to completely reskin a player using a Flash template file applied via the configuration object. VideoPress built a custom skin on top of REOPS to match design and customization needs. Figure 3 shows three examples of control bar skins that can be applied to a REOPS player via the configuration object.
Figure 3. Three control bar skins that can be applied to the REOPS player.
Configuring skins in the REOPS player is as simple as specifying the correct skin SWF file in the configuration object. Here's an example of a custom control bar specified in XML:
<skin path="assets/skins/RE_Skin.swf"> <skinElement id="controlBar" elementClass="com.realeyes.osmfplayer.controls.ControlBar" initMethod="initControlBarInstance" scaleMode="NONE" hAdjust="0" vAdjust="0" vAlign="BOTTOM" autoPosition="true" draggable="true" autoHide="true" /> </skin>
The REOPS configuration object enables publishers to specify custom OSMF plug-ins for inclusion at runtime. The OSMF plug-in architecture allows developers and service providers to create plug-ins that unobtrusively enhance and extend the functionality of a media player. You may choose from a growing list of OSMF plug-in providers or write a plug-in for your own internal use.
<plugin path="http://www.realeyes.com/SampleBugPlugin.swf"> <metaData namespace="http://www.realeyes.com/watermark"> <value key="watermarkURL" type="string"> <id>http://www.realeyes.com/watermark.png</id> </value> </metaData> </plugin>
This code specifies a plug-in SWF location and configuration options. This simple plug-in passes the absolute URL of a watermark image to place on top of your media player object.
To create your own REOPS player, you need to download OSMF, REOPS, and the Captioning Plugin as the basis for a new player project. I recommend adding the source for these projects to your coding environment as a source path or library project for source-level debugging during development.
After workspace setup, the first step in making a custom player based on REOPS is to make the base application class extend the REOPS class. In this class, you add your own methods, and you override methods from REOPS to add your own functionality. There are several key methods in the application startup you will most likely need to override in your implementation.
The first two methods of interest handle the loading of the configuration for the player. The _loadConfigFile method in the REOPS class and the _onConfigLoaded method on the ConfigManager class load the configuration and then start the parsing of the config. Start here if you want to load your configuration file elsewhere or parse your configuration file differently using a custom translator.
Dynamic plug-ins (external plug-in SWF files) can be loaded via the configuration XML. If you are using static plug-ins (plug-ins compiled into the player), you need to override either the _initPlugins or the _onPluginsLoaded methods to include your static plug-ins. The _initMediaElement method sets up media for playback. The parsing is actually done by translators invoked by the PlayerConfig class's mediaElement getter method, but this method on the REOPS class gives you a chance to configure the media element before it is sent to the MediaPlayer. After the media element has been initialized, the next place to do some customization is with the _initSkin method on the REOPS class. This is where you initialize a custom SkinContainer class. This method is a good place to feed custom configuration data to the skin to be used in layout and functionality, as well as to set up event listeners to detect important events from the skin.
Creating a custom skin is beyond the scope of this article. The REOPS site has an article on the skinning system, but let's take a look at a few basics of creating custom controls in a skin. One way to customize the skin is to change the appearance of one of the available skin templates. If you're just changing visuals, then you need to remember not to change the instance names of any controls and not to change the timeline a control is in by putting it in a different movie clip.
Another way to customize the skin is by extending the existing controls and adding custom functionality. For instance, a developer can add a logo to a control bar that sends the user to a company's website when clicked. The first thing to do is point the skin FLA file toward the right codebase. The skin templates included with REOPS have a compiled code object called _code_ in the Library that contains the source code for the skin. This needs to be deleted so it does not interfere with the new code. Then in the ActionScript Settings dialog for the file (File > ActionScript Settings In Flash CS5), you can create a source path entry that points to the src directory in the REOPS project. You will also need to add a source path entry that points to the source directory for your custom player project.
Once the skin FLA file has the correct source, you can create your custom control bar by creating a class that extends the ControlBar class in the REOPS framework. To link the new class to the control in the skin, change the class for the control in the Flash Library panel. To change the class, right-click the control in the Library and select Properties in the context menu. In the Symbol Properties dialog box, change the Class entry to the full class path for the custom class. One thing to be aware of when linking a class to a symbol in the Library is that frame scripts in the control will be ignored if you set the Class entry to the new custom class. To avoid this problem, set the Base Class entry to be the new custom class. Then set the Class entry to be a nonexistent class. The convention of using the same class path as the base class but adding "Asset" to the end works well. Flash puts frame scripts into auto-generated classes for symbols. If you set the Class entry to an existing class, it can't add those frame scripts. Setting the Class entry to a nonexistent class allows Flash to auto-generate the class and attach those frame scripts.
Once the symbol in the skin is linked to the custom class, that class path can be used to instantiate that control. Substituting that class path for the ControlBar class path in the configuration XML will instruct REOPS to create an instance of the custom control instead of the standard ControlBar.
The process is largely the same for creating a completely new control for a custom player. The visuals for the control are defined in the skin files. They are linked to the custom classes. Those classes and controls are specified in the configuration XML. The skin container then instantiates the element from the skin files and places them into the player. The difference here is that you need to add in a new initialization method for the control in the skin container. This requires extending the SkinContainer class.
Init methods for skin elements tell the skin container how to set up the control. Extending the SkinContainer class allows you to add your own init method for your custom controls or override the existing init methods for standard controls. This enables developers to change the functionality associated with controls by overriding event handlers or altering property values.
This is a high-level view of the possibilities for creating custom media players from REOPS and OSMF. The bottom line is that the extensibility and functionality of REOPS will enable developers to quickly create robust video players with a high level of customizability. REOPS provides a video player powered by the amazing depth and versatility of Adobe's Open Source Media Framework that is ready to impress.
OSMF reached 1.0 status in May after 10 monthly releases. OSMF will continue to add new features in future releases, including quality of service APIs, support for new advertising formats, dynamic configuration options, HTML5 video markup integration, and much more. The active development of OSMF creates ongoing maintenance revenue for developers building on the platform. A steady stream of updates to the core platform and partner plug-ins deliver new client customization and maintenance requests, improving the Flash solutions developers can deliver to their clients.
To gain some hands-on experience with OSMF's capabilities for building and skinning custom media players, explore the RealEyes OSMF player sample series by David Hassoun and John Crosby.
Niall Kennedy is a web technologist in San Francisco, California, specializing in the web platform, syndication, video publishing, and widgets. Kennedy is president of Hat Trick Media, a consulting and product company providing the technical expertise, strategy, and implementation businesses need to stay competitive on the ever-changing web.