×
Namespaces

Variants
Actions
Revision as of 09:02, 3 October 2012 by hamishwillee (Talk | contribs)

Archived:Playing external Flash Video in FlashLite3.x

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Code ExampleArticle
Created: sangramp@cybage.com (04 May 2010)
Last edited: hamishwillee (03 Oct 2012)
Featured Article
16 May
2010

Contents

Introduction

Flash Lite 3.0 adds support for Flash Video(FLV) on mobile devices. Flash Video is a container file format used to deliver video over the Internet using Adobe Flash Player. The earlier versions of Flash Lite 2.x supported only the device videos:

  • The video formats supported by the device varied from the target device.
  • Flash Player would not decode the video natively.
  • The Flash player would pass the video to device and device used to take care of decoding and rendering the video.
  • As a result the Flash Lite application was not able to control the playback of video.
  • The video couldn’t be synchronized with the timeline, the volume, seek duration could not be controlled in addition to rotation and skewing of video.


Staring from FlashLite 3.x, FLV video is supported on mobile devices and it is supported natively by Flash Player. The Flash Player now decodes and renders the video on its own. There are certain video codes supported by FlashLite. Currently FlashLite supports On2VP6, Sorenson and H.264 video codes. Even though natively supported, FLV has following limitations on using in FlashLite 3.x:

  • RTMP connection is supported but not RTMPT and RTMPS.
  • Only one-way communication is supported in Flash Lite.
  • Video recording is not supported directly in FlashLite. Yet we can use API Bridge to capture the video by calling the native Camera application from within FlashLite application. See here.
  • Alpha channel video is not supported in Flash Lite. The On2 codec used for Flash on the desktop supports an alpha channel, but the version used for Flash Lite 3.0 does not.
  • Flash Lite 3.0 applications can not directly use the FLVPlayback component for playing the FLV files. We have to use the 'NetConnection' and 'NetStream' class instances to implement video playback.
  • The ActionScript Camera class, which is used in the desktop version of the Flash Player to connect to a user's local camera and broadcast the video, is not supported in Flash Lite.

Contents Of The Code Example

The code example will demonstrate the following aspects of using FLV:

  • Using NetConnection and NetStream class to load/play FLV video.
  • Controlling the video playback (Play, Pause, Seek)
  • Displaying the duration of video played in seconds and in percentage progress bar.
  • Certain observations on FLV playback on actual device.

Demo Example

Declare Variables

To play the video in FlashLite, we would use the NetConnection and NetStream objects. In addition to these instances, the following variables are required. Declare the following variables in a separate layer.

var connection_nc:NetConnection;
var stream_ns:NetStream;
var bPausedVideo:Boolean = false;
var nMaxWidthVideo:Number = 360;
var nMaxHeightVideo:Number = 640;
var nStageWidth:Number = 360;
var nStageHeight:Number = 640;
var nIntervalIDUpdateDuration:Number;
var global_sound:Sound = new Sound ();
var nCurrentSoundLevel:Number = 100;
var nChangeSoundLevelBy:Number = 20;
var nTotalVideoDuration:Number;

Add Video Controller Components

For playing the FLV files, we have to add a new video symbol in the library and create an instance of it on the stage. Name the instance as ‘my_video’. In addition to this, add the video controller components (Play/Pause button, Volume increase/decrease button, progress bar, and Volume indicator) on a separate layer as in the attached example.

Loading FLV File

NetConnection and NetStream ActionScript classes are used to control the playback of external Flash Video files at runtime. NetConnection class is used to establish a connection and NetStream object is used to playback streaming video files. Add the following code in the functions layer to create the connection and define the handlers.

