Flash AS3在循环中使用Sound.extract分析声音文件
从这个AS3代码中,我期望500行跟踪输出包含“2048”。但我得到的只是一些包含“2048”的行。其余的跟踪打印一个“0”,显示extract()方法没有返回任何数据 为什么会这样?我想用特定的步骤遍历声音文件,以在相应位置提取2048字节的声音。一次提取整个声音文件会使flashplayer冻结几秒钟,因此对我来说不是一个好的解决方案 只要长步长小于samplesInSound/2048,就可以发现这种行为。与2048行相比,越接近该值,打印的“0”行就越多Flash AS3在循环中使用Sound.extract分析声音文件,flash,actionscript-3,audio,bytearray,extract,Flash,Actionscript 3,Audio,Bytearray,Extract,从这个AS3代码中,我期望500行跟踪输出包含“2048”。但我得到的只是一些包含“2048”的行。其余的跟踪打印一个“0”,显示extract()方法没有返回任何数据 为什么会这样?我想用特定的步骤遍历声音文件,以在相应位置提取2048字节的声音。一次提取整个声音文件会使flashplayer冻结几秒钟,因此对我来说不是一个好的解决方案 只要长步长小于samplesInSound/2048,就可以发现这种行为。与2048行相比,越接近该值,打印的“0”行就越多 var sound:Sound
var sound:Sound = new Sound();
sound.load(new URLRequest("soundfile.mp3"));
sound.addEventListener(Event.COMPLETE, soundLoaded);
function soundLoaded(e:Event){
var samplesInSound:Number = sound.length*44.1;
var steps:int = 500;
var byteArray:ByteArray = new ByteArray();
for(var i=0; i<samplesInSound; i += Math.floor(samplesInSound/steps)){
var extracted = sound.extract(byteArray, 2048, i);
trace(i + ": " + extracted);
}
}
var声音:声音=新声音();
load(新的URL请求(“soundfile.mp3”);
sound.addEventListener(事件完成,声音加载);
功能已加载(e:事件){
var samplesInSound:Number=sound.length*44.1;
var步数:int=500;
var byteArray:byteArray=new byteArray();
对于(var i=0;i我没有足够的声誉来评论你的问题,因此我将在回答时附上免责声明,如果它不能解决你的问题,请告诉我
每次调用sound.extract都将从上一次调用sound.extract的地方提取,因此您不必每次都使用startPosition参数。这就是为什么您会得到奇怪的结果,对sound.extract的调用已经在声音中进行了:
sound.extract(byteArray, 2048) // advances 2048 samples into the sound
sound.extract(byteArray, 2048) // we are 2048 samples in, grab another 2048
sound.extract(byteArray, 2048) // we are 4096 samples in, grab another 2048, etc.
更重要的是,目前的使用方式实际上并不能阻止Flash播放器在长时间的声音中冻结,因为无论如何,你都是在一个循环中完成的。在一个循环中抓取500*2048(1024000)个步骤并不比用声音一次抓取它们要好。摘录(byteArray,1024000)。如果有的话,它会慢一些。在调用sound.extract的过程中,你需要给闪光时间来“呼吸”
下面是一个可能的解决方案:
class SoundLoader
{
public var sound:Sound;
public var byteArray:ByteArray;
public var samplesInSound:int;
public function SoundLoader(sound:Sound)
{
this.sound = sound;
samplesInSound = sound.length * 44.1;
byteArray = new ByteArray();
}
// Returns "true" if the sound has finished extracting.
public function extract(samplesToExtract:int):Boolean
{
var extracted:int = sound.extract(byteArray, samplesToExtract);
return extracted < samplesToExtract;
}
}
function soundLoaded(e:Event)
{
soundLoader = new SoundLoader(sound);
// 2048 is very low, you'll need to experiment with how much you can load at once without Flash hiccupping.
if (soundLoader.extract(2048))
{
// A very short sound! soundLoader.byteArray contains the extracted sound, ready to use.
}
else
{
// add a timer that calls soundLoader.extract(2048) again.
// keep repeating the timer until soundLoader.extract returns 'true' - then you can use soundLoader.byteArray.
// the timer allows Flash to do other things inbetween, which avoids it freezing up.
}
}
类声音加载器
{
公共声音:声音;
公共变量byteArray:byteArray;
公共var-samplesInSound:int;
公共功能SoundLoader(声音:声音)
{
这个声音=声音;
samplesInSound=sound.length*44.1;
byteArray=新的byteArray();
}
//如果声音已完成提取,则返回“true”。
公共函数提取(samplesToExtract:int):布尔值
{
提取的var:int=sound.extract(byteArray,samplesToExtract);
返回提取的
谢谢你的回答。不幸的是,我的计划是以比我在每个循环中提取的数据更大的步长循环声音。例如,我想要实现的是:sound.extract(byteArray,2048,0)//将2048个样本推进声音。extract(byteArray,2048,10000)//我们有10000个样本,再抓取一个2048声音。提取(byteArray,2048,20000)//我们有20000个样本,再抓取一个2048,等等。
我知道你提到的冻结问题。在最后的代码中,我将在帧上或在你的示例中,在计时器上连接循环。
class SoundLoader
{
public var sound:Sound;
public var byteArray:ByteArray;
public var samplesInSound:int;
public function SoundLoader(sound:Sound)
{
this.sound = sound;
samplesInSound = sound.length * 44.1;
byteArray = new ByteArray();
}
// Returns "true" if the sound has finished extracting.
public function extract(samplesToExtract:int):Boolean
{
var extracted:int = sound.extract(byteArray, samplesToExtract);
return extracted < samplesToExtract;
}
}
function soundLoaded(e:Event)
{
soundLoader = new SoundLoader(sound);
// 2048 is very low, you'll need to experiment with how much you can load at once without Flash hiccupping.
if (soundLoader.extract(2048))
{
// A very short sound! soundLoader.byteArray contains the extracted sound, ready to use.
}
else
{
// add a timer that calls soundLoader.extract(2048) again.
// keep repeating the timer until soundLoader.extract returns 'true' - then you can use soundLoader.byteArray.
// the timer allows Flash to do other things inbetween, which avoids it freezing up.
}
}