Flex Strobe Media Playback component

Posted: 08/02/11

An image of Flex Strobe Media Playback component

Want Strobe Media Playback compiling into your Flex application; displaying as a UIComponent that resizes according to the constraints imposed by the parent container? This post will help you.

By modifying StrobeMediaPlayback.as, then encapsulating it inside a UIComponent, you can instantiate SMP anywhere inside your Flex app as an MXML component. Follow the steps below to get it working inside your own Flex app.

Flex 4/4.1/Hero:

Please compile against OSMF 1.5 or higher. Flex 4/4.1 ship with OSMF 0.95, Hero ships with 1.0. Be sure to delete OSMF.swc from the Flex Library Path and replace it with one downloaded from the OSMF download site.

Download my Modified StrobeMediaPlayback class file for your project, the Flex component that follows implements this class, and requires some custom methods that I've added. The modified class was extracted from the SMP 1.5 source (01 Dec 2010).

The main modifications to this class are to the way in which it redraws itself. Out-of-the-box StrobeMediaPlayback assigns a resize listener to the stage and redraws its child display objects whenever the size of the stage is altered. This is perfect in the context of a video player embedded in a web page - as SMP is designed to be - but not so good if you're wanting to use it in the context of a Flex application, where it will need to conform to the size constraints imposed upon it by its parent container(s). To avoid this problem I've added width and height properties to the StrobeMediaPlayback class, and when they're called it 'marks' itself for redraw on the next frame, which you see happening in the onInvalidate() method. This onInvalidate method is actually just the onStageResize named. After implementing this, StrobeMediaPlayback draws itself each time the width and/or height properties are updated, and only draws itself to the dimensions supplied - no more taking over the stage!

Next is the UIComponent that implements the modified StrobeMediaPlayback class, wrapping it as a Flex component, and updating the wrapped player's dimensions when the framework events fire:

package com.jodieorourke.flexosmf

{

import flash.events.Event;

import flash.events.EventDispatcher;

import mx.core.UIComponent;

import org.osmf.events.DisplayObjectEvent;

import org.osmf.media.DefaultMediaFactory;

import org.osmf.media.URLResource;

import org.osmf.player.media.StrobeMediaPlayer;

public class FlexSMP extends UIComponent

{

private var _mediaPlayer:StrobeMediaPlayback;

private var _source:String;

private var _factory:DefaultMediaFactory;

private var _mediaWidth:int;

private var _mediaHeight:int;

public function FlexSMP()

{

super();

addEventListener( Event.ADDED_TO_STAGE, addedToStage );

percentWidth = percentHeight = 100;

minWidth = minHeight = 5;

_factory = new DefaultMediaFactory();

}

protected function addedToStage( e:Event ) :void

{

removeEventListener( Event.ADDED_TO_STAGE, addedToStage );

_mediaPlayer.initialize( loaderInfo.parameters, stage, loaderInfo, null );

if( _source)

{

playMedia();

}

}

override protected function createChildren() :void

{

super.createChildren();

_mediaPlayer = new StrobeMediaPlayback();

addChild( _mediaPlayer );

}

override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ) :void

{

super.updateDisplayList( unscaledWidth, unscaledHeight );

if( _mediaPlayer )

{

_mediaPlayer.width = unscaledWidth;

_mediaPlayer.height = unscaledHeight;

}

}

override protected function measure() :void

{

super.measure();

measuredWidth = _mediaWidth;

measuredHeight = _mediaHeight;

measuredMinWidth = measuredMinHeight = 5;

}

protected function playMedia() :void

{

if( _mediaPlayer )

{

_mediaPlayer.media = _factory.createMediaElement( new URLResource( _source ) );

_mediaPlayer.player.addEventListener( DisplayObjectEvent.MEDIA_SIZE_CHANGE, onMediaSizeChange );

_mediaPlayer.player.play();

}

}

protected function onMediaSizeChange( e:DisplayObjectEvent ) :void

{

e.stopPropagation();

_mediaWidth = e.newWidth;

_mediaHeight = e.newHeight;

invalidateSize();

invalidateDisplayList();

}

public function set source( value:String ) :void

{

_source = value;

playMedia();

}

}

}

In the code above you see the createChildren(), measure() and updateDisplayList() methods, common to Flex components. You also see that a MEDIA_SIZE_CHANGE is assigned directly to StrobeMediaPlayback's MediaPlayer instance, this allows me to be notified of when the loaded media changes in size, so that the new dimensions can be stored in the _mediaWidth and _mediaHeight member variables. When the component comes to invalidateSize() and invalidateDisplayList() it first checks to see if any explicit dimensions have been assign to it by the parent container, and if they haven't it resizes itself to the dimensions of its loaded media.

Finally, here's the application code that implements 2 instances of the FlexSMP component:

<?xml version="1.0" encoding="utf-8"?>

<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" xmlns:flexosmf="com.jodieorourke.flexosmf.*">

<fx:Declarations>

<!-- Place non-visual elements (e.g., services, value objects) here -->

</fx:Declarations>

<fx:Script>

<![CDATA[

private const RTMP:String = "rtmp://cp67126.edgefcs.net/ondemand/mediapm/strobe/content/test/SpaceAloneHD_sounas_640_500_short";

private const HTTP:String = "http://mediapm.edgesuite.net/osmf/content/test/manifest-files/dynamic_Streaming.f4m";

]]>

</fx:Script>

<mx:HBox>

<s:Panel title="Flex Strobe Media Playback Wrapper" width="50%" height="50%">

<flexosmf:FlexSMP source="{RTMP}"/>

</s:Panel>

<s:Panel title="Flex Strobe Media Playback Wrapper" width="50%" height="50%">

<flexosmf:FlexSMP source="{RTMP}"/>

</s:Panel>

</mx:HBox>

</s:Application>

You can test the resize-to-content vs. constrain to parent's dimensions by removing the outer containers that constrained the component's dimensions:

<?xml version="1.0" encoding="utf-8"?>

<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" xmlns:flexosmf="com.jodieorourke.flexosmf.*">

<fx:Declarations>

<!-- Place non-visual elements (e.g., services, value objects) here -->

</fx:Declarations>

<fx:Script>

<![CDATA[

private const RTMP:String = "rtmp://cp67126.edgefcs.net/ondemand/mediapm/strobe/content/test/SpaceAloneHD_sounas_640_500_short";

private const HTTP:String = "http://mediapm.edgesuite.net/osmf/content/test/manifest-files/dynamic_Streaming.f4m";

]]>

</fx:Script>

<flexosmf:FlexSMP source="{RTMP}"/>

</s:Application>

Download Strobe Media Playback

Keywords for this post: flex, actionscript 3, strobe media playback, osmf, adobe, video, player, uicomponent