Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flash Developer Center /

RealEyes OSMF Player Sample – Part 3: Skinning and control bar system

by David Hassoun

David Hassoun
  • david.realeyes.com

by John Crosby

John Crosby
  • john.realeyes.com

Created

28 June 2010

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
customization Flash Media Server Flash Professional OSMF templates video

Requirements

Prerequisite knowledge

Basic knowledge of ActionScript 3 and Adobe Flash Builder or Adobe Flash Professional is recommended for this tutorial.

User level

Intermediate

Required products

  • Flash Builder (Download trial)
  • Flash Professional (Download trial)

The RealEyes OSMF Player Sample (REOPS) project has a robust, extensible skinning system that includes a fully featured control bar component that you can extend. The REOPS project also includes some professionally designed templates from Juan Sanchez that offer the visual building blocks for the visual elements and allow for further customization.

This article is a follow-up of our previous article, Part 2: Building and configuration, where we showed you how to build a simple OSMF player and then explained each of these OSMF building blocks in simple terms. This article provides a deeper look into the skinning process and framework functionality of the REOPS external skin management solution. This article not only provides details and hands-on walkthroughs showing how to customize the look and feel of what is available out of the box, but also shows how to extend it with additional functionality.

Understanding the skinning system

The REOPS skinning system is broken up into a few different parts. They all work and sequence together to offer the most control and functionality.

The REOPS skinning system does not rely on the OSMF framework, other than referencing the OSMF MediaPlayer for events and media control, and the player display object shell (MediaContainer or MediaPlayerShell) for sizing and positioning. There are, of course, benefits and drawbacks to the skinning system's not directly implementing the OSMF framework for display, layout, or loading. Possible future enhancements to the REOPS project may include converting all or parts of the skinning system to a more OSMF-centric system, possibly even leveraging the plugin system.

The skinning system sequence starts with the main REOPS player being loaded and instantiated. The newly instantiated player then loads the external configuration XML file. This configuration file is the main source of all runtime configuration management. The configuration file specifies the following:

  • What media is displayed and how to render it to the user
  • All the details for the skinning system:
    • The external skin SWF file to load. This file contains the visual elements of the player: control bar, loading indicator, closed caption field, and all other elements.
    • Which skin elements defined in the SWF file to actually create, and what properties to set on them.

The main REOPS player loads all the configuration data and parses it into its model (PlayerConfig). All the skinElement nodes of the configuration are parsed into SkinElement (com.realeyes.osmfplayer.model.config.skin.SkinElement) instances. Each skin element takes some base attributes used in the instantiation process:

  • id
  • initMethodName
  • elementClassString
  • altElementClass
  • altWidthThreshold

The only required attributes are the id and the elementClass attributes. The skin element can also have any number of additional attributes aside from the base ones above that will be applied to the skin element. These attributes can be whatever the component defined by the elementClassString attribute requires. Add those properties as attributes to the skinElement node. Those attributes are parsed and stored in a Dictionary object called properties on the com.realeyes.osmfplayer.model.config.skin.SkinElement class.

After the configuration data is loaded and parsed, the REOPS player goes through its initialization sequence, including the control bar container initialization (REOPS > _initSkin()), which instantiates the SkinContainer component and applies the configuration details (see Figure 1).

Analyzing the elements of the configuration XML file click to enlarge

Figure 1. Analyzing the elements of the configuration XML file

The SkinContainer loads the specified external skin SWF file into the same application context as the main REOPS application (SkinContainer > loadExternal()). Upon the completion of loading the external skin SWF file, the SkinContainer event handler (SkinContainer > _skinLoadComplete()) loops through the skinElements parsed from the configuration file. This is where things start to get complicated internally. As the SkinContainer loops through the elements, it dynamically generates instances from the skin SWF file based on the configuration skinElement node parameters.

