AIR: how to use FileReference.upload() with POST-based web services (AS3) - actionscript-3

I can't seem to get this little AIR app I'm making to work right. There is a single button on the stage, and when the user presses it they are presented with a file browser (FileReference.browse() function). When they select an image file, I want the image to be uploaded to the site imgur.com (http://www.api.imgur.com for those interested).
I'm getting a response from imgur, so I know my app is connecting, but it's returning an error, "No image data was sent to the upload API". Any help is greatly appreciated! (Also I do have an API key, just removed it from this post for obvious reasons :) )
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;
public class Document extends MovieClip
{
//file browser var
var myFileReference:FileReference = new FileReference();
//file loader var
private var loader:URLLoader;
//string constants
private const API_KEY:String = "******REMOVED*******";
private const UPLOAD_URL:String = "http://api.imgur.com/2/upload.xml";
public function Document()
{
// constructor code
browse_btn.addEventListener(MouseEvent.CLICK, browse);
}
function browse(e:MouseEvent)
{
var imagesFilter:FileFilter = new FileFilter("Images", "*.jpg;*.gif;*.png");
myFileReference.browse([imagesFilter]);
myFileReference.addEventListener(Event.SELECT, selectHandler);
myFileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, responseHandler);
}
function selectHandler(e:Event):void
{
var vars:String = "?key=" + API_KEY + "&name=name&title=title";
var params:URLVariables = new URLVariables();
params.date = new Date();
var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
//request.contentType = "application/octet-stream";
request.contentType = "multipart/form-data";
request.method = URLRequestMethod.POST;
request.data = params;
myFileReference.upload(request);
try
{
myFileReference.upload(request);
}
catch (error:Error)
{
trace("Unable to upload file.");
}
}
function responseHandler(e:DataEvent):void
{
trace("responseHandler() initaialized");
var res:XML = XML(e.data);
trace(res);
}
}
}

there's actually an example for AS3 on their site:
package
{
import com.adobe.images.PNGEncoder;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.SecurityErrorEvent;
import flash.events.IOErrorEvent
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
public class ImgurExample
{
private var loader:URLLoader;
private const API_KEY:String = "<api key>";
private const UPLOAD_URL:String = "http://api.imgur.com/2/upload.xml";
public function ImgurExample() {
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, onCookieSent);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
// Create a bitmapdata instance of a movieclip on the stage.
var mc:MovieClip;
var b:BitmapData = new BitmapData(mc.width, mc.height, true);
b.draw(mc);
var png:ByteArray = PNGEncoder.encode(b);
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; // set the data object of the request to your image.
loader.load(request);
}
// privates
private function onSend(e:Event):void {
var res:XML = new XML(unescape(loader.data));
trace(res);
}
private function onIOError(e:IOErrorEvent):void {
trace("ioErrorHandler: " + e);
// Handle error
}
private function onSecurityError(e:SecurityErrorEvent):void {
trace("securityErrorHandler: " + e);
// handle error
}
}
}
http://api.imgur.com/examples

Related

Passing variables from actionscript 3 to actionscript 2

I have a swf written in AS3 which loads an AS2 swf.
AS3 code:
var url:String = "as2.swf?myvar=hello";
var spURL:Array = url.split("?");
var urlVars:URLVariables = new URLVariables();
urlVars.decode(spURL[1]);
var req:URLRequest = new URLRequest( spURL[0] );
req.data = urlVars;
req.method = URLRequestMethod.GET;
AS2 code:
trace(_root.myvar);
but nothing traced!
I found solution to my question.
Full source code bellow
AS3: with a movieclip named "as2btn" and a text field named "as3_log". The publish class name is "main_as3"
package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
public class main_as3 extends MovieClip {
public var ld:Loader;
public function main_as3() {
// constructor code
this.as2btn.addEventListener(MouseEvent.MOUSE_DOWN, as2Load);
this.logMessage("Initialized!");
}
public function logMessage(msg:String)
{
this.as3_log.appendText("AS3: " + msg + "\n");
}
public function as2Load(evt:MouseEvent)
{
if (this.ld) {
this.ld.unloadAndStop();
this.ld = null;
}
var url:String = "as2.swf?myvar=1rewr&myvar2=1234";
var spURL:Array = url.split("?");
var urlVars:URLVariables = new URLVariables();
urlVars.decode(spURL[1]);
var req:URLRequest = new URLRequest(spURL[0]);
req.data = urlVars;
req.method = URLRequestMethod.GET;
this.ld = new Loader();
this.ld.load(req);
addChild(this.ld);
}
}
}
AS2: with a movieclip linkage identifier "main" and class name "main_as2" includes a text field named "as2_log"
class main_as2 extends MovieClip
{
var _parent;
function main_as2()
{
super();
this.gotoAndStop(1);
this.logMessage("Initialized!");
this.logMessage("_parent.myvar: " + _parent.myvar);
}
function logMessage(msg:String)
{
this["as2_log"].text = this["as2_log"].text + "AS2: " + msg + "\n";
}
}

