Flash Video Issue: loadbar (size) vs playbar (time) usability

This deals with some issues I’m having with the seekbar of a player. The seekbar is the area that displays the video time as a bar that shows your current position/percentage of the video, it can also display the loaded portion of the video among other things as well. Including the video players I’ve made, most player code seems to use bytesLoded / bytesTotal to calculate the amount loaded and display in the loadbar (or whatever you call it), this load bar relates to the filesize as it reads the bytes loaded out of the total. In this same scrub bar area, I like to display the current video time in the playbar as the currentTime / totalTime, notice that this relates to the time and not the file size.
seekbars
Since video is usually a variable bit rate, the loadbar (size) and the playbar (time) are not representing the same data of the video. Let’s consider an extreme example case video that consists of a first half containing live action with lots of colors and motion while the second half is a still image black and white slideshow. Understandably the first half of the video will be larger in file size than the second half, even though they each represent the same duration or half of a video… So the first half of the loadbar (size) would not correctly represent the first half of the playbar (time). So the user who watching the video load to the half point, and scrubbing to halfway through the video by clicking the load bar will see errors… The player will not be able to play the halfway (time) yet because that time is not yet loaded, even though the file is halfway loaded (size). So if we allow scrubbing through the video by clicking on the loadbar, there is a good chance that the user experience suffers because the loadbar (size) and playbar (time) are not interchangeable
Calculating display bar actionscript code:
[cc lang=”actionscript”]
//bar is display bar mc
//bar.bg.width is used as a constant to scale the percentage to the full bar width
bar.sizebar.width = (ns.bytesLoaded / ns.bytesTotal) * bar.bg.width;
bar.timebar.width = (ns.time / duration) * bar.bg.width;
[/cc]
Scrub on click actionscript code:
[cc lang=”actionscript”]
//calculate from percentage of bar width to time for seeking to
jumpSeekTo = (bar.mouseX / bar.bg.width) * duration;
ns.seek(jumpSeekTo);
[/cc]

A possible simple solution I’ve thought of is to just display a loading graphic if they click a time which has not yet loaded, but that seems counter intuitive and backwards, since the load bar would display that time as having being loaded.

I have not seen anything in documentation or anywhere online that suggests any other way to display the amount loaded which would represent the amount of TIME loaded rather than SIZE. Is there a way to know what time has loaded in the video and display that in the loadbar rather than display the percent of kb loaded?

Can anyone see something I am missing?

P.S. I already tried a couple forums to no avail: Actionscript.org forum post and gotoandlearn forum post.

My StomperNet Portal Design

my-stompernet-com online videomy-stompernet-com pdf downloadPortal website design for StomperNet. Created to give digital access of subscription content: including video, pdf versions of print material (journal). I was responsible for the design of the front end of the site with valid html and css. I also designed the site logo and the graphics on the site. Was able to include some small customized flash elements. Visit public my.stompernet.com site and purchase instant access to StomperNet content inside the my.stompernet.com portal.
my-stompernet-com publicmy-stompernet-com publicmy-stompernet-com public

How to use fullscreen in AS3 | Stage Display State Tutorial

fullscreen_tut png
One of the best features of the flash player if you’re doing video is the fullscreen functionality. It has been a question I’ve heard repeatedly. There are limits to what you can do in fullscreen. Such as minimal keyboard support while in fullscreen. But it is perfect for a video player! Who doesn’t want to see a video expanded to full screen mode?

There are a couple things to consider when coding fullscreen into your flash. Remember the hard coded “Press Esc to exit full screen mode.” that Adobe has placed into the flash player. This is untouchable by developers, and the function returns to normal stage display state. So we call the function to go fullscreen, but the exit fullscreen has already been written for us. This can pose a problem though, when we need the player to do something when we exit fullscreen, that is when we want it to do something more than the generic black box function adobe includes.

Steps

  1. specify stage properties
  2. full screen button and listeners
  3. stage fullscreenEvent listener
  4. (functions for each)
  5. allowfullscreen = true

Example

[kml_flashembed fversion=”9.0.28″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/03/fullscreen_tut.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”550″ height=”400″ allowfullscreen=”true”]Get Adobe Flash player

[/kml_flashembed]

