Some of our components and applications have the ability to automatically detect all the media files that are uploaded to your application streams directory. This is done through a server-side utility class we built a while back called Video.asc.

Before we get started here are the requirements for this tutorial:

Influxis Services (any size hosting plan)
FMIS 3
Flex Builder 3 or SDK

Source Files [optional]

Let’s start by creating a new main.asc file. At the present time FMIS server-side code is only compatible with ActionScript 1.0. You will need a text editor or ActionScript editor that lets you code in ActionScript 1.0 to create your main.asc file. Once you have your editor open, key this line of code into your file:

load("InfluxisVideoPlayer.asc" ); 

This will load the Video.asc file including any other resources it will need. Login to your Influxis account and create a folder called “videolist” inside that folder. Then create a subfolder called “streams”. Save your main.asc file and load it to the videolist folder you just created. That is pretty much all we need for the server- side code. Simple!

Now we can start our application’s client-side code. We will use Flex 3.0 to create our client-side. Open up your Flex Builder, create a new Flex project and call it VideoList. Create your src folder, VideoList.mxml file and click “finish” when you’re done.

In the VideoList.mxml, locate within the Application tag nest a List control and give it an id of “videoList”. Use its click event to call a function named “playFromList” which we will create in a bit. Using the List’s labelFunction property set a value of “formatListLabel” which, again, we will create soon. Place the List control anywhere you want on the page. I will place mine in the middle of the page horizontally and 260 pixels from the top to make room for a video object. A width of 320 and height of 150:

         

<mx:List click="playFromList()"
labelFunction="formatListLabel"
id="videoList"horizontalCenter="0"
top="260" width="320" height="150"/>         

Now create a UIComponent mxml tag with an id of “vidHolder”, this will hold our video object on the stage. I placed the vidHolder just above the list 10px from the top and in the absolute center matching my videoList:

<mx:uicomponent id="vidHolder"
width="320" height="240"
horizontalCenter="0" top="10"/>

I gave it a width of 320 and a height of 240 as my videos will be formatted to fit this ratio, but you can size yours to whatever matches your video files best. You can even create a dynamic code to handle resizing. In this post, we’ll keep it simple.Now let’s create our AS 3 code. Within the Application tag use the “creationComplete” event to call an init() function which we will build:

<mx:application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()">         

Open a script tag (<:Script>) and import these classes:


<:Script>
<![CDATA[
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.Responder;
import flash.events.NetStatusEvent;
import flash.media.Video;         

Create the init function within the script tag. With the init body let’s create our netConnection. Declare a var called nc and another one for the video object “videoDisp”. We also want to create a simple video object to display the video that the user clicks on. Here is the code for that init function:

         

public var nc:NetConnection;
public var ns:NetStream;
private var videoDisp:Video;
private function init():void{
      //connect to our server.
      nc = new NetConnection();
      nc.client = {};
      nc.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
      nc.connect( "rtmp://influxisaccount.rtmphost.com/videolist" );
      this.videoDisp = new Video();
      //add our video object
      this.vidHolder.addChild( videoDisp );
};

If you notice in the code above our net connection uses an event listener function called “onNetStatus”. We will create this next, also if you notice we set the Video object as a child to the “vidHolder” we created earlier.

Now let’s create our connection handler onNetStatus:

         

//handle the net status
private function onNetStatus( p_e:NetStatusEvent ):void
{
    var code:String = p_e.info.code;
    trace("net status code: "+code);
    //only if we are connected successfully do we continue
    switch( code ){
        case "NetConnection.Connect.Success":
        createStream();
        getVideoFiles();
        break;
    }
};

At this point, when our status event comes in, I wrote a simple switch statement that if we successfully connected we can continue with the setup process. You can add more conditions for unsuccessful connections if you want. For the sample I will just handle the success. Once we successfully connected I call 2 functions createStream, which will build our NetStream to stream the video, and getVideoFiles which will call our server-side class to retrieve the video file list. Here is what these methods should look like:

         

private function createStream():void{
   ns = new NetStream(nc);
   ns.client = {};
   this.videoDisp.attachNetStream( ns );
};
public function getVideoFiles():void
{
   nc.call( "Video.getList", new Responder(onVideos) );
};

The createStream makes a NetStream object and saves it to a variable called ns. Be sure to declare this variable at the top. The method attaches the ns variable to the videoDisp using the attachNetStream method. Now our video is ready to play a stream.

The “getVideoFiles” function, as you can see, calls the servers-side code using the netConection Object’s “call” method. It targets the “getList” function on our server-side video class by first specifying the class name then the function separated by a dot (“Video.getList”). For more info on this follow this link: http://livedocs.adobe.com/fms/2/docs/00000571.html. The server-side function returns an array containing objects, so we must handle that return. As you can see above, I used a Responder class to handle the result data and pass it over to a function called “onVideos” which will receive an array as its argument. Here is the function:

         

private function onVideos( p_a:Array ):void
{
   trace("onVideoList "+p_a );
   this.videoList.dataProvider = p_a;
};         

Once we received our video list from our server-side Video Class we can display the video objects on our list by applying the array to its dataProvider property. Lets back up a bit before we continue. As you remember earlier we had used a “labelFunction” on the List control called “formatListLabel”, this is where it will come into play. Each item in the array that we receive is an object, each of those objects represents data of a stream that is in that streams folder, for example let’s say I have an FLV file in the folder called myvideo.flv, in the array there would be an object that represents that video file. The object contains these properties:


directory:string
size:number
time:number
type:string
creationTime:object
path:string
name:string
lastModified:object         

Size is the size of the video in bytes and type is the length of the video in seconds. In this article we care about just 2 items “name” and “type”, so for the rest of the items we will revisit them in a later article. Using our label function we will create a readable label for the list. It’s a simple function that should look something like this:

         

//format our label for the list
private function formatListLabel( p_o:Object ):String{
     return p_o.name;
};         

Using our myvideo.flv sample this will display that item as “myvideo” in the list. You can add more to it if you’d like at your preference. Some of our beta testers added the type (p_o.name+”.”+p_o.type) since you can play more than just FLV files.

Now last but not least the click function we specified earlier “playFromList”. This function will simply play the selected video file when the list is clicked:

         

public function playFromList():void
{
     var item:Object = this.videoList.selectedItem;
     if( item == null ) return;
     playVideoItem( item );
};         

// play video item - handle flv,mp3 and h.264 files
public function playVideoItem( p_item:Object ):void
{
     var fileName:String;
     var type:String = p_item.type;
     //if type is flv, mp3 and anything else beyond
     //that will be considered an h.264 file
     switch( type ){
          case "flv" :
               fileName = p_item.name;
               break;
          case "mp3" :
               fileName = "mp3:"+p_item.name;
               break;
          default :
               fileName = "mp4:"+p_item.name+"."+p_item.type;
               break;
     }
     trace("playListItem "+fileName);
     //play video in netstream.
     this.ns.play( fileName );
};         

The “playFromList” method is called from the click event of the List control. It gets the item that is selected on the List and sends the object data to another method called “playVideoItem” which sets the file name based on the type of video it is trying to play. Currently in FMIS 3 you can stream FLV files MP3 files and H.246 formatted files like mp4, unfortunately each of those types uses a different format so we have to detect it and format respectively. Using this separate function “playVideoItem” was just a strategic move so I can use other controls like a DataGrid without duplicating too much code, so this is definitely optional. Once our file name is created we play the video using the NetStream play method. For more on NetStreams follow this link: http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/
flash/net/NetStream.html

Your mxml file at this point should look like this:

         

<mx:application "xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()">
<mx:script>
<![CDATA[
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.Responder;
import flash.events.NetStatusEvent;
import flash.media.Video;
public var nc:NetConnection;
public var ns:NetStream;
private var videoDisp:Video;
private function init():void
{
     //connect to our server.
     nc = new NetConnection();
     nc.client = {};
     nc.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
     nc.connect( "rtmp://account.rtmphost.com/videolist" );
     this.videoDisp = new Video();
     //add our video object
     this.vidHolder.addChild( videoDisp );
};         

//handle the net status
private function onNetStatus( p_e:NetStatusEvent ):void
{
     var code:String = p_e.info.code;
     trace("net status code: "+code);
     //only if we are connected successfully do we continue
     switch( code ){
          case "NetConnection.Connect.Success":
               createStream();
               getVideoFiles();
               break;
     }
};         

private function createStream():void
{
     ns = new NetStream(nc);
     ns.client = {};
     this.videoDisp.attachNetStream( ns );
};         

public function getVideoFiles():void
{
     nc.call( "Video.getList", new Responder(onVideos) );
};         

private function onVideos( p_a:Array ):void
{
     trace("onVideoList "+p_a );
     this.videoList.dataProvider = p_a;
};         

//format our label for the list
private function formatListLabel( p_o:Object ):String
{
     return p_o.name;
};         

public function playFromList():void
{
     var item:Object = this.videoList.selectedItem;
     if( item == null ) return;
     playVideoItem( item );
};         

// play video item - handle flv,mp3 and h.264 files
public function playVideoItem( p_item:Object ):void
{
     var fileName:String;
     var type:String = p_item.type;
     //if type is flv, mp3 and anything else beyond
     //that will be considered an h.264 file
     switch( type ){
          case "flv" :
               fileName = p_item.name;
               break;
          case "mp3" :
               fileName = "mp3:"+p_item.name;
               break;
          default :
               fileName = "mp4:"+p_item.name+"."+p_item.type;
               break;
}
     trace("playListItem "+fileName);
     //play video in netstream.
     this.ns.play( fileName );
};
]]>
<mx:List click="playFromList()" labelFunction="formatListLabel"
 id="videoList" horizontalCenter="0" top="260" width="320"
height="150"/>
<mx:uicomponent id="vidHolder" width="320" height="240"
horizontalCenter="0" top="10"/>

Now upload some Video files to your videolist / streams / folder on your Influxis account and give it a test.

Jerry Chabolla

2 Responses to “Influxis Video Utility Class 1: Building a Media List for Audio/Video Streaming in Flex”

  1. James "YogiFish" Herring

    Thank you for this information. I am planning to use your service to build a Flex/AIR application using Live streaming recording and playback of flash files.

    I Hope that you do more Flex based tutorials in the future. I would also like to know if you offer consulting or technical development services? The project I am developing is based on some of the current social video community sites (BlogTv.com, Stickam.com, BlogStar.com), but from a desktop platform.

    Take Care,

    James “YogiFish” Herring

    Reply

Leave a Reply

Current day month ye@r *