How to stablish a Flash Peer-To-Peer Communication Over LAN (Without Cirrus/Stratus) with AIR

I'm trying to stream audio/video (I'm really only interested in Audio) in a LAN.
I've followed tutorials in internet which I've found very informative like the ones from Tom Krcha and thought would solve my problem. But until now I've not been successful in receiving the stream.
This is the code I'm using, can someone please point me out what am I missing?
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.media.Camera;
import flash.media.Microphone;
import flash.media.Video;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import flash.net.NetStream;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
[SWF(width="640", height="920", frameRate="60")]
public class LoudApp extends Sprite {
private var _interpreterStartButton:TextField = new TextField();
private var _listenerStartButton:TextField = new TextField();
private var _connectedLabel:TextField = new TextField();
private var _userTextField:TextField = new TextField();
private var _stream:NetStream;
private var _netConnection:NetConnection;
private var _netGroup:NetGroup;
private var _isConnected:Boolean;
private var _listenerStream:NetStream;
private var _isListener:Boolean;
private var _video:Video;
public function LoudApp() {
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
private function connect():void{
_netConnection = new NetConnection();
_netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
_netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
_netConnection.connect("rtmfp:");
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
trace("securityErrorHandler: " + event);
}
private function init(event:Event):void {
_listenerStartButton.border = _interpreterStartButton.border = true;
_listenerStartButton.backgroundColor = _interpreterStartButton.borderColor = 0;
_listenerStartButton.autoSize = _interpreterStartButton.autoSize = TextFieldAutoSize.LEFT;
_listenerStartButton.selectable = _interpreterStartButton.selectable = false;
_connectedLabel = new TextField();
_connectedLabel.y = 70;
_connectedLabel.text = "not connected";
_listenerStartButton.addEventListener(MouseEvent.CLICK, onButtonClicked, false, 0, true);
_interpreterStartButton.addEventListener(MouseEvent.CLICK, onButtonClicked, false, 0, true);
_interpreterStartButton.text = " Start\rTalking! ";
_listenerStartButton.text = " Start\rListening! ";
addChild(_interpreterStartButton);
addChild(_listenerStartButton);
addChild(_connectedLabel);
_listenerStartButton.x = 120;
var textFormat:TextFormat = new TextFormat(null, 30, 0x000000, true);
_listenerStartButton.setTextFormat(textFormat);
_interpreterStartButton.setTextFormat(textFormat);
// Init the Video
_video = new Video(stage.stageWidth, stage.stageHeight - 100);
_video.y = 100;
addChild(_video);
connect();
}
private function onButtonClicked(event:MouseEvent):void {
_isListener = event.target == _listenerStartButton;
_listenerStartButton.removeEventListener(MouseEvent.CLICK, onButtonClicked);
_interpreterStartButton.removeEventListener(MouseEvent.CLICK, onButtonClicked);
removeChild(_listenerStartButton) && removeChild(_interpreterStartButton);
/*_isConnected && */setupStream();
}
private function setupStream():void{
var groupSpecifier:GroupSpecifier = new GroupSpecifier("en-GB");
groupSpecifier.serverChannelEnabled = true;
groupSpecifier.multicastEnabled = true;
groupSpecifier.ipMulticastMemberUpdatesEnabled = true;
groupSpecifier.addIPMulticastAddress("225.225.0.1:30303");
// _netGroup = new NetGroup(_netConnection, groupSpecifier.groupspecWithAuthorizations());
// _netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
_stream = new NetStream(_netConnection, groupSpecifier.groupspecWithAuthorizations());
_stream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
if(_isListener){
_video.attachNetStream(_stream);
_stream.receiveAudio(true);
// _stream.receiveVideo(false);
_stream.play('sound');
return;
}else{
if(!Microphone.isSupported) return;
_stream.attachAudio(Microphone.getMicrophone());
// var camera:Camera = Camera.getCamera();
// _stream.attachCamera(camera);
_stream.publish("sound", "live");
// _video.attachCamera(camera);
}
}
private function netStatus(event:NetStatusEvent):void{
switch(event.info.code){
case "NetConnection.Connect.Success":
// _isConnected = true;
// _connectedLabel.text = "CONNECTED !";
break;
case "NetGroup.Connect.Success":
_isConnected = true;
_connectedLabel.text = "CONNECTED !";
break;
case "NetStream.Connect.Success":
break;
case "NetStream.Publish.Start":
break;
}
}
private function set listenerStream(value:NetStream):void {
_listenerStream = value;
}
}
}
Thank you in forward.
I was pointed out by Tom Krcha that some networks block multicast. And it was in deed the case.
I got a fresh router to test the apps again and it all worked perfectly.

AS3 - I can't get a string value returned from a function

AS3 code, from a sample, I want to have the value in the string 'location' available to other parts of the main program. It returns fine in the completed handler, but how do I make it available to the first part?
package {
import flash.display.MovieClip;
import flash.display.MovieClip;
import flash.events.*
import flash.net.*;
import flash.net.URLVariables;
public class turl extends MovieClip {
public var location:String = new String();
public function turl() {
// constructor code
var variables:URLVariables = new URLVariables();
variables.url = String("xxxxxxxxx");
sendAndLoad("xxxxxxxx", variables)
// THIS TRACE WILL NOT DISPLAY THE LOCATION _ A TINY URL
trace("TinyURL: " + location);
}
function sendAndLoad(url:String, _vars:URLVariables ):void {
var request:URLRequest = new URLRequest(url);
var _urlloader:URLLoader = new URLLoader();
_urlloader.dataFormat = URLLoaderDataFormat.TEXT;
request.data = _vars;
request.method = URLRequestMethod.POST;
_urlloader.addEventListener(Event.COMPLETE, handleComplete);
_urlloader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
_urlloader.load(request);
}
function handleComplete(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
location = loader.data;
trace("TinyURL: " + location);
}
function onIOError(event:IOErrorEvent):void {
trace("Error loading URL.");
}
}
}
package
{
import flash.display.MovieClip;
import flash.display.MovieClip;
import flash.events.*
import flash.net.*;
import flash.net.URLVariables;
public class turl extends MovieClip
{
public static var Location:String;
public function turl() {
// constructor code
var variables:URLVariables = new URLVariables();
variables.url = String("http://www.designscripting.com");
sendAndLoad("http://tinyurl.com/api-create.php", variables)
// THIS TRACE WILL NOT DISPLAY THE LOCATION _ A TINY URL
trace("TinyURL: " + Location);
}
function sendAndLoad(url:String, _vars:URLVariables ):void
{
var request:URLRequest = new URLRequest(url);
var _urlloader:URLLoader = new URLLoader();
_urlloader.dataFormat = URLLoaderDataFormat.TEXT;
request.data = _vars;
request.method = URLRequestMethod.POST;
_urlloader.addEventListener(Event.COMPLETE, handleComplete);
_urlloader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
_urlloader.load(request);
}
function handleComplete(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
Location= loader.data;
trace("TinyURLss: " + Location);
}
function onIOError(event:IOErrorEvent):void {
trace("Error loading URL.");
}
}
}
static variable Location holds your String value and you can get this String value
anywhere in class and outside the class.
The trace statement in the constructor doesn't work because that trace happens immediately after the data request is made, before the data has been downloaded and location has been set. The constructer is meant for setting the initial conditions of an object. The only way to make the result of the data request immediately available to the constructor is to pass it in directly, but I think this would defeat the point of the class.
public function TURL(value:String)
{
location = value;
// Now this will work like you think.
trace("TinyURL: " + location);
}
I'm guessing you have other objects relying on this TURL class having a proper location. If that's the case, have the TURL class dispatch an event when it sets the location variable, indicating that it is ready to be used.
function handleComplete(event:Event):void
{
var loader:URLLoader = URLLoader(event.target);
location = loader.data;
dispatchEvent(new Event(Event.COMPLETE));
}
Tested and working!
var turl:Turl = new Turl("http://www.designscripting.com");
Once the URL has been received you can access it by trace(turl.loc);
package {
import flash.display.MovieClip;
import flash.events.*
import flash.net.*;
import flash.net.URLVariables;
public class Turl extends MovieClip {
public var loc:String;
public function Turl(urlToEncode:String):void {
var variables:URLVariables = new URLVariables();
variables.url = String(urlToEncode);
sendAndLoad("http://tinyurl.com/api-create.php", variables);
}
//2. send the request for the URL
private function sendAndLoad(url:String, _vars:URLVariables ):void {
var request:URLRequest = new URLRequest(url);
request.data = _vars;
request.method = URLRequestMethod.POST;
var _urlloader:URLLoader = new URLLoader(request);
_urlloader.dataFormat = URLLoaderDataFormat.TEXT;
_urlloader.addEventListener(Event.COMPLETE, handleComplete, false, 0, true);
_urlloader.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
_urlloader.load(request);
}
//3. handle the response. Only accessible once the response has been received.
private function handleComplete(event:Event):void {
event.target.removeEventListener(Event.COMPLETE, handleComplete);
event.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
loc = event.target.data;
trace("loc = "+event.target.data);
}
function onIOError(event:IOErrorEvent):void {
event.target.removeEventListener(Event.COMPLETE, handleComplete);
event.target.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
trace("Error loading URL.");
}
}
}