function fnCreateConnection ()
{
connection_nc = new NetConnection ();
connection_nc.connect (null);
stream_ns = new NetStream (connection_nc);
my_video.attachVideo (stream_ns);
stream_ns.setBufferTime (2);
stream_ns.onStatus = function (iObj:Object)
{
switch (iObj.code)
{
case "NetStream.Play.Start" :
mcVideoControler._visible = true;
mcVideoControler.mcPlayPause._visible = false;
mcVideoControler.btnIncreaseVol._visible = false;
mcVideoControler.btnDecreaseVol._visible = false;
mcVideoControler.mcVolumeIndicator._visible = false;
mcVideoControler.mcProgressBar._visible = true;
mcVideoControler.mcProgressBar.mcProgressIndicator._visible = false;
mcVideoControler.mcProgressBar.mcBufferingBar._visible = true;
break;
case "NetStream.Play.Stop" :
trace ("Video Completed");
_root.mcVideoControler.mcProgressBar.mcProgressIndicator._xscale = 100;
break;
case "NetStream.Play.StreamNotFound" ://Id not Found or user not logged
stream_ns.close ();
clearInterval (nIntervalIDUpdateDuration);
break;
case "NetStream.Buffer.Empty" :
mcVideoControler._visible = true;
mcVideoControler.mcProgressBar._visible = true;
mcVideoControler.mcProgressBar.mcBufferingBar._visible = true;
break;
case "NetStream.Buffer.Full" :
mcVideoControler.mcProgressBar.mcBufferingBar._visible = false;
break;
}
};
stream_ns.onMetaData = function (infoObject:Object)
{
if (infoObject["duration"] != undefined)
{
mcVideoControler._visible = true;
mcVideoControler._x = 30;
mcVideoControler._y = 518;
mcVideoControler.mcProgressBar._visible = true;
nTotalVideoDuration = Number (infoObject["duration"]);
}
var nOriginalWidth:Number = infoObject["width"];
var nOriginalHeight:Number = infoObject["height"];
if (!isNaN (nOriginalWidth) && !isNaN (nOriginalHeight))
{
var nRatio:Number = nOriginalWidth / nOriginalHeight;
var NewWidth, NewHeight;
NewWidth = nMaxWidthVideo;
NewHeight = NewWidth / nRatio;
if (NewHeight > nMaxHeightVideo)
{
NewHeight = nMaxHeightVideo;
NewWidth = NewHeight * nRatio;
}
my_video._height = NewHeight;
my_video._width = NewWidth;
my_video._x = (nStageWidth - NewWidth) / 2;
my_video._y = (nStageHeight - NewHeight) / 2;
mcVideoControler.mcPlayPause.gotoAndStop ("pause");
mcVideoControler.mcPlayPause._visible = true;
mcVideoControler.btnIncreaseVol._visible = true;
mcVideoControler.btnDecreaseVol._visible = true;
mcVideoControler.mcVolumeIndicator._visible = true;
mcVideoControler.mcVolumeIndicator.gotoAndStop (6);
}
my_video._visible = true;
bPausedVideo = false;
};
}
function fnPlayVideo ()
{
my_video._visible = false;
mcVideoControler._x = 30;
mcVideoControler._y = 518;
stream_ns.play ("Video_1.flv");
nIntervalIDUpdateDuration = setInterval (fnCheckTime, 500, stream_ns);
}
function fnCheckTime (my_ns:NetStream)
{
var ns_seconds:Number = my_ns.time;
var minutes:Number = Math.floor (ns_seconds / 60);
var seconds = Math.floor (ns_seconds % 60);
if (seconds < 10)
{
seconds = "0" + seconds;
}
txt_Time.text = minutes + " : " + seconds;
var nPerPlayed:Number = Math.round ((ns_seconds * 100) / nTotalVideoDuration);
mcVideoControler.mcProgressBar.mcProgressIndicator._visible = true;
if (isNaN (nPerPlayed))
{
nPerPlayed = 0;
}
mcVideoControler.mcProgressBar.mcProgressIndicator._xscale = nPerPlayed;
}

The NetConnection class lets you play streaming FLV files from either an HTTP address or a local drive. As we are playing the video from local drive we pass ‘null’ to connect() method.

The next step is to create a NetStream object which takes a NetConnection object as a parameter. This NetStream object is attached to the video symbol instance on the stage. The following NetStream Class events are supported by FlashLite:

  • onStatus: Invoked when a status change or error is posted for the NetStream object. The attached example uses some of the events:
    • NetStream.Play.Start: Executed when the playback is started.
    • NetStream.Play.Stop: Executed when the playback is stopped. When the video is played completely, this event is fired.
    • NetStream.Play.StreamNotFound: Executed when the URL passed to play method is invalid/can not be found.
    • NetStream.Buffer.Empty: Executed when there is not sufficient data in the buffer to play the video playback. Within this handler ‘setBufferTime’ can be used to dynamically adjust the BufferTime so that the user experience a continuous video playback.
    • NetStream.Buffer.Full: Executed when sufficient data is buffered to start playing the video content. We are using these buffer handlers to indicate the user if data is being buffered OR played. If you run the attached example with a heavy/dynamic FLV, you will get to see the buffer bar being shown when there is not sufficient content in the buffer. As and when sufficient data is available, it starts playing the content and the buffer bar is made invisible. The following code is added to handle these events.