Here is the process the system goes through when generating skin elements:

  1. The system does a check to see if altElementClass and altWidthThreshold are defined. The altElementClass attribute defines the full class path of the skin element class to instantiate if the width of the media player shell is less than the value of the altWidthThreshold attribute.
  2. If the altElementClass and altThreshold attributes are not defined, or if the size of the media player shell is greater than the threshold, the elementClass attribute will be used to determine which class to instantiate.
  3. Once the conditional logic to determine which class to instantiate is complete, the SkinContainer will invoke the buildSkinElement() method on the SkinElement class, creating the instance and dynamically applying all the attributes defined on the skin element's properties Dictionary object.
  4. The instance is added to the display list and two checks happen. First, the system checks if there is a value defined for the initMethodName property of the SkinElement. If there is, the method is dynamically invoked on the SkinContainer class and the instance is passed to the method as a parameter. This is very useful to set up event listeners and additional initialization that the newly created instances may require.
  5. The system checks to see if autoPosition has a Boolean value of true. If it does, the system then calls the SkinContainer's updatePosition() method and passes the instance as a parameter. The updatePosition() method handles dynamically positioning the SkinElement instance based on the data values set in the configuration file.

The following properties have control over the positioning, if defined in the config: scaleMode, hAdjust, vAdjust, hAlign, and vAlign. The scaleMode property defines whether the element should be scaled based on the size of the media player shell. Currently the only supported value is stretch, which will scale the SkinElement up or down to match the width of the media player shell while maintaining the proper aspect ratio.

The hAdjust and vAdjust properties simply add the defined numeric values to the horizontal x position (hAdjust) or the vertical y position (vAdjust). Positive and negative numbers are supported. These properties can be used on their own or in conjunction with the alignment properties as well. The hAlign and vAlign properties control the positioning of the element in relation to the media player shell. If the value of hAlign is right and vAlign is center, then the particular skin element would be placed in the middle of the video player shell, aligned to the right edge. All of the positioning properties/attributes are optional, and the default position is centered at the bottom.

An important note regarding the autoPosition feature: When entering and returning from full-screen mode, if a skin element has the autoPosition property set to true, it will rerun the SkinContainer's updatePosition() method for all those elements, repositioning them after the media player shell has been scaled to full screen, then rerunning the method on return from full-screen to return them to their original positions. This is true for all elements other than the instance set to the _controlBar property via the initControlBarInstance() method. That method would be invoked from the initMethod attribute defined in the configuration file for the desired control bar skin element.

Using the provided skin elements within the templates

The skin samples/templates that come with the REOPS project have a few components that are ready to be implemented via skin elements and provide the building blocks to extend further. This section of the article will explore the different components, their usage, and purpose.

SkinElementBase

All the components within the skin templates extend the SkinElementBase class (com.realeyes.osmfplayer.controls.SkinElementBase). This class simply provides the similar properties used by the autoPosition system.

LoadingIndicator

The first and simplest component is the LoadingIndicator component (com.realeyes.osmfplayer.controls.LoadingIndicator). This is a simple loading spinner, and the only feature it contains other than purely timeline-driven visuals is the optional ability to set a label property to change the text it displays with the spinner. Like all the other skin elements provided, it extends the SkinElementBase and thus has the ability to use the autoPosition feature.

ClosedCaptionField

The ClosedCaptionField component is also a very simple class (com.realeyes.osmfplayer.controls.ClosedCaptionField). It is meant to be applied to a Flash MovieClip with a cc_txt TextField instance and any other desired visuals. It is the visual display field for showing closed captioning. When the class instantiates, it sets its visibility to false and has a text() getter/setter method for setting the actual text displayed in the TextField.

ControlBar

The ControlBar component (com.realeyes.osmfplayer.controls.ControlBar) is the most complex in the template. In general, it is meant as a container for all of its optional subcomponents that you as the designer or developer may choose to implement. It is developed to be able to add or omit any of the predefined controls. To this end, it checks to see if one of the predefined controls exists. If so, it sets up the appropriate event handlers to catch the user interactions with the controls—such as clicking on a pause button or toggling the mute button. The ControlBar component also has some more advanced controls, such as the the volume bar and the progress bar, which the ControlBar uses to show progress, buffer length and the like. Both the ProgressBar (com.realeyes.osmfplayer.controls.ProgressBar) and the VolumeSlider (com.realeyes.osmfplayer.controls.VolumeSlider) are basic interactive controls with the needed functionality coded behind them.

