Adobe Flash image data - actionscript-3

I have never worked in AS3. I want to send a screen shot of flash movie to a php file. Somewhere from internet I copied this function :
function sendSprite(sprite: Sprite, scriptLocation: String): void {
var bmpData: BitmapData = new BitmapData(sprite.width, sprite.height, true, 0xFFFFFF);
bmpData.draw(sprite);
var encodedFile: Base64Encoder = new Base64Encoder();
encodedFile.encodeBytes(PNGEncoder.encode(bmpData));
var data: URLVariables = new URLVariables();
data.fileData = encodedFile;
var request: URLRequest = new URLRequest(scriptLocation);
request.method = URLRequestMethod.POST;
request.data = data;
var loader: URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, spriteSend);
loader.addEventListener(Event.OPEN, traceEvent);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, traceEvent);
loader.addEventListener(IOErrorEvent.IO_ERROR, traceEvent);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, traceEvent);
loader.addEventListener(ProgressEvent.PROGRESS, traceEvent);
try {
loader.load(request);
} catch (e: * ) {
trace("an error occured of type", e);
}
function traceEvent(e: * ): void {
trace(e);
}
function spriteSend(e: Event): void {
trace(e, "\n sprite succesfully send \n");
}
}
However I am not sure how to create a sprite object for calling the above function. Please help.

You can create an Spriteobject with the Sprite class:
//---Create a Sprite
var mySprite:Sprite = new Sprite();
//---Add Sprite to Display List
addChild(mySprite);
Inside this Sprite you can put any DisplayObject, for example:
//---Create the Video Object
var myVideo:Video = new Video();
mySprite.addChild(myVideo);
//---Create the NetConnection
var nc:NetConnection = new NetConnection();
nc.connect(null);
//---Create NetStream
var ns:NetStream = new NetStream(nc);
myVideo.attachNetStream(ns);
//---Play the video
ns.play("example.com/video.mp4");
Next, you could send the Spriteobject to your function and do your stuff.

Related

Forwarding a video by frame using NetStream in AS3

I was looking for a way to go back and forth in my video using the seek function in AS3.
import flash.filesystem.File;
import flash.net.NetStream;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var vid:Video = new Video(MovieClip(root).clip.width, MovieClip(root).clip.height)
MovieClip(root).clip.addChild(vid);
var ns:NetStream = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
vid.attachNetStream(ns);
function asyncErrorHandler(event:AsyncErrorEvent):void
{}
var file: File = File.desktopDirectory;
var myFilter: FileFilter = new FileFilter("MP4;MOV", "*.mp4;*.mov");
file.addEventListener(Event.SELECT, loadImage);
function fn_open(e: MouseEvent): void {
file.browseForOpen("Open", [myFilter]);
}
function loadImage(e: Event): void {
ns.play(file.url);
ns.pause();
}
var seek_value:int = 0
function fn_step(e: MouseEvent): void {
seek_value += 0.5
ns.seek(seek_value)
}
Unfortunately this works, but with seconds... is that possible to do so but with FPS or just a fraction of second? I've already tried entering decimal numbers inside the function, like net_stream.seek(0.5), but no results.
Any ideas?

Variable scope in function closure?

I've just started using nested functions and they come in very handy. However I am running into problems with populating a variable which is later returned by the enclosing function.
The code below is for an AIR project to load some BitmapData. I expected that my variable ("bitmapData") would be populated in the loaderComplete function but it is always returned as null. However, in my trace statements, the image dimensions are being logged, so clearly it has been read.
Is there something wrong with my syntax or my understanding (or both ;-)
private function getBitmapData(url:String):BitmapData
{
var bitmapData:BitmapData;
var bytes:ByteArray = getByteArray(url);
if (bytes == null){
trace("bytes null");
return null;
}
var loader:Loader = new Loader();
loader.loadBytes(bytes);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
function loaderComplete(event:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
trace("loader",loaderInfo.width, loaderInfo.height);
bitmapData = new BitmapData(loaderInfo.width, loaderInfo.height, false, 0xFFFFFF);
trace("bitmapData.rect", bitmapData.rect);
bitmapData.draw(loaderInfo.loader);
}
function ioErrorListener(event:IOErrorEvent):void
{
trace("ioErrorListener", event.errorID);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
}
return bitmapData;
}
public function getByteArray(url:String):ByteArray{
var byteFile:File = new File(url);
if(byteFile.exists && !byteFile.isDirectory){
var fileStream:FileStream = new FileStream();
fileStream.open(byteFile, FileMode.READ);
var tempBytes: ByteArray = new ByteArray();
fileStream.readBytes( tempBytes );
fileStream.close();
return tempBytes;
} else {
trace("file doesnt exist");
return null;
}
}
Loader.loadBytes() is an asynchronous method. The COMPLETE event is not fired in the same frame as the call to loadBytes. Therefore, you're actually attempting to return bitmapData before the code in loaderComplete executes.
You may want to try doing something with callbacks. For example, you can pass a reference to a function as a parameter in getBitmapData, and then call that function in loaderComplete:
private function getBitmapData(url:String, callback:Function):void
{
var bitmapData:BitmapData;
var bytes:ByteArray = getByteArray(url);
if (bytes == null){
trace("bytes null");
callback(null);
}
var loader:Loader = new Loader();
loader.loadBytes(bytes);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
function loaderComplete(event:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
trace("loader",loaderInfo.width, loaderInfo.height);
bitmapData = new BitmapData(loaderInfo.width, loaderInfo.height, false, 0xFFFFFF);
trace("bitmapData.rect", bitmapData.rect);
bitmapData.draw(loaderInfo.loader);
callback(bitmapData)
}
function ioErrorListener(event:IOErrorEvent):void
{
trace("ioErrorListener", event.errorID);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderComplete);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
}
}
private function handleNewBitmapData(bitmapData:BitmapData):void
{
trace("handled bitmapData.rect", bitmapData.rect);
}
getBitmapData("[some url]", handleNewBitmapData);

