Remove of Communication between Flash and other wares
Load vars from JavaScript
Inside function readFlashVars(), it calls function xml_load() to load setting variables and assign them to the global variables, and then it use the parameters object from JavaScript to over ride the global variables, saying that the latter has higher priority.
But in my project, I am creating desktop application, and no JavaScript involved. So all the code follow call to xml_load() is redundant and useless. We can delete them. And somehow, that means the function readFlashVars() is also redundant, as its intention doesn't stand any long. Actually we can call xml_load() directly and setxml_playlist to true.
And now readFlashVars() is changed to:
public function readFlashVars():void
{
flashvars = this.loaderInfo.parameters;
xml_load("playlist.xml");
xml_playlist = true;
return;
}
Reading Data from flash.net.SharedObject
This program save the user's setting of volume on user's computer, and each time it try to fetch this value back when it run, and if it is a valid value, it will be set to initial volume.
Here is a sketch for getting that task done:
...
internal var sharedObject:flash.net.SharedObject;
...
sharedObject = flash.net.SharedObject.getLocal("CirclecubeVideoPlayer4");
...
public function getVal(arg1:*):*
{
return sharedObject.data[arg1];
}
...
public function setVal(arg1:*, arg2:*):*
{
sharedObject.data[arg1] = arg2;
sharedObject.flush();
return;
}
...
setVal("volume", initialVol);
...
initialVol = getVal("volume");
setVol(initialVol ? initialVol : defaultInitialVol);
...
And now we remove all this code.
as file(remove sharedobject javascript communication version)
Continue with removing the useless features
FullScreen
Since I don't need this feature in my design, I am going to remove it. Its sketch as following:
vcr.fullscreenB.addEventListener(flash.events.MouseEvent.ROLL_OVER, butOver);
vcr.fullscreenB.addEventListener(flash.events.MouseEvent.ROLL_OUT, butOut);
vcr.smallscreenB.addEventListener(flash.events.MouseEvent.ROLL_OVER, butOver);
vcr.smallscreenB.addEventListener(flash.events.MouseEvent.ROLL_OUT, butOut);
vcr.fullscreenB.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, fullscreenToggle);
vcr.smallscreenB.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, fullscreenToggle);
...
videofg.doubleClickEnabled = true;
videofg.addEventListener(flash.events.MouseEvent.DOUBLE_CLICK, fullscreenToggle);
videofg.buttonMode = true;
...
playOverlay.doubleClickEnabled = true;
playOverlay.addEventListener(flash.events.MouseEvent.DOUBLE_CLICK, fullscreenToggle);
...
public function fullscreenToggle(arg1:flash.events.MouseEvent=null):void
{
if (stage.displayState != flash.display.StageDisplayState.NORMAL)
{
if (stage.displayState == flash.display.StageDisplayState.FULL_SCREEN)
{
stage.displayState = flash.display.StageDisplayState.NORMAL;
if (vcrArray.indexOf(vcr.fullscreenB) != -1)
{
vcr.fullscreenB.visible = true;
vcr.smallscreenB.visible = false;
}
}
}
else
stage.displayState = flash.display.StageDisplayState.FULL_SCREEN;
if (vcrArray.indexOf(vcr.fullscreenB) != -1)
{
vcr.fullscreenB.visible = false;
vcr.smallscreenB.visible = true;
}
}
return;
}
public function checkFSbuttons():*
{
if (vcrArray.indexOf(vcr.fullscreenB) != -1)
{
if (stage.displayState != flash.display.StageDisplayState.NORMAL)
{
if (stage.displayState == flash.display.StageDisplayState.FULL_SCREEN)
{
vcr.fullscreenB.visible = false;
vcr.smallscreenB.visible = true;
}
}
else
{
vcr.fullscreenB.visible = true;
vcr.smallscreenB.visible = false;
}
}
return;
}
The logic is that except the switch button on the vcr, if user double click the video or over-lay-on-video button, the mode will be toggled as well.
And now comment them out. And then remove all the code of creating and initialize fullscreenB and smallscreenB, similar to shareB.
And there is also a listener of stage to listen to the event of display-state change:
stage.addEventListener(flash.events.FullScreenEvent.FULL_SCREEN, onFullscreenChange);
public function onFullscreenChange(arg1:flash.events.FullScreenEvent):void
{
if (arg1.fullScreen)
{
trace("fullScreen");
}
else
{
trace("not fullScreen");
}
trace("toggle to " + stage.displayState);
myCSS();
hideAllWindows();
closer.visible = false;
playerLayout();
return;
}
Remove them, and test the movie. And if it works ok, then we can delete the icons in vcr movieclip
as file(remove fullscreen, videoClient version)
ToolTip
And the next will be tooltip, a mc actually, that shows up when some mouse-over event occurs, this task is handled by showTooltip() and hideTooltip() functions.
Since my program is operated by touching, then mouse-over makes no sense. And we comment out all the references to the two functions and their definitions.
Some event handler function such as overIcon(), only have one statement that invoke showTooltip(), then this kind of function can be removed consequently and so goes the listener. The same logic as jumpOut() and hideTooltip() functions.
Delete all them. And then go on to delete the code of adding, positioning and coloring tooltip MovieClip.
as file(remove tooltip version)
PlayOverLay
Here is the sketch:
playOverlay.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, playDown);
playOverlay.addEventListener(flash.events.MouseEvent.ROLL_OVER, butOverlayOver);
playOverlay.addEventListener(flash.events.MouseEvent.ROLL_OUT, butOverlayOut);
playOverlay.buttonMode = true;
public function hidePlayOverlay():void
{
com.greensock.TweenNano.to(playOverlay, 0.2, {"alpha":0, "scaleX":playOverlay.sXY * 0.8, "scaleY":playOverlay.sXY * 0.8, "ease":com.greensock.easing.Back.easeOut});
return;
}
public function disablePlayOverlay():void
{
playOverlay.alpha = 0;
hide_PlayOverlay = true;
return;
}
com.circlecube.Color_cc.setColor(playOverlay.icon, color_light);
com.circlecube.Color_cc.setColor(playOverlay.bg, color_dark);
if (arg1.settings.@hide_PlayOverlay == "true")
{
disablePlayOverlay();
}
public function playOverlayLayout():void
{
var loc1:*;
playOverlay.scaleY = loc1 = 5 * video.width / 640;
playOverlay.scaleX = loc1;
playOverlay.sXY = playOverlay.scaleX;
playOverlay.x = video.width / 2 + video.x;
playOverlay.y = video.height / 2 + video.y;
return;
}
com.greensock.TweenNano.to(playOverlay, 1, {"x":arg1 + videoWidth * arg3 / 2, "y":arg2 + videoHeight * arg4 / 2, "scaleX":5 * arg3, "scaleY":5 * arg4, "ease":com.greensock.easing.Back.easeOut});
playOverlay.sXY = 5 * arg3;
public function showPlayOverlay():void
{
if (!hide_PlayOverlay)
{
playOverlay.icon.gotoAndStop(vcr.playB.icon.frame);
com.greensock.TweenNano.to(playOverlay, 0.2, {"alpha":0.75, "scaleX":playOverlay.sXY, "scaleY":playOverlay.sXY, "ease":com.greensock.easing.Back.easeOut, "overwrite":false});
}
return;
}
Finally, delete playOverlay MC in the root mc.
Keyboard Event
There is a listener that if user press space key on keyboard, the play state will be toggled, meaning playing will be pausing, and vice verse.
stage.addEventListener(flash.events.KeyboardEvent.KEY_DOWN, keyDownListener);
public function keyDownListener(arg1:flash.events.KeyboardEvent):*
{
trace("keyboard: keyCode: " + arg1.keyCode.toString());
if (arg1.keyCode == spaceKey)
{
playDown();
}
return;
}
as file(remove playoverlay, keyboard-event version)
Remove of Detail Module
Although, it should be similar to what I did on share Module, it won't hurt to do it again.
Find out the code that regisiters listener to detailB button for mouse-click event:
vcr.detailB.buttonMode = true;
vcr.detailB.addEventListener(flash.events.MouseEvent.ROLL_OVER, butOver);
vcr.detailB.addEventListener(flash.events.MouseEvent.ROLL_OUT, butOut);
vcr.detailB.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, dt_click);
And then, pinpoint the function definition of dt_click() :
public function dt_click(arg1:flash.events.MouseEvent=null):void
{
if (vcr.detailB.tooltip != "Hide Details")
{
dt_open(arg1);
closer.visible = true;
}
else
{
dt_close(arg1);
closer.visible = false;
}
return;
}
It invoke two functions: dt_open() and dt_close():
public function dt_open(arg1:flash.events.MouseEvent=null):void
{
hideAllWindows();
var loc1:*;
vcr.detailB.tooltip = loc1 = "Hide Details";
dt.visible = true;
dt_bg.alpha = 0;
dt_update();
com.greensock.TweenNano.to(dt, 0.5, {"delay":0.5, "alpha":1, "ease":com.greensock.easing.Quad.easeIn});
com.greensock.TweenNano.to(dt_bg, 0.5, {"delay":0, "alpha":0.1, "ease":com.greensock.easing.Quad.easeIn});
scaleVideo(v_x_mini_dt, v_y_mini, v_sX_mini, v_sY_mini);
dt_detail.width = stage.stageWidth - padding * 4;
dt_detail.height = stage.stageHeight / 2 - padding * 6;
dt_detail.x = padding * 2;
dt_detail.y = stage.stageHeight / 2 + padding * 3;
dt_bg.x = dt_detail.x - padding;
dt_bg.y = dt_detail.y - padding;
dt_bg.width = dt_detail.width + padding * 2;
dt_bg.height = dt_detail.height + padding * 2;
return;
}
It calls hideAllWindows(), this function set all visual panels invisible to hide all windows; switching to each view state(playlist, detail, share) will call it before any other works proceeded, and then visualize the panel they would like to show(pl, dt, sh). Since this function is referred in the function navigating to playList view state pl_open(), we can not remove it for now.
We notice it call dt_update() function, it is for refreshing the content of detail view, but since it is called by dt_build(), we keep it for a moment.
So we go back to dt_close():
public function dt_close(arg1:flash.events.MouseEvent=null):void
{
var e:flash.events.MouseEvent=null;
var loc1:*;
e = arg1;
var loc2:*;
vcr.detailB.tooltip = loc2 = "Show Details";
com.greensock.TweenNano.to(dt, 0.5, {"delay":0, "alpha":0, "ease":com.greensock.easing.Quad.easeIn, "onComplete":function ():*
{
dt.visible = false;
return;
}})
com.greensock.TweenNano.to(dt_bg, 0.5, {"delay":0, "alpha":0, "ease":com.greensock.easing.Quad.easeIn, "onComplete":function ():*
{
dt_bg.visible = false;
return;
}})
scaleVideo(v_x_norm, v_y_norm, v_sX_norm, v_sY_norm);
return;
}
It is called by close button its click event handler:
public function closer_click(arg1:flash.events.MouseEvent):void
{
if (vcr.playlistB.tooltip == "Close Playlist" || vcr.detailB.tooltip == "Hide Details")
{
pl_close(arg1);
//dt_close(arg1);
closer.visible = false;
}
return;
}
From now on, all the functions to show detail view out is removed, but the content are still there, they will be created each time the app run. And that is what dt_build() do:
internal function dt_build():void
{
trace("dt_build");
dt = new flash.display.MovieClip();
dt_detail = new flash.text.TextField();
dt_detail.wordWrap = true;
dt_detail.selectable = false;
dt_detail.width = stage.stageWidth - padding * 4;
dt_detail.height = stage.stageHeight / 2 - padding * 6;
dt_detail.x = padding * 2;
dt_detail.y = stage.stageHeight / 2 + padding * 3;
dt_bg = new flash.display.Sprite();
dt_bg.graphics.beginFill(color_accent);
dt_bg.graphics.drawRect(0, 0, dt_detail.width + padding * 2, dt_detail.height + padding * 2);
dt_bg.x = -padding;
dt_bg.y = -padding;
dt.addChild(dt_bg);
dt.addChild(dt_detail);
plc.addChild(dt);
dt.visible = false;
dt_update();
return;
}
Now we can delete the call to it and its definition, and as well, dt_update():
public function dt_update():void
{
dt_detail.styleSheet = player_css;
dt_detail.htmlText = "<body><h1>CURRENTLY VIEWING</h1><h1>" + video_title + "</h1><h2>" + video_desc + "</h2></body>";
return;
}
and some other code that change the detail button's appearance:
com.circlecube.Color_cc.setColor(vcr.detailB.icon, color_light);
if (dt_bg)
{
com.circlecube.Color_cc.setColor(dt_bg, color_accent, 0.1);
}
And now it's time to remove the detail button's code:
change
vcrArray.push(vcr.playB, vcr.timeCurrent, vcr.bar, vcr.timeTotal, vcr.volumeB, vcr.playlistB, vcr.detailB);
to
vcrArray.push(vcr.playB, vcr.timeCurrent, vcr.bar, vcr.timeTotal, vcr.volumeB, vcr.playlistB);
remove:
vcr.detailB.weight = 8;
vcr.detailB.fixed = loc2 = loc2;
vcr.detailB.tooltip = "Show Details";
vcr.detailB.tooltip = loc1 = "Show Details";
dt.visible = false;
change
if (vcr.playlistB.tooltip == "Close Playlist" || vcr.detailB.tooltip == "Hide Details")
to
if (vcr.playlistB.tooltip == "Close Playlist")
remove
dt = new flash.display.MovieClip();
internal var dt:flash.display.MovieClip;
internal var pl_detail:flash.text.TextField;
pl_detail.visible = false;
as file(remove detail version)
Remove of PlayList Module
Listener for mouse-click event goes firstly:
vcr.playlistB.buttonMode = true;
vcr.playlistB.addEventListener(flash.events.MouseEvent.ROLL_OVER, butOver);
vcr.playlistB.addEventListener(flash.events.MouseEvent.ROLL_OUT, butOut);
vcr.playlistB.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, pl_click);
remove all references of pl_click() , and its definition:
public function pl_click(arg1:flash.events.MouseEvent=null):void
{
if (vcr.playlistB.tooltip != "Close Playlist")
{
pl_open(arg1);
closer.visible = true;
}
else
{
pl_close(arg1);
closer.visible = false;
}
return;
}
There are a handful of functions that control the play state of video player, in the snapshot, the blue background means event handler, and the the functions surrounded by a red circle are not in use if the play-list module is not required.
So, we can delete code relevent to pl_open(),pl_close(),pl_play() andpli_click().
The last function pli_click(), is brought into action insidepl_build(), when regisitering a click-event listener to the snap-thumb of a video object:
thisOne.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, pli_click);
And at meantime, thisOnealso has two other listeners:pli_over(), andpli_out(), comment them out,
Now let's delve into pl_build() function:
internal function pl_build():void
{
var triangle:flash.display.MovieClip;
var i:uint;
var blackBox:flash.display.Sprite;
var thisOne:flash.display.MovieClip;
var item:uint;
var urlReq:flash.net.URLRequest;
var thisThumb:flash.display.Sprite;
var ldr:flash.display.Loader;
var loc1:*;
i = 0;
item = 0;
thisOne = null;
blackBox = null;
triangle = null;
thisThumb = null;
ldr = null;
urlReq = null;
trace("pl_build");
pl = new flash.display.MovieClip();
pl_index = 0;
trace("pl_flv.length " + pl_flv.length);
has_playlist = pl_flv.length > 1;
if (has_playlist)
{
pl_total = pl_flv.length;
i = 0;
while (i < pl_flv.length)
{
++i;
}
if (pl_orientation == "horizontal")
{
pl_x = padding;
pl_y = stage.stageHeight / 2 + padding + padding;
pl_w = stage.stageWidth - padding - padding;
pl_h = stage.stageHeight / 2 - padding - padding - padding - padding;
pli_h = pl_h;
pli_w = pl_h * 1.33;
}
else
{
pl_x = stage.stageWidth / 2 + padding + padding;
pl_y = padding;
pl_w = stage.stageWidth / 2 - padding - padding - padding;
pl_h = stage.stageHeight - padding - padding - padding;
pli_h = pl_w * 0.75;
pli_w = pl_w;
}
item = 0;
while (item < pl_flv.length)
{
thisOne = new flash.display.MovieClip();
thisOne.smoothing = true;
blackBox = new flash.display.Sprite();
blackBox.graphics.beginFill(16777215);
blackBox.graphics.drawRect(-1, -1, pli_w + 2, pli_h + 2);
blackBox.alpha = thumbFadeOut;
thisOne.addChild(blackBox);
thisOne.blackBox = blackBox;
triangle = new flash.display.MovieClip();
if (pl_orientation == "horizontal")
{
thisOne.myy = loc2 = (pli_h - pli_h * thumbSmall) / 2;
thisOne.y = loc2;
thisOne.myx = loc2 = (pli_w * thumbLarge + padding) * item;
thisOne.x = loc2;
thisOne.myy_over = (pli_h - pli_h * thumbLarge) / 2;
thisOne.myx_over = thisOne.myx - thisOne.width * Math.abs(thumbSmall - thumbLarge) / 2;
triangle.graphics.beginFill(16777215);
triangle.graphics.moveTo(pli_w / 2 - padding, padding);
triangle.graphics.lineTo(pli_w / 2, 0);
triangle.graphics.lineTo(pli_w / 2 + padding, padding);
triangle.graphics.lineTo(pli_w / 2 - padding, padding);
triangle.alpha = 0;
thisOne.addChild(triangle);
thisOne.triangle = triangle;
}
else
{
var loc2:*;
thisOne.myy = loc2 = (pli_h * thumbLarge + padding) * item;
thisOne.y = loc2;
thisOne.myx = loc2 = (pli_w - pli_w * thumbSmall) / 2;
thisOne.x = loc2;
thisOne.myy_over = thisOne.myy - thisOne.height * Math.abs(thumbSmall - thumbLarge) / 2;
thisOne.myx_over = (pli_w - pli_w * thumbLarge) / 2;
triangle.graphics.beginFill(16777215);
triangle.graphics.moveTo(padding, pli_h / 2 - padding);
triangle.graphics.lineTo(0, pli_h / 2);
triangle.graphics.lineTo(padding, pli_h / 2 + padding);
triangle.graphics.lineTo(padding, pli_h / 2 - padding);
triangle.alpha = 0;
thisOne.addChild(triangle);
thisOne.triangle = triangle;
}
thisOne.scaleY = loc2 = thumbSmall;
thisOne.scaleX = loc2;
thisOne.itemNum = item;
thisOne.title = pl_title[item];
thisOne.desc = pl_desc[item];
thisOne.flv = pl_flv[item];
thisOne.still = pl_still[item];
thisThumb = new flash.display.Sprite();
ldr = new flash.display.Loader();
urlReq = new flash.net.URLRequest(thisOne.still);
try
{
ldr.load(urlReq);
}
catch (e:ArgumentError)
{
trace("pl_build", e);
}
ldr.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, completeHandler);
ldr.contentLoaderInfo.addEventListener(flash.events.IOErrorEvent.IO_ERROR, errorHandler);
thisThumb.addChild(ldr);
thisOne.addChild(thisThumb);
//thisOne.buttonMode = true;
//thisOne.addEventListener(flash.events.MouseEvent.ROLL_OVER, pli_over);
//thisOne.addEventListener(flash.events.MouseEvent.ROLL_OUT, pli_out);
//thisOne.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, pli_click);
pl.addChild(thisOne);
++item;
}
plc.addChild(pl);
pl.x = pl_x;
pl.y = pl_y;
pl.visible = false;
pl.alpha = 0;
pl_mask = new flash.display.Sprite();
pl_mask.graphics.beginFill(39168);
pl_mask.graphics.drawRect(0, 0, pl_w, pl_h);
pl_mask.cacheAsBitmap = true;
pl.mask = pl_mask;
addChild(pl_mask);
pl_mask.x = pl_x;
pl_mask.y = pl_y;
pl.addEventListener(flash.events.Event.ENTER_FRAME, pl_move);
pl_detail = new flash.text.TextField();
pl_detail.htmlText = "";
pl_detail.wordWrap = true;
pl_detail.selectable = false;
pl_detail.multiline = true;
plc.addChild(pl_detail);
if (pl_bg == null)
{
pl_bg = new flash.display.Sprite();
pl_bg.graphics.beginFill(color_accent);
pl_bg.graphics.drawRect(0, 0, pl_detail.width + padding * 2, pl_detail.height + padding * 2);
pl_bg.x = -padding;
pl_bg.y = -padding;
pl_bg.visible = false;
plc.addChild(pl_bg);
}
}
else
{
vcrRemove(vcr.playlistB);
pl_total = 1;
}
trace("termination of build pl");
return;
}
What does this function do:
1. create some temperary display objects and some variables, for storage;
2. initialize pl as MovieClip, it is a container; setpl_index to0, keeping track of the video item's index of playing queue;
3. set has_playlist to true only if the length ofpl_flv is larger than 0,pl_flv is an array that stores the video item, and this data is inserted when reading xml;
4. calculate the position of thumbs and store them in some temporary variables, and according to pl_orientation(horizontal or vertical);
5. for each video item in pl_flv array, draw the visual graphics of the thumbs, and align them, and assign listeners, and finally add them to pl;
6. add enter_frame event listener to pl, add pl toplc;
7. create TextField instance for holding the text description, and add it to plc;
8. if the length is 0, remove playlist button in vcr
The variable has_playlist is used in videoComplete() function, but even we left this Boolean variable as its default value false, it will not affect the behaiver. So we can still comment out pl_build(). Butpl_index should be set to 0 explicitly, because when it is accessed first time, it's as its default value 0 assigned by Flash compiler, so we add this line of code to the constructor of the main class:
pl_index = 0;
And now, firstly, remove all the event handler function invoked inside pl_build().
Since all the view states are removed, the close button will never show up, so all code works around it are obsoleted. But before that, we remove playlist buttonplaylistB andpl andpl_bg, pl_x, pl_y, pl_h, pl_w.
And at this point, the function hideAllWindow(), makes no sense, since its body is empty. And pl_previous(),pl_last() have no reference.
as file(remove playlist version)
Some Doubts at the End
onMetaData
About the VideoClient object which is for monitoring video loading process:
videoClient = new Object();
videoClient["onMetaData"] = function (arg1:*):*
{
trace("have I been ever executed? haha");
trace("videoClient.onMetaData");
if (duration == -1)
{
duration = Number(arg1["duration"]);
playerLayout();
}
return;
}
public function onMetaData(arg1:Object):void
{
if (duration == -1 || !pl_duration)
{
duration = Number(arg1["duration"]);
trace("onMetaData duration:", duration);
pl_duration = true;
playerLayout();
}
return;
}
Actually, its author's mistake, he has two lines of code inside the constructor function of the main class:
ns.client = videoClient;
ns.client = this;
and that is why the onMetaData() function can work automatically.
Construction of Child MovirClip
If I don't remove the tooltip from the root movieClip, namely the stage, then I cann't comment out the declaration for it in as file:
public var tooltip:flash.display.MovieClip;
Otherwise, compiler will generate an error saying cann't construct the MovieClip in Sprite().
ReferenceError: Error #1056: 無法在 CirclecubeVideoPlayer 上建立屬性 playOverlay。
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at CirclecubeVideoPlayer()