Aside from those two controls, all the others are basic buttons, many with toggle capabilities. All the button-based controls either directly apply or extend the ToggleButton class (com.realeyes.osmfplayer.controls.ToggleButton). Those controls that do not need the toggle button functionality, such as a simple stop button, simply set the toggle property to false when they are initialized or when they are referenced in the ControlBar component (ControlBar > _initListeners()). The ControlBar either passes interaction events from the buttons or bar components to the SkinContainer, or receives data from the SkinContainer to apply to the controls (progress, isLive, and disabling of controls as necessary, based on playback state). A minor but valuable note on the ControlBar component is that there is a width and height getter/setter that overrides the default width/height getter/setters of the MovieClip. It passes along the width and height of the bg_mc MovieClip that is expected to be within the ControlBar component. This enables a more controllable sizing reference for the autoPosition feature when items such as a vertical volume slider are in play.

On top of that, the ControlBar component can do smart resizing to scale the width of the bar without scaling the height and then reposition its child buttons appropriately. This smart resizing is triggered by setting the ControlBar's scaleMode property to "squeeze." During this resizing, the ControlBar class looks to see which controls are present and whether they are on the left or right side of the ControlBar instance. If the controls are left of center, they will be anchored to the left side; if the controls are right of center, they will be anchored to the right side. The ControlBar then resizes the background graphic to fit the width of the player and then repositions the controls based on their previous position in the ControlBar. The ProgressBar instance, if present, will be stretched or squeezed to fill the space between the controls on either side of it. Because of this, both the background graphic for the ControlBar and the ProgressBar symbol need to be set up with scale-9 slicing to ensure optimal appearance of the ControlBar as it resizes.

For this smart resizing to work, the control instances must be named the same. For instance, the background graphic must be bg_mc. Only controls defined in the ControlBar class will be repositioned. However, the ControlBar class can be extended and adapted to reposition custom controls or graphics. You can also control how the individual controls are anchored by setting the anchor property in the control's class definition. It can be set to "left," "right," or "both." Setting the property to "both" will cause it to be stretched like the ProgressBar. Look at the ProgressBar class to see how this is implemented.

Note: In the skin templates, the classes are applied to the MovieClips in the Library Panel via the Advanced view of the Symbol Properties window, and are applied directly as the Class for the Linkage. This process has the benefit of directly using the defined class instead of subclassing it and generating additional classes dynamically, as would happen if a class were applied to the Base Class field instead. However, since the class is applied to the Class field instead of the Base Class field, this process has the drawback of not allowing any frame scripts to be applied to the components. This means that if you desire to use any frame scripts, you should switch the defined class to the Base Class field and supply a new class name in the Class field that will be dynamically created. Be sure to use whatever the value is in the Class field in the XML configuration file when you want to apply the component or MovieClip as a SkinElement.

The glue that holds all the elements together actually invokes the displays and controls the media is the SkinContainer. With the included elements, the SkinContainer has the definitions for the initMethods of each SkinElement. Those initMethods create the event handlers and set up the proper display and initialization properties, and then maintain the links between the media playback and the visual elements. A key example of this is how the ControlBar controls the media playback. All of this is done by simply broadcasting events such as the ControlBarEvent with a type of ControlBarEvent.PAUSE from the ControlBar skin element. The SkinContainer listens for such events, and then calls the appropriate method (example: pause()) on the media player.

To add new custom skin elements into the deployment, the process is fairly simple. Add the visual elements to the skin FLA file and link them to any code they need by providing them with a Class or Base Class. Any class for your component should extend SkinElement. Then add the appropriate skinElement node to the XML configuration file. If your new element requires integration with the media player or other UI controls, then you will likely want to extend the SkinContainer with a custom class and create the appropriate one or more initMethods for your skin elements. Make sure the custom extension of the SkinContainer is used in the REOPS main class—either by extending or modifying that class—and that should be it. We will publish a fully detailed, step-by-step hands-on article later showing exactly how to do this.

Customizing the skin appearance

Having a high-impact visual display for a video player is an ever-growing request. The REOPS project has attempted to provide an effective visual skinning system, backed by the ability to add custom functionality and leverage the power of the OSMF. The visual skins provided offer great, professional-quality visuals that you are welcome to use out of the box, customize to make your own, or simply use as a referenced starting point for building your own skin from the ground up. Really, the only requirement for the most complex provided skin element (the control bar) is that the instances have the right names, and that the main component implements or extends the default ControlBar class. The visual side is open to whatever the world desires and your creativity can imagine.

