OSMF Player Development (Flash SDK) - Deprecated

The Uplynk Flash SDK has been deprecated. It is recommended that all customers transition to the Uplynk HTML5 AdaptivePlayer. The documentation for legacy flash-based web browser players is still available for reference.

This guide is provided to assist an integrator with the use of the Uplynk OSMF plugin. By using the plugin with the OSMF, you will be able to create a player with a custom skin and personalized playout experience.

For more details about OSMF, Please visit the Open Source Media Framework website. Adobe also provides the OSMF API online.

Use the Uplynk OSMF plugin to create a custom OSMF player .

http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf

Create a Custom OSMF Player

If you are using OSMF or an OSMF-based player such as Strobe, you can create a custom player that loads the Uplynk libraries dynamically as follows:

Basic plugin usage:

package {
    import flash.display.Sprite;
    import org.osmf.media.MediaPlayerSprite;
    import org.osmf.media.URLResource;
    import org.osmf.media.MediaFactory;
    import org.osmf.media.DefaultMediaFactory;
    import org.osmf.events.MediaFactoryEvent;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;

    public class OSMFTestPlayer extends Sprite
    {
        private var factory:MediaFactory;
        private static const MEDIA_URL:String = 'https://content.uplynk.com/content/xxxx.m3u8';

        public function OSMFTestPlayer()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            factory = new DefaultMediaFactory();
            factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD, onPluginLoad);

            var resource:URLResource = new URLResource('http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf');
            factory.loadPlugin( resource );
        }

        private function onPluginLoad(e:MediaFactoryEvent):void
        {
            var sprite:MediaPlayerSprite = new MediaPlayerSprite(null, null, factory);
            addChild(sprite);

            sprite.resource = new URLResource(MEDIA_URL);
        }
    }
}

OSMF Metadata

OSMF uses metadata in order to provide access features inside the OSMF framework. Uplynk provides several metadata hooks that you can use. they are as follows:

Available metadata namespaces:

// Defines namespaces for listening to asset metadata events
public static const UPLYNK_ASSET_NAMESPACE:String 			= "http://www.uplynk.com/streaming/asset/1.0";
public static const UPLYNK_ASSET_NAMESPACE_KEY_ASSET_METADATA:String 	= "assetMetadata"
public static const UPLYNK_ASSET_NAMESPACE_KEY_ID3:String 		= "ID3"

//Defines namespaces for accessing and configuring internal renderer
public static const UPLYNK_CAPTION_METADATA_NAMESPACE:String		= "http://www.uplynk.com/metadata/caption/1.0";

public static const UPLYNK_CAPTION_KEY_SELECTED_CAPTION:String 		= "selectedCaption";
public static const UPLYNK_CAPTION_KEY_RENDERER_SETTINGS:String 	= "rendererSettings";
public static const UPLYNK_CAPTION_KEY_AVAILABLE_VTT_STREAMS:String 	= "availableVttStreams";
public static const UPLYNK_CAPTION_KEY_AVAILABLE_608_CHANNELS:String 	= "available608Channels";

//Defines namespaces for accessing internal webvtt subtitling.
public static const UPLYNK_WEBVTT_NAMESPACE:String 		= "http://www.uplynk.com/timeline/webvtt/1.0";
public static const UPLYNK_WEBVTT_KEY_SELECTED_CAPTION:String 	= "selectedCaption";
public static const UPLYNK_WEBVTT_KEY_WEBVTT:String 		= "webvtt";

//Defnies namespaces for accessing 608 CC streams
public static const UPLYNK_CAPTION_NAMESPACE_v1_1:String 	= "http://www.uplynk.com/timeline/caption/1.1";
public static const UPLYNK_CAPTION_KEY_CAPTION:String 		= "caption";

// Defines namespaces for listening to SegmentMap changes
public static const UPLYNK_SEGMENTMAP_NAMESPACE:String 		= "http://www.uplynk.com/stream/segmentmap/1.0";
public static const UPLYNK_SEGMENTMAP_KEY_SEGMENTMAP:String 	= "segmentMap"

OSMF Metadata Example #1 - Internal CC and subtitle support + assetMetadata

The following is an example of how to setup and listen for different metadata events in a OSMF player. In this example we will setup the internal CC Renderer. select a caption and also listen for assetMetadata.

Internal CC and subtitle support + assetMetadata:

package {

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.osmf.events.MediaElementEvent;
	import org.osmf.events.MediaFactoryEvent;
	import org.osmf.events.MetadataEvent;
	import org.osmf.events.TimelineMetadataEvent;
	import org.osmf.media.DefaultMediaFactory;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactory;
	import org.osmf.media.MediaPlayerSprite;
	import org.osmf.media.URLResource;
	import org.osmf.metadata.Metadata;
	import org.osmf.metadata.TimelineMetadata;

	[SWF(backgroundColor="#000000")]
	public class OsmfPlayer extends Sprite
	{


		private var factory:MediaFactory;
		private var mediaPlayer:MediaPlayerSprite;
		private var mediaElement:MediaElement;

		private static const MEDIA_URL:String = "https://content.uplynk.com/content/xxxx.m3u8";

		private var captionSelected : Boolean = false;

		public function OsmfPlayer()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;

			factory = new DefaultMediaFactory();
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD, onPluginLoad);
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD_ERROR, onPluginLoadError);

			trace('loading plugin');
			var resource:URLResource = new URLResource('http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf');
			factory.loadPlugin(resource);
		}

		private function onPluginLoad(e:MediaFactoryEvent):void
		{
			var resource : URLResource = new URLResource( MEDIA_URL );
			eesource.addMetadataValue( "http://www.uplynk.com/metadata/caption/1.0" , {} ); // Notifies the plugin to use the internal CC renderers

			mediaPlayer = new MediaPlayerSprite(null, null, factory);
			addChild(mediaPlayer);

			mediaElement = factory.createMediaElement(resource);
			mediaElement.addEventListener(MediaElementEvent.METADATA_ADD, onMetadataAdd);

			mediaPlayer.media = mediaElement;
		}

		private function onPluginLoadError(e:MediaFactoryEvent):void
		{
			trace('error loading plugin');
		}

		private function onMetadataAdd(event:MediaElementEvent):void
		{
			if( event.namespaceURL == "http://www.uplynk.com/metadata/caption/1.0" )
			{
				var caption:Metadata = mediaElement.getMetadata("http://www.uplynk.com/metadata/caption/1.0") as Metadata;
				caption.addEventListener(MetadataEvent.VALUE_CHANGE, onCaptionChanged);
				caption.addEventListener(MetadataEvent.VALUE_ADD, onCaptionChanged);
			}

			else if( event.namespaceURL == "http://www.uplynk.com/streaming/asset/1.0"  )
			{
				var asset:Metadata = mediaElement.getMetadata("http://www.uplynk.com/streaming/asset/1.0") as Metadata;
				asset.addEventListener(MetadataEvent.VALUE_CHANGE, onAssetChanged);
				asset.addEventListener(MetadataEvent.VALUE_ADD, onAssetChanged);
			}
		}

		private function onCaptionChanged(event:MetadataEvent):void
		{

			switch(event.key)
			{
				case "available608Channels":
				{
					//selects the first CC channel.
					var channels : Vector.<int> = event.value;
					if(channels.length > 0){
						selectCaption(channels[0]);
					}

					break;
				}

				case "availableVttStreams":
				{
					//selects a random track.
					var tracks : Vector.<Object> = Vector.<Object>( event.value );
					if(tracks.length > 0){
						var index : int = Math.floor(Math.random()*tracks.length)
						trace("Selecting Track Index: [" + index + "] Language: " + tracks[index].language);
						selectCaption(tracks[index]);
					}


					break;
				}

			}
		}

		private function onAssetChanged(event:MetadataEvent):void
		{
			switch(event.key)
			{
				case "assetMetadata":
				{
					// Add your code here to handle new metadata associated with the new asset ID
					break;
				}

			}
		}

		private function selectCaption( data : Object) : void
		{
			// for this demo we just select the first CC that comes in first.
			if(!captionSelected){
				var caption:Metadata = mediaElement.getMetadata("http://www.uplynk.com/metadata/caption/1.0") as Metadata;
				caption.addValue("selectedCaption",data);
				captionSelected = true;
			}
		}



	}
}

OSMF Metadata Example #2 - DIY Basic CC support + assetMetadata

The following is an example of how to setup and listen for different metadata events in a OSMF player. In this example we will setup our own basic CC renderer and listen for assetMetadata

DIY basic CC support + assetMetadata:

package {

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.osmf.events.MediaElementEvent;
	import org.osmf.events.MediaFactoryEvent;
	import org.osmf.events.MetadataEvent;
	import org.osmf.events.TimelineMetadataEvent;
	import org.osmf.media.DefaultMediaFactory;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactory;
	import org.osmf.media.MediaPlayerSprite;
	import org.osmf.media.URLResource;
	import org.osmf.metadata.Metadata;
	import org.osmf.metadata.TimelineMetadata;

	[SWF(backgroundColor="#000000")]
	public class OsmfPlayer extends Sprite
	{

		private var _captionsAvailable : Boolean = false;
		public var captionsEnabled : Boolean = true;

		private var captionDisplay : TextField;

		private var factory:MediaFactory;
		private var mediaPlayer:MediaPlayerSprite;
		private var mediaElement:MediaElement;

		private static const MEDIA_URL:String = "https://content.uplynk.com/content/xxxx.m3u8";

		public function get captionsAvailable() : Boolean{
			return _captionsAvailable
		}

		public function OsmfPlayer()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;

			factory = new DefaultMediaFactory();
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD, onPluginLoad);
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD_ERROR, onPluginLoadError);

			trace('loading plugin');
			var resource:URLResource = new URLResource('http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf');
			factory.loadPlugin(resource);
		}

		private function onPluginLoad(e:MediaFactoryEvent):void
		{
			var resource : URLResource = new URLResource( MEDIA_URL );

			mediaPlayer = new MediaPlayerSprite(null, null, factory);
			addChild(mediaPlayer);

			mediaElement = factory.createMediaElement(resource);
			mediaElement.addEventListener(MediaElementEvent.METADATA_ADD, onMetadataAdd);
			initializecaption();

			mediaPlayer.media = mediaElement;
		}

		private function onPluginLoadError(e:MediaFactoryEvent):void
		{
			trace('error loading plugin');
		}

		private function onMetadataAdd(event:MediaElementEvent):void
		{
			if (event.namespaceURL == "http://www.uplynk.com/timeline/caption/1.1")
			{
				var oldCaptionMetadata:Metadata = mediaElement.getMetadata("http://www.uplynk.com/timeline/caption/1.1") as Metadata;
				oldCaptionMetadata.addEventListener(MetadataEvent.VALUE_CHANGE, onCaption);
				oldCaptionMetadata.addEventListener(MetadataEvent.VALUE_ADD, onCaption);
			}

			else if( event.namespaceURL == "http://www.uplynk.com/streaming/asset/1.0"  )
			{
				var asset:Metadata = mediaElement.getMetadata("http://www.uplynk.com/streaming/asset/1.0") as Metadata;
				asset.addEventListener(MetadataEvent.VALUE_CHANGE, onAssetChanged);
				asset.addEventListener(MetadataEvent.VALUE_ADD, onAssetChanged);
			}
		}

		private function initializecaption() : void
		{
			captionDisplay = new TextField();
			captionDisplay.visible = false;
			captionDisplay.autoSize = TextFieldAutoSize.LEFT;
			captionDisplay.multiline = true;
			captionDisplay.background = true;
			captionDisplay.backgroundColor = 0x000000;

			var defaultFormat:TextFormat = new TextFormat();
			defaultFormat.color = 0xFFFFFF;
			defaultFormat.font = "Verdana";
			defaultFormat.size = 16;
			captionDisplay.defaultTextFormat = defaultFormat;

			addChild( captionDisplay );
		}

		private function onCaption(event:MetadataEvent):void
		{
			var captionData : Object = event.value;

			_captionsAvailable = true;
			if(captionsEnabled){
				captionDisplay.htmlText= captionData.text;
				captionDisplay.visible = true;
				captionDisplay.x = (stage.stageWidth - captionDisplay.width) / 2;
				captionDisplay.y = stage.stageHeight - captionDisplay.height - 50;
			}

		}

		private function onAssetChanged(event:MetadataEvent):void
		{
			switch(event.key)
			{

				case "assetMetadata":
				{
					// Add your code here to handle new metadata associated with the new asset ID
					break;
				}

			}
		}



	}
}

OSMF Metadata Example #3 - ID3 and SegmentMap

The following is an example of how to setup and listen for different metadata events in a OSMF player. In this example we will setup listen for ID3 and segment map events

DIY basic CC support + assetMetadata:

package {

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import org.osmf.events.MediaElementEvent;
	import org.osmf.events.MediaFactoryEvent;
	import org.osmf.events.MetadataEvent;
	import org.osmf.events.TimelineMetadataEvent;
	import org.osmf.media.DefaultMediaFactory;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactory;
	import org.osmf.media.MediaPlayerSprite;
	import org.osmf.media.URLResource;
	import org.osmf.metadata.Metadata;
	import org.osmf.metadata.TimelineMetadata;

	[SWF(backgroundColor="#000000")]
	public class OsmfPlayer extends Sprite
	{

		private var factory:MediaFactory;
		private var mediaPlayer:MediaPlayerSprite;
		private var mediaElement:MediaElement;

		private static const MEDIA_URL:String = "https://content.uplynk.com/content/xxxx.m3u8";

		public function OsmfPlayer()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;

			factory = new DefaultMediaFactory();
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD, onPluginLoad);
			factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD_ERROR, onPluginLoadError);

			trace('loading plugin');
			var resource:URLResource = new URLResource('http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf');
			factory.loadPlugin(resource);
		}

		private function onPluginLoad(e:MediaFactoryEvent):void
		{
			var resource : URLResource = new URLResource( MEDIA_URL );

			mediaPlayer = new MediaPlayerSprite(null, null, factory);
			addChild(mediaPlayer);

			mediaElement = factory.createMediaElement(resource);
			mediaElement.addEventListener(MediaElementEvent.METADATA_ADD, onMetadataAdd);

			mediaPlayer.media = mediaElement;
		}

		private function onPluginLoadError(e:MediaFactoryEvent):void
		{
			trace('error loading plugin');
		}

		private function onMetadataAdd(event:MediaElementEvent):void
		{
			if( event.namespaceURL == "http://www.uplynk.com/streaming/asset/1.0"  )
			{
				var asset:Metadata = mediaElement.getMetadata("http://www.uplynk.com/streaming/asset/1.0") as Metadata;
				asset.addEventListener(MetadataEvent.VALUE_CHANGE, onAssetChanged);
				asset.addEventListener(MetadataEvent.VALUE_ADD, onAssetChanged);
			}

			else if( event.namespaceURL == "http://www.uplynk.com/stream/segmentmap/1.0"  )
			{
				var segment:Metadata = mediaElement.getMetadata("http://www.uplynk.com/stream/segmentmap/1.0") as Metadata;
				segment.addEventListener(MetadataEvent.VALUE_CHANGE, onSegmentMapChanged);
				segment.addEventListener(MetadataEvent.VALUE_ADD, onSegmentMapChanged);
			}
		}


		private function onAssetChanged(event:MetadataEvent):void
		{
			if(event.key == "ID3")
			{
				if(event.value.type == "TXXX")
				{
					trace( "TXXX: " + event.value.data);
				}
				break;
			}

		}

		private function onSegmentMapChanged(event:MetadataEvent):void
		{

			if(event.key == "segmentMap")
			{
				var segments : Vector.<Object> = Vector.<Object>( event.value );
				for each( var segment : Object in segments){
					trace("Asset ID: " + segment.id +"\n" +
						  "Type: " + segment.type +"\n" +
						  "Index: " + segment.index +"\n" +
						  "Position: " + segment.position +"\n" +
						  "Duration: " + segment.duration );
				}
			}
		}



	}
}

OSMF Dynamic Stream Trait and Alternate Audio Trait

The following is an example of how to setup and listen for different trait events in order to handle events dealing with dynamic streaming and switching audio sources

Plugin with advanced traits:

package {
    import flash.display.Sprite;
    import org.osmf.media.MediaPlayerSprite;
    import org.osmf.media.URLResource;
    import org.osmf.media.MediaFactory;
    import org.osmf.media.DefaultMediaFactory;
    import org.osmf.events.MediaFactoryEvent;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;

    import org.osmf.events.AlternativeAudioEvent;
    import org.osmf.events.DynamicStreamEvent;


    public class OSMFTestPlayer extends Sprite
    {
        private var factory:MediaFactory;
        private static const MEDIA_URL:String = 'https://content.uplynk.com/content/xxxx.m3u8';

        public function OSMFTestPlayer()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            factory = new DefaultMediaFactory();
            factory.addEventListener(MediaFactoryEvent.PLUGIN_LOAD, onPluginLoad);

            var resource:URLResource = new URLResource('http://storage.uplynk.com/client/latest_upLynkOsmfPlugin.swf');
            factory.loadPlugin( resource );
        }

        private function onPluginLoad(e:MediaFactoryEvent):void
        {
            var sprite:MediaPlayerSprite = new MediaPlayerSprite(null, null, factory);

            mediaPlayerSprite.mediaPlayer.addEventListener(AlternativeAudioEvent.NUM_ALTERNATIVE_AUDIO_STREAMS_CHANGE, onNumAlternativeAudioStreamsChange);
			mediaPlayerSprite.mediaPlayer.addEventListener(AlternativeAudioEvent.AUDIO_SWITCHING_CHANGE, onAlternateAudioSwitchingChange);
			mediaPlayerSprite.mediaPlayer.addEventListener(DynamicStreamEvent.AUTO_SWITCH_CHANGE, onAutoSwitchChange);
			mediaPlayerSprite.mediaPlayer.addEventListener(DynamicStreamEvent.NUM_DYNAMIC_STREAMS_CHANGE, onNumDynamicStreamsChange);
			mediaPlayerSprite.mediaPlayer.addEventListener(DynamicStreamEvent.SWITCHING_CHANGE, onSwitchingChange);

            addChild(sprite);

            sprite.resource = new URLResource(MEDIA_URL);
        }

        private function onNumAlternativeAudioStreamsChange(event:AlternativeAudioEvent):void
		{
			if (mediaPlayerSprite.mediaPlayer.hasAlternativeAudio)
			{
				//Code to handle what to do if the audio streams available change.
			}
		}

		private function onAlternateAudioSwitchingChange(event:AlternativeAudioEvent):void
		{
			if (event.switching)
			{
				// Code to handle alternative audio stream switch in progress
			}
			else
			{
				// Code to handle alternate audio stream switch completed
			}
		}

		private function onAutoSwitchChange(event:DynamicStreamEvent):void
		{
			// If auto switch logic has been enabled / disabled
		}

		private function onNumDynamicStreamsChange(event:DynamicStreamEvent):void
		{
			// code to handle when the number of dynamic streams has changed.
		}

		private function onSwitchingChange(event:DynamicStreamEvent):void
		{
			// Code to indicate if are switching bit-rates
		}

    }
}

Kaltura Plugin Integration

The Kaltura video player is based on OSMF and loads plugins that are compatible with OSMF plugins. To use Uplynk content with your Kaltura-based player, you will have to create your own plugin that loads the Uplynk OSMF plugin. Sample code is available on Kaltura integration instructions page. Once when you have compiled your swf you can place it in your player's plugins folder:

~/KDP3$ ll plugins/
total 1000
-rw-rw-r--  1 user  staff  346843 Oct 21 09:01 upLynkKalturaPlugin.swf
-rw-r--r--@ 1 user  staff  141327 Oct 12 10:21 kalturaMixPlugin.swf
-rw-r--r--@ 1 user  staff    8944 Oct 12 10:21 statisticsPlugin.swf

Next, edit your config.xml file and add a <Plugin> element. Typically this is added inside the player VBox element:

<layout id="full" skinPath="assets/skin.swf">
    <VBox id="player" width="100%" height="100%" styleName="black">
        <Plugin id="upLynkKaltura" width="0%" height="0%" includeInLayout="false" />
        <Plugin id="statistics" width="0%" height="0%" includeInLayout="false" />
        ...

Finally, to play the content, set the sourceType to url, the streamerType to rtmp, and the entityId to the asset's playback URL. How this is done depends on your specific project; web pages that start Kaltura via Javascript often use the AC_FL_RunContent function, so the above parameters would be specified there:

AC_FL_RunContent(
    "src", "kdp3",
    "width", "800",
    "height", "360",
    "allowFullScreen", "true",
    "id", "kdp3",
    "quality", "high",
    "bgcolor", "#eeeeee",
    "name", "kdp3",
    "allowScriptAccess","always",
    "type", "application/x-shockwave-flash",
     "flashvars","sourceType=url"+
              "&autoPlay=true"+ //autoplay mode
              "&streamerType=rtmp"+ // to enable seeking
              "&entryId=https://content.uplynk.com/37d6fd87f71141dbb1638e1cdf4ea93f.m3u8"+
              ...

For additional information, please see the Kaltura plugin integration instructions.