Putting Urlloader in a Class

I have searched on google en different pages i found the problem but not the solution.
I have a class i made and that class is called WebServiceController:
public class WebServiceController
{
private var url:String;
private var post:Object=new Object();
private var loader:URLLoader = new URLLoader();
private var postVariable:String="";
private var getVariable:String="";
private var Geladen:Boolean=false;
public function WebServiceController()
{
}
public function postUrlData(u:String,p:Object):String
{
url=u;
post=p;
var urlReq:URLRequest = new URLRequest (url);
var i:int=0;
for(var key:String in post)
{
//trace(key +" = " + post[key]);
if(i==0)
{
// urlVars.key = post[key];
postVariable=postVariable+""+key+"="+post[key];
}
else
{
//urlVars.key = post[key];
postVariable=postVariable+"&"+key+"="+post[key];
}
i++;
}
//trace(postVariable);
var urlVars:URLVariables = new URLVariables(postVariable);
//trace(urlVars);
// Add the variables to the URLRequest
urlReq.data = urlVars;
urlReq.method = URLRequestMethod.POST;
// Add the URLRequest data to a new Loader
//loader.load(urlReq);
// Set a listener function to run when completed
loader.addEventListener(Event.COMPLETE, onLoaderComplete);
// Set the loader format to variables and post to the PHP
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.load(urlReq);
function onLoaderComplete(event:Event):void
{
return loader.data;
}
}
Now from my movieclip i call the next function but it says undefined:
var wb:WebServiceController = new WebServiceController();
trace(wb.postUrlData(url,post));
I dont know how to solve this. I tried different things but it keeps saying undefined.
The URLLoader.load call is executed asynchronously so the data has not been returned when you attempt to trace it out in the class that instantiates your WebServiceController class.
To access the data in the parent class, your best bet is probably to dispatch an event from the WebServiceController class when the data has loaded and catch it in the parent class.
WebServiceController:
public function postUrlData(u:String, p:Object):void
{
url=u;
post=p;
var urlReq:URLRequest = new URLRequest (url);
var i:int=0;
for(var key:String in post)
{
//trace(key +" = " + post[key]);
if(i==0)
{
// urlVars.key = post[key];
postVariable=postVariable+""+key+"="+post[key];
}
else
{
//urlVars.key = post[key];
postVariable=postVariable+"&"+key+"="+post[key];
}
i++;
}
//trace(postVariable);
var urlVars:URLVariables = new URLVariables(postVariable);
//trace(urlVars);
// Add the variables to the URLRequest
urlReq.data = urlVars;
urlReq.method = URLRequestMethod.POST;
// Add the URLRequest data to a new Loader
//loader.load(urlReq);
// Set a listener function to run when completed
loader.addEventListener(Event.COMPLETE, onLoaderComplete);
// Set the loader format to variables and post to the PHP
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.load(urlReq);
}
private function onLoaderComplete(event:Event):void
{
// We can pass the event on like this
dispatchEvent(event);
}
Parent class:
public function initWebServiceController():void
{
var wb:WebServiceController = new WebServiceController();
wb.addEventListener(Event.COMPLETE, onWebServiceControllerDataLoaded);
wb.postUrlData(url, post);
}
private function onWebServiceControllerDataLoaded(event:Event):void
{
// The event target is the URLLoader instance. We can
// access the loaded data via its data property
trace(URLLoader(event.target).data);
}

AS3/AIR: IOStream Error when trying to upload files

I'm making an AIR app in which the user drags and drops image files onto the stage, the app then uploads those dropped images to the site imgur.com, and then returns with links to the images (in XML format).
I am having two issues:
the program works successfully with a very small file, however anything larger (1mb or more), I get an IOStream error 2023. Imgur supports uploads of up to 10mb so I know it must be something on my end.
I would like to be able to drop multiple image files at once into the program, and have it upload all of them (either synchronously or asynchronously, it does not matter). Right now the program gives errors when I attempt to do this (something along the lines of the byteArray having to be greater than 0).
Below is the code in question which is giving me issues. (thank you for your help in advanced)
private function doDragDrop(e:NativeDragEvent):void
{
trace("doDragDrop() called.");
var dropFiles:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
for each (var file:File in dropFiles)
{
switch (file.extension.toLowerCase())
{
case "jpg" :
case "jpeg" :
case "gif" :
case "png" :
case "apng" :
case "tiff" :
case "bmp" :
case "pdf" :
case "xcf" :
trace("file Extension Check = passed");
addImage(file.nativePath);
break;
//error handling for non-supported filetypes
default :
trace("ERROR: Unsupported File Type Detected!");
}
}
}
private function addImage(nativePath:String):void
{
trace("addImage() called.");
trace("NativePath is: " + nativePath);
//var file:File = new File(nativePath);
var file:File = File.desktopDirectory.resolvePath(nativePath);
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fileLoaded);
loader.loadBytes(ba);
}
private function fileLoaded(e:Event):void
{
trace("fileLoaded() called.");
var bitmap:Bitmap = Bitmap(e.target.content);
var bitmapData:BitmapData = bitmap.bitmapData;
var png:ByteArray = PNGEncoder.encode(bitmapData);
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
var vars:String = "?key=" + API_KEY + "&name=name&title=title";
var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
request.data = png;
urlLoader.load(request);
}
private function onCookieSent(e:Event):void
{
trace("onCookieSent() called.");
var res:XML = new XML(unescape(urlLoader.data));
var resultsList:XMLList = res.links;
trace(resultsList);
}
private function onIOError(e:IOErrorEvent):void
{
trace("ioErrorHandler: " + e);
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
// Handle error
}
private function onSecurityError(e:SecurityErrorEvent):void
{
trace("securityErrorHandler: " + e);
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
// handle error
}
//When the dragged object leaves the drop point, do this
private function doDragExit(e:NativeDragEvent):void
{
trace("doDragExit() called.");
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
}
after doing this:
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
you already have a ByteArray of the file/image. can't you just send this one...
private function addImage(nativePath:String):void
{
trace("addImage() called.");
trace("NativePath is: " + nativePath);
//var file:File = new File(nativePath);
var file:File = File.desktopDirectory.resolvePath(nativePath);
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
var vars:String = "?key=" + API_KEY + "&name=name&title=title";
var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
request.data = ba;
urlLoader.load(request);
}

AS3 - Remove Child Problem

I'm using the following code to display an advertisement in a mobile game that I'm working on. It works fine but I don't know what to put in the clickStart function to remove the advertisement from the stage before the game plays. I've been playing around with removeChild but can't seem to get it to work.
stop();
startButton.addEventListener(MouseEvent.CLICK,clickStart);
function clickStart(event:MouseEvent) {
gotoAndStop("play");
}
var request:URLRequest = new URLRequest("http://soma.smaato.com/oapi/reqAd.jsp");
var variables:URLVariables = new URLVariables();
variables.adspace = "0";
variables.pub = "0";
variables.devip = "127.0.0.1";
variables.format = "IMG";
variables.adcount = "1";
variables.response = "XML";
request.data = variables;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);
function onComplete(e:Event):void
{
var data:XML = new XML(loader.data as String);
var status:String = data.*::status.toString();
if(status == "success")
{
var ad:XMLList = data.*::ads.*::ad;
var link:String = ad.*::link.toString();
var l:Loader = new Loader();
l.load(new URLRequest(link));
addChild(l);
l.x = 135;
l.y = 265;
var clickurl:String = ad.*::action.#target.toString();
l.addEventListener(MouseEvent.CLICK, onAdClick);
function onAdClick(e:MouseEvent):void
{
var request:URLRequest = new URLRequest(clickurl);
navigateToURL(request);
}
}
}
You need to move the declaration of the Loader outside of the onComplete function, since the variable runs out of scope.
var l:Loader = new Loader();
You could try placing it on the same scope as these:
var request:URLRequest = new URLRequest("http://soma.smaato.com/oapi/reqAd.jsp");
var variables:URLVariables = new URLVariables();
then you should be able to update your clickStart function to something like this:
function clickStart(event:MouseEvent) {
removeChild(l);
gotoAndStop("play");
}