The skin templates are installed as Flash templates with the REOPS Flash Extension (MXP) available from the REOPS project page. They are accessed in the initial start splash screen > Create from Template > OSMF_Skins or via the File > New > Templates (tab on top) > OSMF_Skins (see Figure 2)

Accessing a skin template
Figure 2. Accessing a skin template

The templates themselves are broken out into two main parts, Compositions and Assets (see Figure 3).

Identifiying template elements by type
Figure 3. Identifiying template elements by type

Compositions are the actual SkinElements and are technically component MovieClips with classes defined for the linkages. In the provided templates this includes the LoadingIndicator, ClosedCaptionField, and the ControlBar. One of the major benefits of the skin templates with the REOPS project is that you can actually compile and see the animations and user interactions of the compositions independent of the player. This allows for true layout testing, user interaction, and motion review before deploying. This is in part because the code for the aforementioned skin elements is actually supplied as a compiled clip within the library of the skin templates. The code is also in the REOPS project if you prefer to work directly with the source and map the class-path of the FLA to the REOPS source. The concept of the compositions is they contain the different individual controls, or assets.

Whichever assets are implemented by a composition is completely up to the designer and developer. It is as simple as copying and pasting the asset into a composition and positioning it appropriately on the timeline—or via ActionScript if you prefer and understand the process. In essence, the Assets section of the template can be viewed as the preparation section. In the Assets section, you can simply double-click any item to edit its visual source or sources. If that asset is already in the composition, then you will see it update appropriately there as well. Similarly, if it is already in the composition, you can edit directly from the composition and see it update in the assets. if the asset doesn't exist in the composition initially, all you have to do is copy and paste the asset from the below section directly into one of the compositions. Since all the assets on the Stage are already applied with the appropriate instance names, they should work automatically for you when applied to an appropriate skin element such as the ControlBar.

It is important to note that these instance names should not be changed, and cannot be nested deeper than direct children of such components unless you update the code appropriately for your use case. All of the assets in the skin templates are on a layer set as a guide and thus will not appear when you compile the skin. This is done on purpose to not detract from the compositions when testing, as the compositions are the only items available to be used by default from the skin SWF files via the XML configuration system.

Juan Sanchez, who designed the skin templates around the base we provided, wrote an excellent article, OSMF Player Skins, describing his process for the design and implementation. In general, the recommended approach for skinning is easy: First pick a template that matches the basic direction you want to follow; then modify the assets as you see fit.

Where to go from here

The skinning system from the RealEyes OSMF Player Sample project offers a lot of functionality out of the box, and both visual and functional extensibility. This article has offered you some insight into the concepts, capabilities, structure, and sequence in which the skinning system works. The key player in managing the skin elements is the SkinContainer; refer to the SkinContainer class for a deeper dive into the system.

In a future article, we will dive into a hands-on approach of creating customized skins and adding new functionality to the skin and player. Check back often on the REOPS code page for more samples and enhancements, too.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License

More Like This

  • Captioning Flash video with Captionate and the captioning-supported FLVPlayback component skins
  • Creating a Talking-Head Flash Video
  • vidgal_structure_mx2004
  • Flash 411: Getting your video questions answered
  • Deconstructing the ActionScript 3 Flash video gallery application
  • Generating sounds dynamically in Flash Player 10
  • Using the FLVPlayback component with Flash Player 9 Update 3
  • Flash CS4 Missing Manual excerpts: Video, testing and debugging, optimization, and sound
  • Exploring the Flash video templates and tutorials
  • Delivering a reliable Flash video experience

Flash User Forum

More
04/23/2012 Auto-Save and Auto-Recovery
04/23/2012 Open hyperlinks in new window/tab/pop-up ?
04/21/2012 PNG transparencies glitched
04/01/2010 Workaround for JSFL shape selection bug?

Flash Cookbooks

More
02/13/2012 Randomize an array
02/11/2012 How to create a Facebook fan page with Flash
02/08/2012 Digital Clock
01/18/2012 Recording webcam video & audio in a flv file on local drive

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement