当前位置:软件学习 > Flash >>

flash as3 Error: Error #2037 错误提示解决办法

Error: Error #2037: 函数调用序列不正确,或前面的调用不成功。

 代码如下 复制代码
at flash.media::Sound/_load()
at flash.media::Sound/load()
at org.mousebomb.media.musicPlayerV4::Mp3Container/loadMp3()
at org.mousebomb.media.musicPlayerV4::Mp3Container/nextMp3()
at org.mousebomb.media.musicPlayerV4::MusicPlayer/aC()

经过调查,这个错误的原因是:Sound对象只允许被load一个声音流,即使close()了也不能加载另一个声音.
一旦对某个 Sound 对象调用了 load(),就不能再将另一个声音文件加载到该 Sound 对象中。 若要加载另一个声音文件,请创建新的 Sound 对象。

外国人的解决办法

Sound files load asynchronously in Flash. Listen for the Event.COMPLETE event and in that event handler, add code to check if both are loaded and then play.

an example:

//

 代码如下 复制代码

Before you load,
myMusic2.addEventListener(Event.COMPLETE, musicLoaded);


//Event listener
private function musicLoaded(e:Event):void {
      //play logic here
      channel = myMusic.play(songPosition);
      channel2 = myMusic2.play(channel.position);
}

 

Example: do this:

 代码如下 复制代码

s = new Sound(req);

///do a bunch of stuff, and at some time later try to load a new mp3 in
s.load(req);

You will get

Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.

For each new mp3 you need to create a new Sound object. Note that SoundChannel is like a playhead, more than one of them can be accessing the Sound data, so you can create chorus/echo effects by triggering play() multiple times at different time/offsets. Here's a sound player that cycles through 2 mp3s with no errors, and caches the results.

 代码如下 复制代码

import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.*;
import com.troyworks.core.persistance.CacheEvent;

var mp3s:Array = ["test.mp3","BT - Satellite.mp3"];

var cache:Object = new Object();

playNext_mc.addEventListener(MouseEvent.CLICK, playSound);

var s:Sound;
var _channel:SoundChannel;

function getNextAudioURL():String {
var curURL:String = mp3s.shift();
mp3s.push(curURL);
return curURL;
}
function playSound(evt:Event = null) {
var audioSwfURL:String = getNextAudioURL();
trace("***************************************************************");
trace("playSound " +audioSwfURL);
//trace(" attempting to restore " + audioSwfURL + " into AUDIO");
try {
if (_channel != null) {
//_channel.stop(); //UNCOMMENT ME TO STOP THE PREVIOUS PLAYING TRACK
//s.load(); //won't work with progressive
//s.close(); //won't work with progressive
}
if (audioSwfURL != null && cache[audioSwfURL] == null) {

//////////// normal audio loading ////////////
var req:URLRequest = new URLRequest(audioSwfURL);
s = new Sound();
//speaker_mc.display_txt.text =".";
s.addEventListener(Event.COMPLETE, onSoundLoaded);
s.addEventListener(IOErrorEvent.IO_ERROR, onSoundFailedToLoad);
s.load(req);
}else{

//////////// use cached audio ////////////////
trace("hitting cache");
var cevt:CacheEvent = new CacheEvent(Event.COMPLETE);
cevt.target = cache[audioSwfURL];
onSoundLoaded(cevt);
}
} catch (err:IOError) {
trace(err.toString());
} catch (err:Error) {
trace(err.toString());
}
}

function onSoundFailedToLoad(Event:IOErrorEvent):void {
trace("onSoundLoaded **FAILED**");
//speaker_mc.display_txt.text = "!";
}
function onSoundLoaded(event:Event ):void {
//speaker_mc.display_txt.text = "";

var localSound:Sound = event.target as Sound;

////////////// parse the key mp3 name /////////////////

//NOTE: a cleaner approach way would to be a Proxy that passes arguments along with the event, created during //the listener

 代码如下 复制代码

var url:String = localSound.url;
var a:Number = url.lastIndexOf("/");
var b:Number = url.lastIndexOf("\");
var c:Number = Math.max(a,b);
var url2:String = url.substr(c+1, url.length);
trace("onSoundLoaded" + url2);

//////////// cache it ////////////////////////
cache[url2] = localSound;
_channel = localSound.play();
localSound.addEventListener(Event.SOUND_COMPLETE, onPlayComplete);

}
function onPlayComplete(evt:Event):void {
//if has more sounds play them else, move to next slide
//content_mc.play();
}
playSound();

Caching Sounds...or anything for that matter

Once you've loaded a Sound(Bitmap etc) it's in memory so if your reusing it (e.g. Sound FX) there's no need to reload it. Here you can use a  cache, using the name of the sound as a key, and a CustomEvent to mimic the loaded event, as the default Event target is readonly, so you can't mimic the call coming from the cache. The solution is to override it, and call the listeners directly if you can't redispatch using the original sound.  The advantage is the loading event, don't know the difference between the real or loaded. The cache might also be used for offline/online type activities. But of course be aware you're memory useage for caching like this can get large quickly.

 代码如下 复制代码

package com.troyworks.core.persistance {
import flash.events.*;
public class CacheEvent extends Event {

private var _overriddenTarget:Object;

public function CacheEvent(type:String,bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
override public function get target():Object{
return _overriddenTarget;
}
public function set target(target:Object):void{
_overriddenTarget = target;
}

}

}

补充:flash教程,As3.0
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,