AS3 在循环中使用 Sound.extract 来分析声音文件
从这个 AS3 代码中,我预计有 500 行包含“2048”的跟踪输出。但我只得到一些包含“2048”的行。其余的跟踪打印一个“0”,这表明 extract() 方法没有返回任何数据。
为什么会这样呢?我想使用特定数量的步骤迭代声音文件,以在相应位置提取 2048 字节的声音。一次提取整个声音文件会使 flashplayer 冻结几秒钟,因此对我来说不是一个好的解决方案。
只要 steps 小于 samplesInSound/2048,就可以发现此行为。越接近该值,与包含 2048 的行相比,打印包含“0”的行就越多。
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);
}
}
我的想法是,声音文件的提取部分在提取后会从声音文件的其余部分中删除(例如 Actionscript 3 - Sound.extract 方法清空声音对象数据),所以我尝试了另一个 for 循环:
for(var i=0; i<samplesInSound - steps * 2048; i += Math.floor(samplesInSound/steps) - 2048)
但这也没有成功。
谁能帮我解决这个问题吗?
From this AS3 code I expect 500 lines of trace outputs that contain "2048". But instead I get only some lines containing "2048". The rest of the traces print a "0" which shows me that the extract() method did not return any data.
Why is this the case? I would like to iterate through the soundfile with a specific amount of steps to extract 2048 bytes of the sound at the respective position. Extracting the entire soundfile at once would freeze the flashplayer for seconds and is therefore not a good solution for me
This behaviour can be found as long steps is smaller than samplesInSound/2048. The closer it comes to that value, the more lines with a "0" are printed compared to those with a 2048 in it.
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);
}
}
I had the idea that the extracted part of the soundfile is cut out of the rest of the soundfile after extracting it (like at Actionscript 3 - Sound.extract method empties sound object data), so I tried out another for loop:
for(var i=0; i<samplesInSound - steps * 2048; i += Math.floor(samplesInSound/steps) - 2048)
but this didn't work out either.
Can anyone help me with this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我没有足够的声誉来评论你的问题,所以我会写下这个带有免责声明的答案,如果它不能解决你的问题,请告诉我。
每次调用 sound.extract 都会从上一次调用 sound.extract 完成的位置提取内容,因此您不需要每次都使用 startPosition 参数。这就是为什么你会得到奇怪的结果,对 sound.extract 的调用已经在声音中前进了:
更重要的是,你现在的方式实际上并不能阻止 Flash 播放器在长声音上冻结,因为你无论如何,这一切都在一个循环中完成。在循环中抓取 500 * 2048 (1,024,000) 个步骤并不比使用 sound.extract(byteArray, 1024000) 一次抓取所有步骤更好。如果有什么不同的话,那就是速度变慢了。您需要在调用 sound.extract 之间给 Flash 时间“呼吸”。
这是一个可能的解决方案:
I don't have enough reputation to comment on your question, so I'll write this answer with a disclaimer, let me know if it doesn't solve your problem.
Every call to sound.extract will just extract from where the previous call to sound.extract finished up, so you don't need to use the startPosition argument every time. That's why you were getting strange results, the call to sound.extract was already advancing through the sound:
More importantly, the way you have it at the moment doesn't actually stop the Flash player freezing on a long sound, because you're doing it all in one loop anyway. Grabbing 500 * 2048 (1,024,000) steps in a loop is no better than just grabbing them all at once with sound.extract(byteArray, 1024000). If anything, it's slower. You need to give Flash time to 'breathe' inbetween the calls to sound.extract.
Here's a possible solution: