I am using as3 and the Flash Professional IDE to code an app for Droid and IOS. I have noticed a few times when downloading a file nearly 100 megs that it sometimes stops for both android and IOS. It will stay at a certain percentage and I have to close the app to try again.
I am wondering if there is a "BREAK" some how for a moment in the internet connection that the file no longer sees the URL request and just stops. Does this make sense? Is there a way to fix this?
Here is the line of code I am using. The var urlString comes is an http request. Its a zip file. Exmaple is:
var urlString = "http://myWebsite.com/French.zip";
var urlReq:URLRequest = new URLRequest(urlString);
UPDATE: I think I have to add a URLstream to it but still not sure how to do this. I am getting closer I think.
Related
I'm trying to help out a client with an Adobe AIR application that suddenly stopped working on Mac OS Sierra. I haven't developed the app myself, so I am trying to do my best to solve the problem. It's essentially a Flex application written in Actionscript 3. When I was debugging I can see that I am getting the following error:
[ERROR] Error #2032: Stream Error.
The way the application works is that it first makes a web request to the server and gets an XML with a number of songs. No problem there.
After that the application downloads the first song in the XML result and starts playing.
When the first song starts playing the application then downloads the second song in the XML-list, when that download is finished it starts downloading the next one and so forth. The files being downloaded seems to be rather large, a couple of MB's.
So the first download works just fine, but all the other track downloads fails with Stream Error #2032. It seems I dont get any response headers from the failed requests, only the first one. I have a crossdomain.xml on the server.
This app works just fine on Mac OS X El Capitan and Windows, but with Sierra I am getting this error. The code is not that complex, it makes an API URL Request with an URLLoader and saves the file to disk. I have also tried using URLStream instead, same issue.
This is some of the code for example:
public function downloadTrack(track:Object, storeName:String, apiKey:String):void {
this.setCurrentTrack(track);
this.urlParameters.storeName = storeName;
this.urlParameters.keystring = apiKey;
this.urlLoader = new URLLoader();
this.urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
this.urlRequest = new URLRequest("/api/" + 'download/' +
this.currentTrack.id + "?time=" + new Date().getTime());
this.urlRequest.method = URLRequestMethod.POST;
this.urlRequest.data = this.urlParameters;
this.addEventListeners();
this.urlLoader.load(this.urlRequest);
}
private function loaded(e:Event):void {
this.fileData = e.target.data;
writeFile();
}
private function writeFile():void {
var filePath:String = this.currentTrack.md5 + '.ogg';
var cacheFile:File = this.downloadDirectory.resolvePath('.' + filePath);
this.fileStream.addEventListener(Event.CLOSE, saveReady);
this.fileStream.openAsync(cacheFile, FileMode.WRITE);
this.fileStream.writeBytes(fileData,0,fileData.length);
this.fileStream.close();
}
In the addEventListeners()-method, event-listeners for the URLLoader is added, and it's the urlloader that fires the IOError.
A weird thing that has happened twice is that the app suddenly starts to work as normal and downloads all of the files successively. Then after a couple of minutes it starts acting up again and nothing works. I am really having a hard time to understand where the error lies. I am no Adobe AIR/Flex-expert, so maybe you can point me in the right direction? I am pretty close to giving up on this one.
Thanks!
Try to change the destination, probably you don't have permissions to
write there.
Use the latest AIR SDK
Would be much better if you will share the project where it reproduced so I could check on my machine
I am trying to make my scrips as cross-platform as possible. I am using CameraUI to fetch files and upload them to Firebase. The problem is I can only get the bytearray through the filepromise and not the file extension..or anything. According to numerous guides iOS wont let you get mediaPromise.file to get it's type. So I'm left with the question of how to get a mime/type from this bytearray I have, that I know is either an image or a video from MediaPromise.type.
MetaData or anything would help.
Following this guide gets me to a security error. Something with domains. I'm in Android and iOS so I can't do Security.allowDomain("*"); I made my own version by following this guide.
I searched and found this guide, and this works. But it only fetches the bytearray..
He wrote another article that made something that extracted data from the first 64K of the bytearray or something and displayed it in his app. He used a lib that's no longer up so I can't really go with his guide.
The code in there is the code I have in my script aside from a few UI management additions. How would I go about solving this? Is there some meta-data that always lies in the first set of bytes?
I even tried using this nice ANE, but I get an error..
You can get the mime type once the mediapromise was loaded:
cameraUI = new CameraUI();
if (CameraUI.isSupported)
{
cameraUI.addEventListener(MediaEvent.COMPLETE, onCameraUIComplete);
cameraUI.addEventListener(Event.CANCEL, onCameraUICanceled);
cameraUI.addEventListener(ErrorEvent.ERROR, onCameraError);
cameraUI.launch(MediaType.IMAGE);
}
private function onCameraUIComplete(e:MediaEvent):void
{
var mediaPromise:MediaPromise = e.data;
if (mediaPromise)
{
myLoader = new Loader();
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMediaPromiseLoaded);
myLoader.addEventListener(IOErrorEvent.IO_ERROR, onMediaPromiseLoadError);
myLoader.loadFilePromise(mediaPromise);
}
}
private function onMediaPromiseLoaded(e:Event):void
{
var myLoaderInfo:LoaderInfo = e.target as LoaderInfo;
var myByteArray:ByteArray = myLoaderInfo.bytes;
var mimeType:String = myLoaderInfo.contentType;
}
Another way is to determine the mimetype "manually" based on the file extension in mediaPromise.file.extension
I know it's 2016 and this is a question about Flash...
Sadly a lot of the Flash AS3 resources are no longer available as the format has fallen out of favour with web devs and the tutorials I have managed to find are all done on earlier versions of Flash - I have CS6, and some of the functions/commands don't seem to work the same way.
So my question for you S.O gurus...
How do I load any kind of data into a swf movie via a GET URL.
For example :
www.example.com/mymovie.swf?loadfile=myfile.mp3
I know I can do the following to load an external file :
var url:String = "http://example.com/myfile.mp3";
var soundFile:URLRequest = new URLRequest(url);
But instead of hard coding the url how do I tell it to look for the data in the loadfile variable delivered via the incoming request?
The answer in case anybody else stumbles across this :
loaderInfo.parameters['loadfile']
Gets the variable from the url
I'm trying to get sound working on my iPhone game using the Web Audio API. The problem is that this app is entirely client side. I want to store my mp3s in a local folder (and without being user input driven) so I can't use XMLHttpRequest to read the data. I was looking into using FileSystem but Safari doesn't support it.
Is there any alternative?
Edit: Thanks for the below responses. Unfortunately the Audio API is horribly slow for games. I had this working and the latency just makes the user experience unacceptable. To clarify, what I need is sounething like -
var request = new XMLHttpRequest();
request.open('GET', 'file:///./../sounds/beep-1.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
dogBarkingBuffer = buffer;
}, onError);
}
request.send();
But this gives me the errors -
XMLHttpRequest cannot load file:///sounds/beep-1.mp3. Cross origin requests are only supported for HTTP.
Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101
I understand the security risks with reading local files but surely within your own domain should be ok?
I had the same problem and I found this very simple solution.
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
audio_player.src = file;
audio_player.play();
};
<input id="audio_file" type="file" accept="audio/*" />
<audio id="audio_player" />
You can test here:
http://jsfiddle.net/Tv8Cm/
Ok, it's taken me two days of prototyping different solutions and I've finally figured out how I can do this without storing my resources on a server. There's a few blogs that detail this but I couldn't find the full solution in one place so I'm adding it here. This may be considered a bit hacky by seasoned programmers but it's the only way I can see this working, so if anyone has a more elegent solution I'd love to hear it.
The solution was to store my sound files as a Base64 encoded string. The sound files are relatively small (less than 30kb) so I'm hoping performance won't be too much of an issue. Note that I put 'xxx' in front of some of the hyperlinks as my n00b status means I can't post more than two links.
Step 1: create Base 64 sound font
First I need to convert my mp3 to a Base64 encoded string and store it as JSON. I found a website that does this conversion for me here - xxxhttp://www.mobilefish.com/services/base64/base64.php
You may need to remove return characters using a text editor but for anyone that needs an example I found some piano tones here - xxxhttps://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js
Note that in order to work with my example you're need to remove the header part data:audio/mpeg;base64,
Step 2: decode sound font to ArrayBuffer
You could implement this yourself but I found an API that does this perfectly (why re-invent the wheel, right?) - https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Resource taken from - here
Step 3: Adding the rest of the code
Fairly straightforward
var cNote = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote);
var context = new webkitAudioContext();
context.decodeAudioData(byteArray, function(buffer) {
var source = context.createBufferSource(); // creates a sound source
source.buffer = buffer;
source.connect(context.destination); // connect the source to the context's destination (the speakers)
source.noteOn(0);
}, function(err) { console.log("err(decodeAudioData): "+err); });
And that's it! I have this working through my desktop version of Chrome and also running on mobile Safari (iOS 6 only of course as Web Audio is not supported in older versions). It takes a couple of seconds to load on mobile Safari (Vs less than 1 second on desktop Chrome) but this might be due to the fact that it spends time downloading the sound fonts. It might also be the fact that iOS prevents any sound playing until a user interaction event has occured. I need to do more work looking at how it performs.
Hope this saves someone else the grief I went through.
Because ios apps are sandboxed, the web view (basically safari wrapped in phonegap) allows you to store your mp3 file locally. I.e, there is no "cross domain" security issue.
This is as of ios6 as previous ios versions didn't support web audio api
Use HTML5 Audio tag for playing audio file in browser.
Ajax request works with http protocol so when you try to get audio file using file://, browser mark this request as cross domain request. Set following code in request header -
header('Access-Control-Allow-Origin: *');
I've recently started putting together a Facebook Connect AS3 app and retrieving objects and images through the Graph API.
Running anywhere but locally, I receive security errors of the form:
SecurityError: Error #2122: Security sandbox violation: Loader.content: xxxx cannot access http://photos-a.ak.fbcdn.net/xxxx.jpg
A policy file is required, but the checkPolicyFile flag was not set when this media was loaded.
If I add a line of the form:
Security.loadPolicyFile("ht_tp://photos-a.ak.fbcdn.net/crossdomain.xml");
-then I'm fine for that server, but it seems that there are any number of domains with the photos-[letter] format. I've added the one for each in the alphabet - which happily retrieves crossdomain files successfully - but it doesn't seem like a nice solution, and doesn't accommodate any new hosting setups Facebook may will implement in the future.
One thing I'd considered was retrieving the crossdomain policy file on a per image basis, capturing the domain from the image URL before making the image request. Unfortunately, at least via the Graph solution (and I haven't looked too closely at the others), their servers resolve the image url after the request is made, from something more generic like:
ht_tps://graph.facebook.com/[objectId]/picture?type=small&access_token=[accessToken]
Has anyone found a more dependable means of ensuring that images can be retrieved without security sandbox violations? Or do Facebook maintain a definitive list that developers need to keep an eye on?
Thanks!
Load the facebook crossdomains on the initial of your application as below;
Security.allowDomain("*");
Security.allowInsecureDomain("*");
Security.loadPolicyFile("http://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("https://graph.facebook.com/crossdomain.xml");
Security.loadPolicyFile("http://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.ak.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("https://profile.cc.fbcdn.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("http://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
Security.loadPolicyFile("https://fbcdn-sphotos-a.akamaihd.net/crossdomain.xml");
and then whenever you want to load an image from facebook, set the checkPolicy flag to true using the Loader's LoaderContext as below;
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
context.checkPolicyFile = true;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadFacebookPhoto);
loader.load(new URLRequest(YOUR_FACEBOOK_PHOTO_URL),context);
private function onLoadFacebookPhoto(e:Event):void
{
addChild(Bitmap(LoaderInfo(e.target).content));
}
Ideally I would guess that you'd want Flash to get the policy file on its own, rather than triggering it with Security.loadPolicyFile. Have you tried simply setting the checkPolicyFile flag for your Loader's LoaderContext?
Alternately, I believe that when you use URLLoader instead of Loader, Flash will request a policy file automatically, so you could try that as well. The tricky thing is that if you use Loader, Flash will let you display what you've loaded even without a crossdomain policy, so it doesn't load one unless you tell it to. When you use URLLoader, the load itself is not allowed unless there's a policy file, so Flash gets it automatically.