问题描述
|
早上好!
我正在尝试为MP3创建可视波形。成功加载MP3时,将调用我包含的代码。我打算从声音中提取一些重要的样本来创建波形,而不是将整个声音提取到一个字节数组中。即使在好的机器上,提取整首歌曲也可能导致闪光灯冻结3-5秒(甚至更长!)。就我的目的而言,这是不可行的。
不幸的是,我下面的代码无法产生任何数字。如果我提取整首歌曲,它将起作用,但是仅提取关键点并不能给我任何好处。执行提取是否会使声音对象的其余部分对于将来的提取无效?如果是这样,是否有解决方法,在提取过程中不会长时间冻结Flash?
代码其余部分中的一些重要变量:
waveFormWidth:波形精灵的静态宽度。
waveFormHeight:波形精灵的静态高度。
song:我将用来创建波形的声音对象。
public function mapWaveForm(e:Event = null):void
{
// Clear the wave form sprite
waveForm.graphics.clear();
waveForm.graphics.linestyle(0,0x000000,1);
// Storage for the wave form bit data
var byteOutput:ByteArray;
var leftPeakSize:Number;
var rightPeakSize:Number;
var songTotalSamples:int;
var thisSample:int;
byteOutput = new ByteArray();
// How many samples?
songTotalSamples = (song.length * 44.1);
// Loop for the wave form width
for (var peakCount:int = 0; (peakCount < waveFormWidth); peakCount++)
{
// Get info at each peak.
thisSample = Math.floor(songTotalSamples * (peakCount / waveFormWidth));
song.extract(byteOutput,1,thisSample);
byteOutput.position = 0;
trace(thisSample,byteOutput.readFloat());
leftPeakSize = byteOutput.readFloat() / 1.27;
rightPeakSize = byteOutput.readFloat() / 1.27;
// Turn those peaks into something usable.
leftPeakSize = leftPeakSize * (waveFormHeight * .5);
rightPeakSize = rightPeakSize * (waveFormHeight * .5);
// Make the left channel line
waveForm.graphics.moveto(peakCount,(waveFormHeight * .5));
waveForm.graphics.lineto(peakCount,(waveFormHeight * .5) - leftPeakSize);
// Make the right channel line
waveForm.graphics.moveto(peakCount,(waveFormHeight * .5) + rightPeakSize);
}
}
感谢您的帮助!
解决方法
为了它的价值,我只是在做同样的事情,经过一番研究才让它工作。我似乎无法将其与WAV文件一起使用,但这可以与所有类型的MP3文件兼容。我最终得到的是:
var IMAGE_SIZE:int = new int(600); // Final width of image
var IMAGE_DEPTH:int = new int(5); // How many passes per pixel of image
var RESOLUTION:int = new int(IMAGE_SIZE * IMAGE_DEPTH);
var DRAW_AMPLITUDE:int = new int(150); // pixel height of max volume line
var waveForm:Shape = new Shape();
var mp3File:Sound = new Sound();
mp3File.load(new URLRequest(\"audio.mp3\"));
mp3File.addEventListener(Event.COMPLETE,parseSound);
function parseSound(e:Event):void {
var soundBytes:ByteArray = new ByteArray();
for (var i:int=0; i<RESOLUTION; i++) {
mp3File.extract(soundBytes,1,Math.floor((mp3File.length*44.1)*(i/RESOLUTION)));
soundBytes.position = 0;
while (soundBytes.bytesAvailable > 0) {
var tmpNum:Number = new Number();
tmpNum += soundBytes.readFloat();
}
drawWave(i,tmpNum);
soundBytes.clear();
}
this.addChild(waveForm);
trace(\"--DONE--\");
}
function drawWave(i:Number,amp:Number):void {
var pixX:Number = new Number(Math.floor(i/IMAGE_DEPTH));
var pixY:Number = new Number((amp*DRAW_AMPLITUDE)/2);
waveForm.graphics.lineStyle(1,0x0,(1.2/IMAGE_DEPTH));
waveForm.graphics.moveTo(pixX,((DRAW_AMPLITUDE/2)-pixY));
waveForm.graphics.lineTo(pixX,((DRAW_AMPLITUDE/2)+pixY));
}
, 这是一篇过时的文章,也许我不能正确理解您的问题,但是extract方法允许您指定样本的长度以及起始位置。
\"public function extract(target:ByteArray,length:Number,startPosition:Number = -1):Number\"
length是要提取的样本数,startPosition是byteArray中要开始的位置。
参见http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#extract%28%29
, 使用此类:
http://www.bytearray.org/?p=329
我还把它整合到了一个很烂的,半生半熟的实验中,我早就开始制作调音台了。您也可以在此处获取其源代码:
http://code.google.com/p/ascensionsystems/downloads/list