case "NetStream.Buffer.Empty" :
mcVideoControler._visible = true;
mcVideoControler.mcProgressBar._visible = true;
mcVideoControler.mcProgressBar.mcBufferingBar._visible = true;
break;
case "NetStream.Buffer.Full" :
mcVideoControler.mcProgressBar.mcBufferingBar._visible = false;
break;
  • onCuePoint: Invoked when an embedded cue point is reached while playing an FLV file.
  • onMetaData: Invoked when the Flash Player receives descriptive information embedded in the FLV file. Inside this handler we access the total video duration in seconds and also the original width and height of the video. This information is used to define the aspect ratio and resize the video accordingly. Only after we get the metadata information, we enable the video controller buttons so that user can interact with the video.

The following call begins playback of an external video file, we pass the URL of the video to play.

stream_ns.play ("Video_1.flv");
nIntervalIDUpdateDuration = setInterval (fnCheckTime, 500, stream_ns);
function fnCheckTime (my_ns:NetStream)
{
var ns_seconds:Number = my_ns.time;
var minutes:Number = Math.floor (ns_seconds / 60);
var seconds = Math.floor (ns_seconds % 60);
if (seconds < 10)
{
seconds = "0" + seconds;
}
txt_Time.text = minutes + " : " + seconds;
var nPerPlayed:Number = Math.round ((ns_seconds * 100) / nTotalVideoDuration);
mcVideoControler.mcProgressBar.mcProgressIndicator._visible = true;
if (isNaN (nPerPlayed))
{
nPerPlayed = 0;
}
mcVideoControler.mcProgressBar.mcProgressIndicator._xscale = nPerPlayed;
}

We then call an interval function to check the progress of video played. This function accesses the current seconds played against the total duration and is used to display the progress bar and the time duration.

Adding Playback Controllers

We can control the playback of Flash Video. We can Pause/Play, seek the video and set different volume levels. Add the following code to control the Video Playback.

function fnIncreaseSoundLevel ()
{
if (nCurrentSoundLevel <= 90)
{
nCurrentSoundLevel = nCurrentSoundLevel + nChangeSoundLevelBy;
}
else
{
nCurrentSoundLevel = 100;
}
global_sound.setVolume (nCurrentSoundLevel);
var nFrame:Number = (nCurrentSoundLevel / nChangeSoundLevelBy) + 1;
mcVideoControler.mcVolumeIndicator._visible = true;
mcVideoControler.mcVolumeIndicator.gotoAndStop (nFrame);
}
function fnDecreaseSoundLevel ()
{
if (nCurrentSoundLevel >= 10)
{
nCurrentSoundLevel = nCurrentSoundLevel - nChangeSoundLevelBy;
}
else
{
nCurrentSoundLevel = 0;
}
global_sound.setVolume (nCurrentSoundLevel);
var nFrame:Number = (nCurrentSoundLevel / nChangeSoundLevelBy) + 1;
mcVideoControler.mcVolumeIndicator._visible = true;
mcVideoControler.mcVolumeIndicator.gotoAndStop (nFrame);
}
function fnPlayPause ()
{
stream_ns.pause ();
bPausedVideo = !bPausedVideo;
if (bPausedVideo)
{
mcVideoControler.mcPlayPause.gotoAndStop ("play");
}
else
{
mcVideoControler.mcPlayPause.gotoAndStop ("pause");
}
}

The above procedures are quite straightforward. There are mainly two ways we can control the volume level, one by using the Global Sound Object and another by using a local sound object and attaching stream object. The second way of using local sound object can be attributed by following lines of code.

this.createEmptyMovieClip("videoSound_mc",2)
videoSound_mc.attachAudio(ns);
var video_snd = new Sound(videoSound_mc);
video_snd.setVolume(75);

Important Observations

Following are certain observations of executing the FLV on actual mobile devices:

  • FlashLite 3.x supports the seeking functionality only for relatively small duration videos. For all other videos, call for seek is ignored. There is not a definite duration defined for which seek is guaranteed to work.
  • When the video is streaming, the other action-scripting takes a lot of time for execution. This is more obvious on devices like N95.
  • Surprisingly the video streaming from web executes without error, but the local (and heavy) FLV files give the 'Problem with content: 13' error. Again observed on N95.
  • The streaming video executes perfectly in normal view but in case we rotate the video to either 90 or 270 degrees the performance degrades.
  • Even when you stop playing the video content by closing the connection and stream, it takes some time to clear the connection and video continues to execute.

Download

You can download the source code Loading FLV in FlashLite. It is tested on Nokia 5800 XpressMusic. Also please use any compatible FLV file and rename it to 'Video_1.flv' to run the Demo example.

94 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×