1. Stage properties exist that allow us to specify what type of fullscreen we want.  We can have the swf scale to fit the fullscreen area (StageScaleMode.SHOW_ALL), not scale at all (StageScaleMode.NO_SCALE), skew to fit fullscreen (StageScaleMode.EXACT_FIT), and scale to fill fullscreen area (Stage.ScaleMode.NO_BORDER).  We may also edit the alignment of the stage in the fullscreen area; in this example I’m using TOP, but refer to documentation for more options

2. Adobe has placed restrictions on when a swf can enter fullscreen, and has deemed that it must result from a user interaction, a mouse click or keystroke. So create your buttons (or keyListeners). I prefer to have one button to enter fullscreen and another to exit, and have them both call the same function to toggle fullscreen. It gives a clearer communication to the user. I then control the visibility of these buttons depending on the current display state of the stage.

3. Another listener to watch the stage dispaly state. stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreenChange); This will fire every time the stage display state changes. We need this because as I mentioned earlier, when entering fullscreen we use our own function, but the ‘hit esc to exit fullscreen’ functionality is built into the flash player, we can’t update our stage layout or button visibility without watching to catch when the display state is changed. Using this method we can update our stage layout any and every time.

4. Of course flesh out the fullscreenToggle function to include anything else you need.

5. Lastly, for a SWF file embedded in an HTML page, the HTML code to embed Flash Player must include a ‘param’ tag and ’embed’ attribute with the name ‘allowFullScreen’ and value ‘true’, like this:

<object>
    ...
    <param name="allowFullScreen" value="true" />
    <embed ... allowfullscreen="true" />
</object>

The allowFullScreen tag enables full-screen mode in the player. If you do everything else right and don’t include this in your embed codes, fullscreen will not work. The default value is false if this attribute is omitted. Note the viewer must at least have Flash Player version 9,0,28,0 installed to use full-screen mode. Also note that  the simple (ctrl + enter) testing your movie in flash will not allow fullscreen either, you must use the debug tester (ctrl + shift + enter) … or go open the published swf in flash player.

Actionscript

[cc lang=”actionscript”]
stage.scaleMode = StageScaleMode.SHOW_ALL;
stage.align = StageAlign.TOP;

var stageDisplayAdjustCounter:uint = 0;

fsb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
ssb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreenChange);

fsb.buttonMode = true;
ssb.buttonMode = true;

//fullscreen buttons need this to adjust the stage display state.
//pressing escape to exit fullscreen bypasses this function
function fullscreenToggle(e:MouseEvent = null):void {
status.appendText(stageDisplayAdjustCounter+”. fullscreenToggle from “+stage.displayState+”\n”);
//normal mode, enter fullscreen mode
if (stage.displayState == StageDisplayState.NORMAL){
//set stage display state
stage.displayState = StageDisplayState.FULL_SCREEN;
}
//fullscreen mode, enter normal mode
else if (stage.displayState == StageDisplayState.FULL_SCREEN){
//set stage display state
stage.displayState = StageDisplayState.NORMAL;
}
//here we subtract 1 from the counter because it has already incremented (in onFullscreenChange) when we set the display state above

status.appendText((stageDisplayAdjustCounter-1)+”. fullscreenToggle to “+stage.displayState+”\n”);
status.scrollV = status.maxScrollV;

}

//this function is called every and anytime the stage display state is adjusted
//either by pressing our buttons or
function onFullscreenChange(e:FullScreenEvent = null):void {
status.appendText(stageDisplayAdjustCounter+”. onFullscreenChange\n”);
status.scrollV = status.maxScrollV;
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
fsb.visible = false;
ssb.visible = true;
}
else {
fsb.visible = true;
ssb.visible = false;
}

stageDisplayAdjustCounter++;
}

onFullscreenChange();

[/cc]

Source

Download fullscreen_tut.fla file

Fullscreen in AS3 Tutorial | Plus Firefox Flash bug when enter fullscreen keyboard events fired

To view the full fullscreen tutorial go here: How to use fullscreen in AS3 | Stage Display State Tutorial

fullscreen_keyboard_bug_thumbnail
Sucks when you seem to have a bug in your code somewhere so you dissect your code over and over and are convinced that according to your code, everything should be fine, so you come back later thinking fresher eyes will see it, and still can’t find the cause, and then resort to debugging with various trace statements…

I’ve been developing a custom flash player in as3. Fullscreen and all those bells and whistles… I could test locally and eveything was beautiful… but then upload and test in the browser and when I would go into fullscreen mode, the video would pause. Pretty annoying bug! So I’d go through my code and examine anywhere a call to pause the video (there are only two): pressing the play/pause button and pressing the spacebar (keyboard shortcut). I couldn’t find any correalation. I was thinking adobe must be doing some crazy security things when going into fullscreen… but no, no other video player I’ve seen does this!
After commenting out my keyboard events, the bug is fixed! But I still can’t use the spacebar to pause/play. I love this functionality for usability. Isn’t that pretty standard for video? space to pause, it’s like second nature to me.

Does entering fullscreen really trigger a keyboard event equivalent to pressing my spacebar!? Sure enough. how much sense does that make, but it gets better! I had a friend test this swf and it worked fine for him. No pause on fullscreen! Wha!? Using good ole IE7… So yes, it’s a browser specific actionscript bug, firefox even! That was one of the things I liked about flash initially, not too much to mess with as far as cross browser issues once you get the swf embedded in the html, or so I thought.

So after playing with booleans to try to control when the keyboard events will be working.

Has anyone experienced this or another issue that just left you baffled, even after you figured out the bug?!

Well, I’ve done the right thing, I’ve posted about it to hopefully help anyone else having this issue. I created a test case file to rule out anything else in my code and make sure I’m not crazy.
[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/03/fullscreen_keyboardevent_bug.swf” targetclass=”flashmovie” bgcolor=”#336666″ publishmethod=”dynamic” width=”550″ height=”400″ allowfullscreen=”true”]

Get Adobe Flash player

[/kml_flashembed]

[cc lang=”actionscript”]
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

fsb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
ssb.addEventListener(MouseEvent.CLICK, fullscreenToggle);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreenChange);
fsb.buttonMode = true;
ssb.buttonMode = true;
onFullscreenChange();

function fullscreenToggle(e:MouseEvent = null):void {
//normal mode, enter fullscreen mode
if (stage.displayState == StageDisplayState.NORMAL){
//set stage display state
stage.displayState = StageDisplayState.FULL_SCREEN;
}
//fullscreen mode, enter normal mode
else if (stage.displayState == StageDisplayState.FULL_SCREEN){
//set stage display state
stage.displayState = StageDisplayState.NORMAL;
}
onFullscreenChange();
}
function onFullscreenChange(e:FullScreenEvent = null):void {
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
tracer(“full screen”);
fsb.visible = false;
ssb.visible = true;
}
else {
tracer(“small screen”);
fsb.visible = true;
ssb.visible = false;
}
tracer(“toggle to “+stage.displayState);
}
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener);

function keyDownListener(e:KeyboardEvent) {
tracer(“keyboard: keyCode: “+ e.keyCode.toString());
}
var tracerwindow:TextField;
function tracer( …args){
if (tracerwindow == null){
tracerwindow = new TextField();
tracerwindow.width = stage.stageWidth/2;
tracerwindow.height = stage.stageHeight;
tracerwindow.multiline = true;
addChild(tracerwindow);
}

for (var i:uint = 0; i < args.length; i++) { tracerwindow.appendText(args[i].toString() + " "); } tracerwindow.appendText("\n"); trace(args); } [/cc]other places that I've found this mentioned that helped me understand what was going on: http://dreamweaverforum.info/actionscript-3/123202-keyboard-event-full-screen.html http://bugs.adobe.com/jira/browse/FP-814

How to as3 resize a movieClip and constrain proportions | Actionscript Tutorial

constrain proportions jpgI’ve had that exact task numerous time while scripting actionscript. I have a source image loaded externally or a mc within the program and I need to fit it into a certain area (width x height) but keep the aspect ratio the same or as photoshop calls it “constrain proportions”. I’ve done this with fancy and not so fancy formulas and equations, but finally I had it and created a simple function that would do it every time. Figured it was worth sharing cause if I’ve googled it before then others most likely will too!

This is more than just setting the width and height of an object, because that way the image is easily skewed and the natural proportions are messed up. If you want to just use scale you need to know the dimensions of the image being resized, and that’s just not scalable (no pun intended).

