我正在尝试使用mp3文件播放无间隙循环。我已经阅读了一些教程,并了解到有类似编码器/解码延迟的东西,并且可以使用一些工具用适当的音乐数据填补这个空白。它甚至工作得很好,但是当我试图用闪光灯播放音乐时(实际上是haxe nme,但我认为它没有任何区别),我发现还有另一个延迟,我想,这是由flash制作的.media.Sound(好吧,实际上在互联网的代码中发现了这样的一些评论)。
Sooo,因为我有时需要更快或更慢地播放声音,这就是我的播放器的工作方式:
如果我已经做错了 - 请指出来。
为了摆脱这种延迟,我试图:
它起作用,但是:
你能帮助我理解为什么(1)发生以及如何解决所有3个问题?
答案 0 :(得分:0)
使用Flash完成无缝循环很烦人,但这是可能的。
尝试制作无间隙MP3很困难,所以完全避免这个问题!将循环导入为WAV文件,而不是MP3。 WAV没有任何编码器延迟,并且可以轻松地产生无缝循环。
使用Sound.play()的loops参数循环播放声音。如果音频真的无间隙,这应该产生一个无缝循环。 不要尝试使用SOUND_COMPLETE事件来循环播放声音。此事件与帧速率相关,并在声音完成后不久发生,而不是在实际发生时触发,因此总会造成间隙。
正如您所注意到的,Sound.length通常不准确。如果您确实需要准确的样本计数,请使用Sound.extract()提取完整的音频数据。它返回提取的样本数。
如果由于某种原因您无法嵌入无间隙WAV文件,或者您必须从外部位置流式传输MP3,则可以执行以下操作:
以下是一些示例代码:
// load our original audio track and extract the samples
var music:Sound = new Music();
var data:ByteArray = new ByteArray();
music.extract(data,99999999);
data.position = 0;
// crop off silent samples from the beginning
// TODO: you should also do this for the end
var i:uint = 0;
const EPSILON:Number = 0.05;
var sample:Number = 0;
// step forward until the magnitude exceeds some threshold
while(data.bytesAvailable > 8 && sample < EPSILON) {
sample = Math.abs(data.readFloat()) + Math.abs(data.readFloat());
}
// now, data.position is the location where the audio first kicks in
// let's crop it
var croppedData:ByteArray = new ByteArray();
croppedData.writeBytes(data, data.position);
croppedData.position = 0;
// load our newly cropped data and loop
music = new Sound();
music.loadPCMFromByteArray(croppedData, croppedData.length / 8);
music.play(0,99999);
与使用SampleDataEvent实时跳过差距相比,这更容易,处理器更少。如果你真的需要使用SampleDataEvent进行动态播放,那么这个方法仍然有助于为你提供一大堆音频数据而没有间隙。
请注意,以上内容仅适用于Flash 。由于您使用的是NME,因此会增加额外的皱纹层,因为NME可能会在打包过程中摆弄声音,并且上述功能并非在所有目标上都可用。但是,如果您只是为Flash目标发布,这些技术仍应有效。