Why does my proprietary file format fail to unarchive? - actionscript-3

I've got a proprietary file format that works as an archive. It takes a folder full of files and packs them into a single file with no compression - the first X bytes of the files are dedicated to the "Table of contents" - the file paths, their size in bytes and their location (byte index) in the archive file. the remaining bytes are for the actual data of each file.
This format works and has been working for several years except in a few cases I am trying to debug. There are some cases where the files fail to unarchive properly In my experience this is typically on laptops which I presume have 5400 rpm hard drives. But sometimes it fail on SSD hard drives (like a Surface Book) Also the failure is not consistent. If I were to unarchive the same file 10 times on a "problem" machine it might only fail 1 or 2 times or not at all in some cases.
In the language that I am unarchiving this format (as3), the file stream reader has property 'readAhead' - which as the docs indicate is 'The minimum amount of data to read from disk when reading files asynchronously' . Could this value be affecting my unarchiving? My initial value for this was '8192' which I have now changed to 8192/4 to test on some new machines. Anyone have any thoughts on this? Is the readAhead value irrelevant?
I realize this is vague. I'm not looking for a specific solution just want to get some feedback from people who have more experience on how I could better diagnose and resolve this issue.
Here is the class in question. I've tried to remove anything unrelated to what I'm asking about:
/**
* ...
* #author Phil
*/
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class Archive extends EventDispatcher
{
public static const UNARCHIVING_COMPLETE:String = "unarchivingComplete";
public static const UNARCHIVING_PROGRESS:String = "unarchivingProgress";
public static const UNARCHIVE_CANCEL:String = "unarchiveCancel";
public static const ENDIAN:String = Endian.LITTLE_ENDIAN;
private var _inputFile:File;
private var _outputFile:File;
private var _inputStream:FileStream;
private var _outputStream:FileStream;
private var _files:Vector.<ArchiveItem>;
private var _readAheadValue:uint = 8192 / 4;
private var _maxTableSize:uint = 40960 * 30;
private var _tableData:ByteArray;
private var _curArchiveItem:ArchiveItem;
private var _currentArchiveItemBytesWritten:uint;
private var _pointerPosition:uint = 0;
private var _tableSize:uint = 0;
private var _totalSize:uint = 0;
private var _totalFiles:uint = 0;
public function Archive()
{
}
public function readArchive(archive:File, dest:File):void
{
_inputFile = archive;
_outputFile = dest;
createReadStream();
createTableData();
_inputStream.openAsync( _inputFile, FileMode.READ );
}
public function destroy():void
{
killStreams();
_inputFile = null;
_outputFile = null;
}
public function cancel():void
{
killStreams();
}
private function killStreams():void
{
killInStream();
killOutStream();
}
private function killInStream():void
{
if (!_inputStream) return;
_inputStream.removeEventListener(Event.COMPLETE, onFileReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onFileReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.CLOSE, onInputClosed);
_inputStream.removeEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
_inputStream.close();
_inputStream = null;
}
private function killOutStream():void
{
if (!_outputStream) return;
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.removeEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.close();
_outputStream = null;
}
private function createTableData():void
{
_files = new Vector.<ArchiveItem>();
_tableData = new ByteArray();
_tableData.endian = ENDIAN;
}
private function createReadStream():void
{
_inputStream = new FileStream();
_inputStream.endian = ENDIAN;
_inputStream.readAhead = _readAheadValue;
_inputStream.addEventListener(Event.CLOSE, onInputClosed);
_inputStream.addEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
}
private function onErrorReadingArchive(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function onArhiveReadComplete(e:Event):void
{
if (_tableData.length < _maxTableSize)
{
onTableReadProgress( null, true);
}
}
private function onTableReadProgress(e:ProgressEvent, force:Boolean = false):void
{
if (_tableData.length < _maxTableSize && force == false)
{
_inputStream.readBytes( _tableData,_tableData.length );
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
populateTable( _tableData );
}
return;
if (_inputStream.bytesAvailable < _maxTableSize && force == false)
{
return;
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
var ba:ByteArray = new ByteArray();
ba.endian = ENDIAN;
_inputStream.readBytes(ba);
populateTable( ba );
}
}
private function populateTable(tableData:ByteArray):void
{
var a:ArchiveItem;
var offset:uint = 0;
var size:uint = 0;
var fileName:String;
if (tableData is ByteArray)
{
tableData.position = 0;
}
for (;;)
{
offset = tableData.readUnsignedInt();
size = tableData.readUnsignedInt();
fileName = tableData.readUTF();
if (fileName == "endTable")
{
_tableSize = tableData.position;
_totalFiles = _files.length;
_totalSize = _inputFile.size;
completeTableRead();
break;
}
a = new ArchiveItem();
a.filename = fileName;
a.offset = offset;
a.size = size;
_files.push(a);
}
}
private function completeTableRead():void
{
createFileOutputStream();
_inputStream.readAhead = _readAheadValue;
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.addEventListener(Event.COMPLETE, onArchiveReadProgress);
writeNextArchiveItemToFile();
}
private function onInputClosed(e:Event):void
{
completeUnarchiving();
}
private function completeUnarchiving():void
{
killStreams();
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function createFileOutputStream():void
{
_outputStream = new FileStream();
_outputStream.endian = ENDIAN;
_outputStream.addEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
}
private function onOutPutClosed(e:Event):void
{
completeUnarchiving();
}
private function onIOError(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function writeNextArchiveItemToFile():void
{
if (_files.length == 0)
{
endWriting();
return;
}
_curArchiveItem = _files.shift();
_currentArchiveItemBytesWritten = 0;
var dest:File = new File();
dest.nativePath = _outputFile.nativePath + File.separator + _curArchiveItem.filename;
_outputStream.open(dest, FileMode.WRITE);
movePointer();
}
private function endWriting():void
{
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArchiveReadProgress);
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.close();
_inputStream.close();
}
private function onOutputStreamCloseOnCompelte(e:Event):void
{
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function movePointer():void
{
_inputStream.position = _tableSize + _curArchiveItem.offset;
_pointerPosition = _inputStream.position;
if (_curArchiveItem.size == 0)
{
writeNextArchiveItemToFile();
}
}
private function onArchiveReadProgress(e:Event):void
{
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
return;
}
writeBytesToDisk();
}
private function writeBytesToDisk():void
{
var bytes:ByteArray = new ByteArray();
var bytesRemaining:uint = _curArchiveItem.size - _currentArchiveItemBytesWritten;
var bytesToWrite:uint = _inputStream.bytesAvailable;
if (bytesToWrite > bytesRemaining)
{
bytesToWrite = bytesRemaining;
}
_inputStream.readBytes(bytes, 0, bytesToWrite);
try {
_outputStream.writeBytes(bytes, 0, bytes.length); //This throws an error on large files.
}catch (e:Error)
{
dispatchEvent( new Event(Event.CANCEL) );
return;
}
_currentArchiveItemBytesWritten += bytes.length;
_pointerPosition = _inputStream.position;
dispatchEvent( new Event(UNARCHIVING_PROGRESS) );
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
}
}
}
}
class ArchiveItem
{
public var offset:uint;
public var size:uint;
public var filename:String;
public function ArchiveItem()
{
}
}

This was too long for comments..
Just my personal opinion but I think you've over-cooked a simple task. Your usage of .readAhead is confusing. For un-archive part why not have..
(1) On startup your app creates & fills an Object with entries parsed from table of contents (myself I'd just make & update 3 arrays noting file Names, Sizes and also the Indices within the archive file).
(2) For extracting say the 5th file in archive you just check dest_Name = fileNames[4]; for expected output name String, then also note expected dest_Size = size[4]; integer (length to extract).
(3) Now just read the archive file (on disk) and get that 5th file saved.
Archive_Stream.openAsync( URL_Archive_File, FileMode.READ );
Archive_Stream.position = dest_indexInArchive[4]; //starting index
The above would read bytes into a temp_BA which can then be saved (when READ is complete, the handler function does a WRITE to disk of that single extracted file). Now you can use temp_BA.clear(); to reset and clear it for a different file (or just reclaim memory used).

Related

Set up a Countdown and stop the game when it reaches 0

I have a simple game in AS3, and I'm trying to get a countdown working, so when the countdown gets to 0 the game ends.
I'm not getting any errors when I test this code but I'm also not getting a countdown clock. In the project I've created a text box and made it dynamic with an embedded font.
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.media.Sound;
import flash.media.SoundChannel;
public class MatchingGameObject10 extends MovieClip {
// game constants
private static const boardWidth:uint = 2;
private static const boardHeight:uint = 2;
private static const cardHorizontalSpacing:Number = 52;
private static const cardVerticalSpacing:Number = 52;
private static const boardOffsetX:Number = 145;
private static const boardOffsetY:Number = 70;
private static const pointsForMatch:int = 50;
private static const pointsForMiss:int = -5;
// variables
private var firstCard:Card10;
private var secondCard:Card10;
private var cardsLeft:uint;
private var gameScore:int;
private var gameStartTime:uint;
private var clockTimer:Timer;
// text fields
private var gameScoreField:TextField;
private var clock:TextField;
// timer to return cards to face-down
private var flipBackTimer:Timer;
// set up sounds
var theFirstCardSound:FirstCardSound = new FirstCardSound();
var theMissSound:MissSound = new MissSound();
var theMatchSound:MatchSound = new MatchSound();
// initialization function
public function MatchingGameObject10():void {
// make a list of card numbers
var cardlist:Array = new Array();
for(var i:uint=0;i<boardWidth*boardHeight/2;i++) {
cardlist.push(i);
cardlist.push(i);
}
// create all the cards, position them, and assign a randomcard face to each
cardsLeft = 0;
for(var x:uint=0;x<boardWidth;x++) { // horizontal
for(var y:uint=0;y<boardHeight;y++) { // vertical
var c:Card10 = new Card10(); // copy the movie clip
c.stop(); // stop on first frame
c.x = x*cardHorizontalSpacing+boardOffsetX; // set position
c.y = y*cardVerticalSpacing+boardOffsetY;
var r:uint = Math.floor(Math.random()*cardlist.length); // get a random face
c.cardface = cardlist[r]; // assign face to card
cardlist.splice(r,1); // remove face from list
c.addEventListener(MouseEvent.CLICK,clickCard); // have it listen for clicks
c.buttonMode = true;
addChild(c); // show the card
cardsLeft++;
}
}
// set up the score
gameScoreField = new TextField();
addChild(gameScoreField);
gameScore = 0;
showGameScore();
}
// set up the clock
public function CountdownClock() {
startClock();
}
public function startClock() {
clockTimer = new Timer(1000,10);
clockTimer.addEventListener(TimerEvent.TIMER, clockTick);
clockTimer.addEventListener(TimerEvent.TIMER_COMPLETE, clockEnd);
clockTimer.start();
showClock();
}
public function clockTick(event:TimerEvent) {
showClock();
}
public function showClock() {
clock.text = String(clockTimer.repeatCount - clockTimer.currentCount);
}
public function clockEnd(event:TimerEvent) {
clock.text = "!";
}
// player clicked on a card
public function clickCard(event:MouseEvent) {
var thisCard:Card10 = (event.target as Card10); // what card?
if (firstCard == null) { // first card in a pair
firstCard = thisCard; // note it
thisCard.startFlip(thisCard.cardface+2);
playSound(theFirstCardSound);
} else if (firstCard == thisCard) { // clicked first card again
firstCard.startFlip(1);
firstCard = null;
playSound(theMissSound);
} else if (secondCard == null) { // second card in a pair
secondCard = thisCard; // note it
thisCard.startFlip(thisCard.cardface+2);
// compare two cards
if (firstCard.cardface == secondCard.cardface) {
// remove a match
removeChild(firstCard);
removeChild(secondCard);
// reset selection
firstCard = null;
secondCard = null;
// add points
gameScore += pointsForMatch;
showGameScore();
playSound(theMatchSound);
// check for game over
cardsLeft -= 2; // 2 less cards
if (cardsLeft == 0) {
MovieClip(root).gameScore = gameScore;
MovieClip(root).clockTimer = clockTimer;
MovieClip(root).gotoAndStop("gameover");
}
} else {
gameScore += pointsForMiss;
showGameScore();
playSound(theMissSound);
flipBackTimer = new Timer(2000,1);
flipBackTimer.addEventListener(TimerEvent.TIMER_COMPLETE,returnCards);
flipBackTimer.start();
}
} else { // starting to pick another pair
returnCards(null);
playSound(theFirstCardSound);
// select first card in next pair
firstCard = thisCard;
firstCard.startFlip(thisCard.cardface+2);
}
}
// return cards to face-down
public function returnCards(event:TimerEvent) {
if (firstCard != null) firstCard.startFlip(1);
if (secondCard != null) secondCard.startFlip(1);
firstCard = null;
secondCard = null;
flipBackTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,returnCards);
}
public function showGameScore() {
gameScoreField.text = "Score: "+String(gameScore);
}
public function playSound(soundObject:Object) {
var channel:SoundChannel = soundObject.play();
}
}
}
In your question you are speaking about a text field that you'v added to your stage, but in this case, your current code should give you an error about the line private var clock:TextField; if your text field is named clock, otherwise ( the name of your text field is not clock ) you can use that name in your showClock() function and do not forget to call CountdownClock() which will start the timer :
public function MatchingGameObject10(): void
{
// ...
CountdownClock();
}
And
public function showClock(): void
{
your_clock_textfield.text = String(clockTimer.repeatCount - clockTimer.currentCount);
}
You can also create your clock text field like you did with your gameScoreField one and in this case you can remove the text field that you'v already inserted in your stage :
public function MatchingGameObject10(): void
{
// ...
clock = new TextField();
addChild(clock);
CountdownClock();
}
Also, don't forget to set the position of your text fields because they will be inserted in the same position (0, 0) by default.
For embedding fonts dynamically ( using ActionScript ), take a look on my answer of this question.
Hope that can help.

AIR for desktop and Google's Speech to text API [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
Is anyone aware of a native Extension for Adobe AIR desktop that ties into Google's Speech API?
After a couple days of searching i have come across 2 ANE's but they both seem to be dependent on the Android OS. ie You must target and publish to an android based device for them to work
http://myappsnippet.com/google-speech-api-air-native-extension/
http://blog.immanuelnoel.com/2011/12/07/new-actionscript-native-extension-speech-recognition/
There is also this approach which works offline, but requires training and only works with 'pre canned' responses
http://www.bytearray.org/?p=1151
Here's a web example of Google's API
https://www.google.com/intl/en/chrome/demos/speech.html
I too tried the same thing for ios. But finally i found some FLAC file which integrates with Google API only. And this works a bit better for me in AIR too.
http://8byte8.com/blog/2012/07/voice-recognition-ios/
just go through that URL, you will get some idea.
And the class which i made is .
package com.gmail.nxhoaf
{
import com.adobe.audio.format.WAVWriter;
import com.adobe.serialization.json.JSONDecoder;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SampleDataEvent;
import flash.media.Microphone;
import flash.media.Sound;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
import flash.utils.Endian;
import cmodule.flac.CLibInit;
import fr.kikko.lab.ShineMP3Encoder;
//import mx.controls.Alert;
public class Recorder
{
public var CALL_BACK:Function;
private var bytes:ByteArray;
private var mic:Microphone;
private var mp3Encoder : ShineMP3Encoder;
private static const FLOAT_MAX_VALUE:Number = 1.0;
private static const SHORT_MAX_VALUE:int = 0x7fff;
public function Recorder()
{
}
public function setMicrophone (mic : Microphone) {
this.mic = mic;
}
public function getMicrophone () {
return mic;
}
public function startRecord() :void {
this.bytes = new ByteArray();
mic.gain = 100;
mic.rate = 44;
mic.setSilenceLevel(0,4000);
// Remove playback listener if any
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, onPlaying);
// Add record listener
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onRecording);
}
public function stopRecord() :void {
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA,onRecording);
}
public function playback () :void {
if (bytes.length > 0) {
bytes.position = 0;
var sound:Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA,onPlaying);
sound.play();
}
}
private function onRecording(event:SampleDataEvent):void {
while (event.data.bytesAvailable) {
var sample:Number = event.data.readFloat();
bytes.writeFloat(sample);
}
}
private function onPlaying(event:SampleDataEvent): void {
var sample:Number;
for (var i:int = 0; i < 8192; i++) {
if (!bytes.bytesAvailable) return;
sample = bytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
}
public function encodeToFlacAndSend() : void {
var flacCodec:Object;
flacCodec = (new cmodule.flac.CLibInit).init();
bytes.position = 0;
var rawData: ByteArray = new ByteArray();
var flacData : ByteArray = new ByteArray();
rawData = convert32to16(bytes);
flacData.endian = Endian.LITTLE_ENDIAN;
//flacData.endian = Endian.BIG_ENDIAN
flacCodec.encode( encodingCompleteHandler, encodingProgressHandler, rawData, flacData, rawData.length, 30);
function encodingCompleteHandler(event:*):void
{
trace(flacData.length.toString(),"FLACCodec.encodingCompleteHandler(event):", event);
//Alert.show(flacData.length.toString());
//var PATH:String = "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-IN";
var PATH:String = "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-IN";
var urlRequest:URLRequest = new URLRequest(PATH);
var urlLoader:URLLoader = new URLLoader();
//urlRequest.contentType = "audio/x-flac; rate=44000";
urlRequest.contentType = "audio/x-flac; rate=44000";
urlRequest.data = flacData;
urlRequest.method = URLRequestMethod.POST;
urlLoader.dataFormat = URLLoaderDataFormat.BINARY; // default
urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, IOErrorOccured);
urlLoader.addEventListener(ErrorEvent.ERROR, urlLoader_error);
urlLoader.load(urlRequest);
function urlLoader_complete(evt:Event):void {
trace("MORTYYYYYYYY",urlLoader.data);
var dc:JSONDecoder = new JSONDecoder(String(urlLoader.data),true);
var ob:Object = dc.getValue();
var test:Array = ob["hypotheses"];
if(CALL_BACK != null){
if (test.length >=1){
CALL_BACK(test[0]["utterance"]);
}else {
CALL_BACK(null);
}
}
}
function urlLoader_error(evt:ErrorEvent): void {
trace("*** speech to text *** " + evt.toString());
if(CALL_BACK != null){
CALL_BACK(null);
}
}
function IOErrorOccured(evt:IOErrorEvent): void {
trace("*** IO Error Occured *** " + evt.toString());
if(CALL_BACK != null){
CALL_BACK(null);
}
}
function onHTTPResponse(eve:HTTPStatusEvent):void{
trace("*** HTTP Error Occured *** " + eve.toString());
}
}
function encodingProgressHandler(progress:int):void {
// trace("FLACCodec.encodingProgressHandler(event):", progress);;
}
}
/**
* Converts an (raw) audio stream from 32-bit (signed, floating point)
* to 16-bit (signed integer).
*
* #param source The audio stream to convert.
*/
private function convert32to16(source:ByteArray):ByteArray {
// trace("BitrateConvertor.convert32to16(source)", source.length);
var result:ByteArray = new ByteArray();
result.endian = Endian.LITTLE_ENDIAN;
while( source.bytesAvailable ) {
var sample:Number = source.readFloat() * SHORT_MAX_VALUE;
// Make sure we don't overflow.
if (sample < -SHORT_MAX_VALUE) sample = -SHORT_MAX_VALUE;
else if (sample > SHORT_MAX_VALUE) sample = SHORT_MAX_VALUE;
result.writeShort(sample);
}
// trace(" - result.length:", result.length);
result.position = 0;
return result;
}
/**
* Save recorded audio stream to a specific audio format
* #param soundFormat: expected sound format
*/
/* public function saveAs(soundFormat: String) {
switch(soundFormat) {
case SoundFormat.WAV:
encodeToWav(bytes);
break;
case SoundFormat.MP3:
encodeToMp3(bytes);
break;
default:
encodeToWav(bytes);
break;
}
}*/
/**
* Encode recorded audio to .wav
* #param inputStream stream which we want to encode
*
*/
private function encodeToWav(bytes:ByteArray) : void {
var wav:WAVWriter = new WAVWriter();
wav.numOfChannels = 1;
wav.sampleBitRate = 16;
wav.samplingRate = 44100;
bytes.position = 0;
var wavData : ByteArray = new ByteArray();
wavData.endian = Endian.BIG_ENDIAN;
wav.processSamples(wavData,bytes,44100,1);
//wavData.position = 0;
(new FileReference()).save(wavData, ".wav");
}
/**
* Encode recorded audio to .mp3
* #param inputStream stream which we want to encode
*
*/
private function encodeToMp3(bytes:ByteArray) : void {
var wav:WAVWriter = new WAVWriter();
wav.numOfChannels = 1;
wav.sampleBitRate = 16;
wav.samplingRate = 44100;
bytes.position = 0;
var wavData : ByteArray = new ByteArray();
wavData.endian = Endian.BIG_ENDIAN;
wav.processSamples(wavData,bytes,44100,1);
wavData.position = 0;
mp3Encoder = new ShineMP3Encoder(wavData);
mp3Encoder.addEventListener(Event.COMPLETE, mp3EncodeComplete);
mp3Encoder.addEventListener(ProgressEvent.PROGRESS, mp3EncodeProgress);
mp3Encoder.addEventListener(ErrorEvent.ERROR, mp3EncodeError);
mp3Encoder.start();
function mp3EncodeProgress(event : ProgressEvent) : void {
}
function mp3EncodeError(event : ErrorEvent) : void {
// Alert.show(event.toString());
}
function mp3EncodeComplete(event : Event) : void {
// mp3Encoder.saveAs();
}
}
}
}
//import com.gmail.nxhoaf;

Dynamic Object Name in AS3

I have this code in my MXML project, I want to get dynamic Stream connection for different and dynamic usernames.
private var inStream:NetStream;
private function listenStream(user:String):void
{
this["inStream"+user] = new NetStream(connection);
this["inStream"+user].play(user);
}
private function closeStream(user:String):void
{
//clear stream listener
this["inStream"+user].close();
}
But this code is not worked, How can i build dynamic object names in ActionScript3?
Thanks alot
Try Dictionary
import flash.utils.Dictionary
private var streamDict:Dictionary = new Dictionary();
private function listenStream(user:String):void
{
var key:String = getKey(user);
var lastStream:NetStream = streamDict[key] as NetStream;
if (lastStream)
{
//close the last stream or do sth else
}
else
{
streamDict[key] = new NetStream(connection);
streamDict[key].play(user);
}
}
private function closeStream(user:String):void
{
var key:String = getKey(user);
//clear stream listener
var stream:NetStream = streamDict[key] as NetStream ;
if (stream)
{
stream.close();
}
//delete the stream
streamDict[key] = null;
delete streamDict[key];
}
private function getKey(user:String):String
{
return "inStream" + user;
}

AS3 > Starting class on certain frame? TypeError :Error #1006

Im trying to create a simple memory game i have 3 frames Intro ,Main Game , End however every time i click the "start button" to jump to frame 2 i keep getting this error;
TypeError: Error #1006: Play_AnimalCardGame is not a function.
at AnimalCardGame/frame2()
at flash.display::MovieClip/gotoAndStop()
at AnimalCardGame/startGame()
My .AS
package{
import flash.display.*;
import flash.events.*;
import flash.utils.getTimer;
public class Play_AnimalCardGame extends MovieClip
{
private static const boardWidth:uint =4;
private static const boardHeight:uint =3;
private static const cardVSpace:Number=100;
private static const cardHSpace:Number=15;
private static const offSetX:Number=115;
private static const offSetY:Number=155;
public function Play_AnimalCardGame ():void
{
var cardDeck:Array = new Array();
for ( var i:uint=0;i<boardWidth*boardHeight/2;i++){
cardDeck.push(i);
cardDeck.push(i);
}
for(var x:uint=0; x<boardWidth ; x++){
for(var y:uint=0; y<boardHeight;y++){
var aCard:Card = new Card();
aCard.stop();
aCard.x = x*offSetX+cardVSpace;
aCard.y = y*offSetY+cardHSpace;
var randomCard:uint = Math.floor(Math.random()*cardDeck.length);
aCard.cardface= cardDeck[randomCard];
cardDeck.splice(randomCard,1);
aCard.gotoAndStop(1);
aCard.addEventListener(MouseEvent.CLICK,clickCard);
addChild(aCard);
cardLeft++;
}
}
}
private var firstPick:Card;
private var secondPick:Card;
private var cardLeft;
private static const pointHit:int =100;
private static const pointMiss:int = -5;
private var startscore =0;
var startTime:uint;
var time:uint;
public function clickCard(event:MouseEvent){
var pickedCard:Card = (event.currentTarget as Card);
if(firstPick == null){
firstPick =pickedCard;
firstPick.gotoAndStop(pickedCard.cardface+2);
}
else if (firstPick ==pickedCard){
firstPick.gotoAndStop(1);
firstPick=null;
}
else if (secondPick ==null){
secondPick= pickedCard;
secondPick.gotoAndStop(pickedCard.cardface+2);
if (firstPick.cardface == secondPick.cardface){
startscore +=pointHit;
cardLeft-=2;
removeChild(firstPick);
removeChild(secondPick);
txtscore.text= String(startscore);
firstPick = null;
secondPick=null;
}
else{
firstPick.gotoAndStop(1);
secondPick.gotoAndStop(1);
startscore +=pointMiss;
txtscore.text= String(startscore);
secondPick=null;
firstPick = pickedCard;
firstPick.gotoAndStop(pickedCard.cardface+2);
}
}
if(cardLeft==0){
gotoAndStop("gameover");
}
}
public function showTimer(event:Event)
{
startTime = getTimer();
time=0;
time = getTimer()- startTime;
txtTime.text = clockTime(time);
}
public function clockTime(ms:int){
var seconds:int = Math.floor(ms/1000);
var minutes:int = Math.floor(seconds/60);
seconds -=minutes *60;
var timeString:String = minutes+":"+String(seconds+100).substr(1,2);
return timeString;
}
}
From what i can there are no problems but then again in still only learning
It looks like you've defined the class name as
Play_AnimalCardGame
but then you define the constructor as
AnimalCardGame
Start by setting the constructor name to the same as the class name

AS3 Error 2038 on Windows only

hope someone can help me with this!
I've written a simple online 3d editor in Flash - it's about to go out to a selection of clients but the file uploader has a bit of a glitch which has only just reared its ugly head. Using FileReference to upload media to https page, it works like a dream on OSX which is what it was built on, but on Windows it's returning Error 2038 on every browser. Has anyone encountered this before?
Any help much appreciated!
public class CustomFileReferenceList extends FileReferenceList {
private var uploadURL:URLRequest;
private var pendingFiles:Array;
public static var length:int = 0;
public static var arrLen:int = 0;
public function CustomFileReferenceList() {
uploadURL = new URLRequest();
uploadURL.url = "https://___";
var rqd:URLVariables = new URLVariables();
uploadURL.method = URLRequestMethod.POST;
rqd.sessionId = Main.sessionId;
uploadURL.data = rqd;
initializeListListeners();
}
private function initializeListListeners():void {
addEventListener(Event.SELECT, selectHandler);
addEventListener(Event.CANCEL, cancelHandler);
}
private function doOnComplete():void {
//var event:Event = new Event(Uploader.LIST_COMPLETE);
//dispatchEvent(event);
enter code here
}
private function addPendingFile(file:FileReference):void {
pendingFiles.push(file);
file.addEventListener(Event.OPEN, openHandler,false,0,true);
file.addEventListener(Event.COMPLETE, completeHandler,false,0,true);
file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler,false,0,true);
file.addEventListener(ProgressEvent.PROGRESS, progressHandler,false,0,true);
file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler,false,0,true);
file.upload(uploadURL);
}
private function removePendingFile(file:FileReference):void {
for (var i:uint; i < pendingFiles.length; i++) {
if (pendingFiles[i].name == file.name) {
pendingFiles.splice(i, 1);
if (pendingFiles.length == 0) {
doOnComplete();
}
return;
}
}
}
private function selectHandler(event:Event):void {
arrLen = length = fileList.length;
pendingFiles = new Array();
var file:FileReference;
for (var i:uint = 0; i < fileList.length; i++) {
file = FileReference(fileList[i]);
addPendingFile(file);
}
}
private function cancelHandler(event:Event):void {
//var file:FileReference = FileReference(event.target);
}
private function openHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function progressHandler(event:ProgressEvent):void {
var file:FileReference = FileReference(event.target);
}
private function completeHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
length--;
removePendingFile(file);
}
private function httpErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function ioErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function securityErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
}
After trying just about every solution, the other web dev found it worked ok minus fancy url names i.e referencing ourserver/thepage.php instead of ourserver/service. Absolutely crazy.
I have today this issue, in my case, I was be trace of the length of the source (url/nativePath) and the length of destin; I was found that the length of the destin url is up to 256 characters.
To solve this, I was be changed the destin point (with simbolic link or network drive)
Example:
// MAC remote path
var mSt:String = "file:////MacBook-Pro-de-Jaime.local/Seagate/netShared/transport-machines/SoftDepot/";
// Windows Remote Drive (\\MacBook-Pro-...\transport-machines)
// Remote MAC as Windows Drive N
var mSt:String = "file:///N:/SoftDepot/";
Voila, the new name reduces several characers.