What we have to do is to do both. Assign the width and height to skew it, and then scale it to correct the proportion. So if we want to resize an image when we don’t know it’s current size to fit into a 300 pixel square we set the width and height of that image to 300 and then a bit of logic that can be summed up in one line:
mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
That says if the x scale is larger than the y scale set the x to the y scale amount, and vice versa. It's basically setting both scales to the smaller of the two. This works because we don't know the original size of the image, but actionscript does. scaleX and scaleY are ratios of the current width and height to the originals. A little complicated I know, but that's why I've made the function below. I know how to use it and now I don't have to think about skewing and then scaling back to keep my aspect ratio or proportion. You should see how to use it just by looking at it:
resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true)
Pass in the movieClip you want to resize, and the size you want it to fit into. So with the same example above, just do
resizeMe(image, 300);

Example

Here's an interactive example to show what I mean. It loads an external image and you click and drag the mouse around to resize it. To toggle whether you want to constrain proportions use the space bar. Type a url to any image you want to test it with and press load, or hit 'enter'.
[kml_flashembed fversion="9.0.0" movie="https://circlecube.com/circlecube/wp-content/uploads/sites/10/2009/01/constrainproportions.swf" publishmethod="dynamic" width="550" height="550"]

Get Adobe Flash player

[/kml_flashembed]

Here's a screenshot of me playing with a photo in here NOT constraining proportions.
constrain proportions jpg

Source (AS3)

The resizing function
[cc lang="actionscript"]
//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{
maxH = maxH == 0 ? maxW : maxH;
mc.width = maxW;
mc.height = maxH;
if (constrainProportions) {
mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY; } } [/cc]The full source [cc lang="actionscript"] var defaultUrl:String = "https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/11/circlecubelogo4.png"; var image:MovieClip = new MovieClip(); loadImage(); function loadImage(url:String=""):void { if (url == "" || url == defaultToLoadString) url = defaultUrl; //clear image image.visible = false; image = new MovieClip(); //add image var ldr:Loader = new Loader(); var urlReq:URLRequest = new URLRequest(url); trace("loading image: " + url); ldr.load(urlReq); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, imageCompleteHandler); image.addChild(ldr); addChild(image); }function imageCompleteHandler(e:Event):void { resizeMe(image, stage.stageWidth) }//The resizing function // parameters // required: mc = the movieClip to resize // required: maxW = either the size of the box to resize to, or just the maximum desired width // optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once) // optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true. function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{ maxH = maxH == 0 ? maxW : maxH; mc.width = maxW; mc.height = maxH; if (constrainProportions) { mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY; } }var constrainOn:Boolean = true; var isPressed:Boolean = false;stage.addEventListener(MouseEvent.MOUSE_MOVE, moved); stage.addEventListener(MouseEvent.MOUSE_DOWN, pressed); stage.addEventListener(MouseEvent.MOUSE_UP, released); stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener);function keyDownListener(e:KeyboardEvent) { if (e.keyCode == 32){//spacebar toggled(e); } if(e.keyCode == 13){//enter loadImagePress(e); } }function moved(e:Event):void{ if (isPressed) resizeMe(image, mouseX, mouseY, constrainOn); } function pressed(e:MouseEvent):void{ isPressed = true; moved(e); } function released(e:MouseEvent):void{ isPressed = false; } function toggled(e:Event):void{ constrainOn = !constrainOn; moved(e); } var defaultToLoadString:String = "type url of image to load"; toLoad.text = defaultToLoadString; toLoad.addEventListener(FocusEvent.FOCUS_IN, toLoadFocus); toLoad.addEventListener(FocusEvent.FOCUS_OUT, toLoadBlur); function toLoadFocus(e:FocusEvent):void{ if (toLoad.text == defaultToLoadString) toLoad.text = ""; } function toLoadBlur(e:FocusEvent):void{ if (toLoad.text == "") toLoad.text = defaultToLoadString; } loadBtn.addEventListener(MouseEvent.CLICK, loadImagePress); function loadImagePress(e:Event):void{ loadImage(toLoad.text); } [/cc]

Download

constrainProportions.fla

And as usual, let me know if you've got any comments questions or suggestions! Thanks,

asfunction (TextEvent.LINK) Tutorial for AS3 | Flash HTML Link to call actionscript function | Tutorial

Overview

Earlier I wrote a tutorial article about asfunction in as2. Now that I’ m into as3, surprise surprise asfunction has been depreciated and now to replace it is the LINK TextEvent. Dispatched when a user clicks a hyperlink in an HTML-enabled text field, where the URL begins with “event:”. The remainder of the URL after “event:” will be placed in the text property of the LINK event.
This differs from the asfunction method in that we must add an event listener (addEventListener) to the textField object, the event listener specifies which function will be called in the event of a link click and there is no way to send arguments along with the event (AFAIK). But it’s easy enought to use one link event function for all your link events and put in a simple switch statement to coordinate the desired results…

Steps

  1. Use event in the href attribute. (href=”event:eventText”)
  2. Listen to the textField (theTextField.addEventListener(TextEvent.LINK, linkHandler);)
  3. Handle the link event (function linkHandler(linkEvent:TextEvent):void {…)

Example

[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/12/textlinkevent_as3.swf” publishmethod=”dynamic” width=”550″ height=”400″]

Get Adobe Flash player

[/kml_flashembed]

Actionscript

[cc lang=”actionscript”]
var myHTMLText:String = “Sample text in an html enabled text box.\n”+
“Here’s a normal link to circlecube putting the link into the href attribute like normal!\n”+
Click this circlecube, to see the text event link in action! \n”+
“And some more links that don’t go anywhere, but they do call functions in actionscript. “+
“Click this to move UP, click me move back “+
DOWN.\n”+
“Also, one last example click for a trace test“;

//create and initialize css
var myCSS:StyleSheet = new StyleSheet();
myCSS.setStyle(“a:link”, {color:’#0000CC’,textDecoration:’none’});
myCSS.setStyle(“a:hover”, {color:’#0000FF’,textDecoration:’underline’});
myHTML.styleSheet = myCSS;
myHTML.htmlText = myHTMLText;

myHTML.addEventListener(TextEvent.LINK, linkHandler);

function linkHandler(linkEvent:TextEvent):void {
switch (linkEvent.text) {
case “clickLink”:
clickLink();
break;
case “moveUp”:
moveUp();
break;
case “moveDown”:
moveDown();
break;
default:
giveFeedback(linkEvent.text);
}
}
//function to be called from html text
function clickLink():void {
giveFeedback(“Hyperlink clicked!”);
var myURL:String = “https://circlecube.com/circlecube”;
var myRequest:URLRequest = new URLRequest(myURL);
try {
navigateToURL(myRequest);
}
catch (e:Error) {
// handle error here
giveFeedback(e);
}
}

//another function to be called from html text, recieves one argument
function moveUp():void {
feedback.y -= 10;
giveFeedback(“Up”);
}

//a simple trick to allow passing of multiple arguments
function moveDown():void {
feedback.y += 10;
giveFeedback(“Down”);
}

function giveFeedback(str):void {
trace(str);
feedback.appendText(str +”\n”);
feedback.scrollV = feedback.maxScrollV;
}
[/cc]

Source

Download the fla here: textlinkevent_as3.fla

StomperNet Strikes Again! with FormulaFIVE

StomperNet has been a ‘buzz’.

After Andy’s ‘Mea Culpa‘ why wouldn’t it be…

But this is so much better and bigger, learning many lessons from the last launch – StomperNet strikes again!

Teamed up with Paul Lemberg a new product called FormulaFIVE (F5 for short).

Just launched a video to excite the industry!
So check out stomperf5.com now!

formula five landing page

Circlecube Freshens Up … for you!

Thanks for your patience as I’ve been tinkering with the theme, layout and css of circlecube.com.

I started with a free theme from Justin Tadlock, Options Theme, available at theme hybrid. I’ve changed that theme quite a bit, from restyling it to fixing bugs I found and updated many other things on the site as well. So the reason I’m going on about it is I think I’m finished… and I’m asking you to let me know if you see anything that looks odd or fishy, or even just want to make a suggestion or comment on how much you like/hate the redesign. Comment on this post or contact me!

And as always, if there’s something you would like me to write about or have questions you can also contact me. I’ve even set up a poll in the sidebar showing post ideas I have which you can vote on and encourage me to write the one(s) you want most first! So let me know what you want, it encourages me to write more as well. And be sure to subscribe to the circlecube rss feed so you won’t miss anything that’s coming up!

Sally Kolar Photography

Sally, a great photographer in the Augusta, GA area wanted help putting up a website that was easy to maintain and looked professional. I helped her out and set her up with a wordpress install, some essential plugins and a few themes! She is ecstatic!

Check out the site here: http://sallykolar.com/ and book her if you’re in the area and want great photography!