Get response status code from flash Sound object - actionscript-3

I have music player which downloads and plays music (it should play while downloading), currently my code looks like this:
sound = new Sound(new URLRequest(url_stream));
Sometimes server returns 404 (Not Found) and 429 (Too many requests) status codes instead of music file, I'm looking for way to find out response status code in case of playback error, any ideas?

To get the response status, you can use HTTPStatusEvent event with an URLLoader like this :
var sound:Sound
var request:URLRequest = new URLRequest('http://www.example.com/file.mp3')
var loader:URLLoader = new URLLoader()
loader.addEventListener(
HTTPStatusEvent.HTTP_STATUS,
function(event):void {
trace('http status: ' + event.status)
if(event.status == 200){
sound = new Sound(request)
sound.play()
}
}
)
loader.addEventListener(IOErrorEvent.IO_ERROR, function(){})
loader.load(request)
This code is working 100%.

In akmozo's solution, you're downloading the MP3 twice. First to see if the file exists on the server, then once more to play it in the Sound. It would be better to do it like this:
var sound:Sound;
var request:URLRequest = new URLRequest('http://www.example.com/file.mp3');
var loader:URLLoader = new URLLoader();
var httpCode:int;
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,loaderStatus);
loader.addEventListener(Event.COMPLETE,loaderComplete);
function loaderStatus(evt:HTTPStatusEvent):void {
httpCode = evt.status;
}
function loaderComplete(evt:Event):void {
if (httpCode == 200) {
ba:ByteArray = loader.data as ByteArray;
sound = new Sound();
sound.loadCompressedDataFromByteArray(ba,ba.length);
sound.play();
}
}
Although if the URLRequest is cached, maybe it doesn't get downloaded twice.

Related

getting POST using URLRequest + if statement syntax issue

I'm trying to get the reply from the address specified in var url:String, which is either 0 or 1. If the reply is 1 then it must set currentState = CallFailed (as seen below). The client compiles without error (using Adobe Flash Builder 4.6) and seems to successfully reach var url:String, but doesn't seem to be getting the response\and or my if statement is incorrect.
Actionscript:
// check to see if block.php replies 0 or 1
var url:String = "https://domain.com/block.php?postid=" + calleeInput.text + "";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
request.data = variables;
request.method = URLRequestMethod.POST;
navigateToURL(request);
if (request.data == 1)
{
// if reply is 1 then cancel the call
currentState = CallFailed;
return;
}
PHP:
PHP will echo 0 or 1 when block.php is loaded. It's not encoded in any format such as JSON\AJAX.
It seems you want data from the server. Perhaps the URLLoader class would be better?
var url:String = "https://domain.com/block.php?postid=" + calleeInput.text + "";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
request.data = variables;
request.method = URLRequestMethod.POST;
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener( Event.COMPLETE,
function( e:Event ) : void
{
// your response data will be here
// you'll have to verify the format
trace( e.target.data );
}
)
loader.load( request );
Put a breakpoint at the trace statement and check out the contents of e.target.data, and go from there
The purpose of navigateToURL() is to open the webbrowser, as stated in its documentation:
Opens or replaces a window in the application that contains the Flash Player container (usually a browser). In Adobe AIR, the function opens a URL in the default system web browser
In order to perform an request (without opening a browser, just the HTTP communication) you should use URLLoader.
The URLLoader class downloads data from a URL as text, binary data, or URL-encoded variables.
On a related note: your logic is not valid. The call to a server is asynchronous. You have to wait for the response to be returned before reasoning about the result.
The URLLoader class dispatches a number of Events that help you decide when the result of a request is returned or if there's a problem with it.

AS3 won't send POST data to browser - wrong URLRequestHeader content type?