How to post JSON data using Actionscript 3.0?

I have to work with webservices in Actionscript. I found the following code that allows me to use JSON URLs that implement only the GET method. However, it doesn't work for POST methods (doesn't even enter the "onComplete" method). I searched the net and was unable to find any answers. How can i "POST" JSON data using Actionscript 3.0?
package
{
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.events.*;
import com.adobe.serialization.json.JSON;
public class DataGrab extends Sprite {
public function DataGrab() {
}
public function init(resource:String):void {
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest(resource);
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);
}
private function onComplete(e:Event):void {
var loader:URLLoader = URLLoader(e.target);
var jsonData:Object = JSON.decode(loader.data);
for (var i:String in jsonData)
{
trace(i + ": " + jsonData[i]);
}
}
}
}
You need to specify the method used with your URLRequest object. The default is GET. This could be a second argument to your init method:
public function init(resource:String,method:String = "GET"):void {
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest(resource);
request.method = method;
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);
}
When you call this function you can use the static GET and POST properties of URLRequestMethod rather than just passing strings for a little bit of extra safety.
I'm doing it with
import com.adobe.serialization.json.JSON;
var messages:Array = new Array ();
messages.push ({"nombreArchivo":"value"});
messages.push ({"image":"value"});
var vars: URLVariables = new URLVariables();
vars.data = JSON.encode(messages);
var req: URLRequest = new URLRequest();
req.method = URLRequestMethod.POST;
req.data = vars;
req.url = "crearIMG.php"
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleServerResponse);
loader.load(req);

Upload picture directly to the server

In the following link http://www.tuttoaster.com/create-a-camera-application-in-flash-using-actionscript-3/ how to make the picture upload directly to the server after taking a picture from webcam
package
{
import flash.display.Sprite;
import flash.media.Camera;
import flash.media.Video;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.utils.ByteArray;
import com.adobe.images.JPGEncoder;
public class caml extends Sprite
{
private var camera:Camera = Camera.getCamera();
private var video:Video = new Video();
private var bmd:BitmapData = new BitmapData(320,240);
private var bmp:Bitmap;
private var fileReference:FileReference = new FileReference();
private var byteArray:ByteArray;
private var jpg:JPGEncoder = new JPGEncoder();
public function caml()
{
saveButton.visible = false;
discardButton.visible = false;
saveButton.addEventListener(MouseEvent.MOUSE_UP, saveImage);
discardButton.addEventListener(MouseEvent.MOUSE_UP, discard);
capture.addEventListener(MouseEvent.MOUSE_UP, captureImage);
if (camera != null)
{
video.smoothing = true;
video.attachCamera(camera);
video.x = 140;
video.y = 40;
addChild(video);
}
else
{
trace("No Camera Detected");
}
}
private function captureImage(e:MouseEvent):void
{
bmd.draw(video);
bmp = new Bitmap(bmd);
bmp.x = 140;
bmp.y = 40;
addChild(bmp);
capture.visible = false;
saveButton.visible = true;
discardButton.visible = true;
}
private function saveImage(e:MouseEvent):void
{
byteArray = jpg.encode(bmd);
fileReference.save(byteArray, "Image.jpg");
removeChild(bmp);
saveButton.visible = false;
discardButton.visible = false;
capture.visible = true;
}
private function discard(e:MouseEvent):void
{
removeChild(bmp);
saveButton.visible = false;
discardButton.visible = false;
capture.visible = true;
}
}
}
The FileReference.upload() and FileReference.download() functions are nonblocking. These functions return after they are called, before the file transmission is complete. In addition, if the FileReference object goes out of scope, any upload or download that has not yet been completed on that object is cancelled upon leaving the scope. So, be sure that your FileReference object will remain in scope for as long as the upload or download could be expected to continue. http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001063.html