I have the following code in my AS3 Flash code that takes a screenshot within the swf using JPGEncoder and sends it to the url where i write it to a file in PHP.
I did run into the Google Chrome Pepperflash issue recently where the function just stops and the page fails to redirect. Nothing gets sent to save.php. By changing
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");
to
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain");
That seemed to do the trick. As of today though this works in internet Explorer but no longer in Chrome, Safari, Firefox. I saw that Adobe put out an update/patch to flash and flash player yesterday - could that have anything to do with it?
If i remove the following:
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain");
jpgURLRequest.requestHeaders.push(header);
Then the page successfully redirects but $GLOBALS['HTTP_RAW_POST_DATA'] is then empty so no image file can be created.
Is there an alternative header i can put that will solve this?
My code is:
AS3:
function createJPG(m:MovieClip, q:Number, fileName:String) {
var jpgSource:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
jpgSource.draw(stage);
var jpgScreenshot: BitmapData = new BitmapData(362, 310);
jpgScreenshot.copyPixels(jpgSource, new Rectangle(288, 89, 362, 310), new Point(0, 0));
var jpgEncoder:JPGEncoder = new JPGEncoder(q);
var jpgStream:ByteArray = jpgEncoder.encode(jpgScreenshot);
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain");
var jpgURLRequest:URLRequest = new URLRequest ("http://www.url.com/save.php");
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = jpgStream;
var jpgURLLoader:URLLoader = new URLLoader();
navigateToURL(jpgURLRequest, "_self");
}
save.php
$imagefile=''.$imageURL.'';
$fp = fopen($imagefile, 'wb');
fwrite($fp, $GLOBALS['HTTP_RAW_POST_DATA']);
fclose($fp);
header('Location: https://www.url.com/your-image.php');
Managed to get this working now with the following code. Liam was correct on the Flash Player issue. Working now by separating saving the image and navigating to the url into 2 differents function:
function createJPG(m:MovieClip, q:Number, fileName:String) {
var jpgSource:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
jpgSource.draw(stage);
var jpgScreenshot: BitmapData = new BitmapData(362, 310);
jpgScreenshot.copyPixels(jpgSource, new Rectangle(288, 89, 362, 310), new Point(0, 0));
var jpgEncoder:JPGEncoder = new JPGEncoder(q);
var jpgStream:ByteArray = jpgEncoder.encode(jpgScreenshot);
var urlLoader:URLLoader = new URLLoader();
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var saveJPG:URLRequest = new URLRequest('http://www.url.com/save_image.php?name=filename';
saveJPG.requestHeaders.push(header);
saveJPG.method = URLRequestMethod.POST;
saveJPG.data = jpgStream;
urlLoader.addEventListener(Event.COMPLETE, goToCheckout);
urlLoader.load(saveJPG);
}
function goToCheckout(e:Event):void{
var url:String = 'http://www.url.com/show_image.php';
var request:URLRequest = new URLRequest(url);
try {
navigateToURL(request, '_self');
} catch (e:Error) {
trace("Error occurred!:");
}
}
save_image.php:
if(isset($GLOBALS["HTTP_RAW_POST_DATA"])){
$jpg = $GLOBALS["HTTP_RAW_POST_DATA"];
$path = "";
$id = $_GET["name"];
$file = $id;
file_put_contents($path.$file, $jpg);
echo "complete";
} else{
// error
}
Flash Player version 13.0.0.214 introduces some key security fixes. Unfortunately it also breaks navigateToUrl() by forbidding the changing of any headers in the request given to navigateToUrl(). This breaks POST requests that need to pass in security/session token headers, or to even change the Content-Type, e.g. to text/xml, etc. as you have done in your example.
Right now, as much as it sucks, our best known workaround is to downgrade clients to 13.0.0.206
Adobe proposes using external interface call as described here: https://forums.adobe.com/message/6396080
it uses JavaScript to replace the POST method
The solution proposed by odd_duck seems simpler though - would be great to see the php code as well.

Imdb api with flash - as3 - flex

I am trying to use the imdb API, in this case: http://imdbapi.org/
I need to search for a movie by name and get a json, then load an image with the poster obtained.
I'll be using as3 - flex to generate an Air package.
I tried this example, but can't seem to get it right.
import flash.net.*;
var url:String = "http://imdbapi.org/";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
var variables:URLVariables = new URLVariables();
variables.name = "Pulp fiction";
request.data = variables;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
function onComplete (event:Event):void {
trace(event.target.data);
}
Perhaps you could enlight me with an example of connecting to the api and retrieving that json so that I can load an image with the poster and generate my air package.
Many thanks!
The API seems to want the movie in the q param so change this
variables.name = "Pulp fiction";
to :
variables.q = "Pulp fiction";
To verify : http://imdbapi.org/?q=Pulp%20Fiction
From there getting the poster URL is just a matter of reading the correct property from the JSON string.
private function onComplete (event:Event):void {
var data:Array = JSON.parse(event.target.data);
if(data && data.length)
{
var movie:Object = data[0];
trace(movie.poster);
}
}

How do you read and write http headers in ActionScript?

Is it even possible to both read and write http headers in actionscript?
Hmm... ok setting them doesn't seem to be a problem.
Pretty straight forward, you just add and array of URLRequestHeader objects to the URLRequest object.
var req:URLRequest = new URLRequest();
var someheader:URLRequestHeader = new URLRequestHeader( "Connection", "OK" );
req.requestHeaders = [someheader];
However, you can't read them in the regular FlashPlayer. This can be done in AIR and Flash Lite on using the requestHeader property on the HTTPStatusEvent.
var loader:URLLoader = new URLLoader();
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onStatus);
private function onStatus( e:HTTPStatusEvent ) : void
{
var headers:Array = e.requestHeaders; // only available in FlashLite and AIR
}
This is kinda weird.

AS3 functions and accessing variables

I'm trying to create a JW player plugin, a part of the source code is shown below:
public function initPlugin(player:IPlayer, config:PluginConfig):void {
api = player;
var streamUrl:String = 'xxx';
var streamSecret:String = 'xxx';
var xid:String = config['xid'];
var request:URLRequest = new URLRequest("xxx"+xid);
request.method = URLRequestMethod.POST;
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);
var fileName:String, drive:String, userFolder:String, t_hex:String, linkType:String
function completeHandler(evt:Event) {
linkType = evt.target.data.linkType;
fileName = evt.target.data.filename;
drive = evt.target.data.drive;
userFolder = evt.target.data.userFolder;
t_hex = evt.target.data.t_hex;
if (linkType == "1")
{
/*
PHP will generate these variables for the plugin.
fileName, drive, userFolder, t_hex
*/
var relPath:String = "/"+drive+"/"+userFolder+"/"+fileName;
var md5Hash = MD5.encrypt (streamSecret+relPath+t_hex);
var link:String = streamUrl+md5Hash+"/"+t_hex+relPath;
} else
{
}
api.load('http://music-stream.burst-dev.com/test.flv');
api.play();
}
I'm currently stuck on getting api.load('') to actually load the file. I've tested through anthropod and the variables getting added in are a-okay and the link generates perfectly.
I think my error is trying to get api = player to be accessed by function completeHandler, but it is not able to. Anyone got any ideas?
The code above worked, using Anthropod, I found out that it still was a crossdomain issue. I solved it by loading all files under the same URL basename. For example, xxx.burst-dev.com. api.load however can load files abroad, despite the crossdomain need in AS3 files.