在ENTER_FRAME事件上调用channel.position时,我注意到它并不是每帧都更新,但它看起来更像是每一帧半。
var sound:Sound = new Sound(new URLRequest('music.mp3'));
var channel:SoundChannel = sound.play(); // assume the sound is completely,
// totally, 100% loaded
addEventListener(Event.ENTER_FRAME, function(e:Event):void{
trace( "Position : " + channel.position
+ " - Frame : " + int(channel.position / 30));
});将产生类似于(30 FPS)的结果
...
Position : 1439.6371882086166 - Frame : 47
// 48 is missing
** Position : 1486.077097505669 - Frame : 49
** Position : 1486.077097505669 - Frame : 49
Position : 1532.517006802721 - Frame : 51
Position : 1578.9569160997733 - Frame : 52
// 53 is missing
** Position : 1625.3968253968253 - Frame : 54
** Position : 1625.3968253968253 - Frame : 54
Position : 1671.8367346938776 - Frame : 55
// 56 is missing
Position : 1718.2766439909296 - Frame : 57
...以前有没有人注意到过这种行为?在知道这种不准确的情况下,有没有什么技术可以确定正在播放的是哪一帧音频?
发布于 2009-05-31 18:03:39
是的,这是正常行为,因为事件是线程化的,因此只要它们的线程具有优先级,就会调用它们的委托。打印到控制台也是线程化的,因此它可能并不总是在正确的时间打印消息。实际上,您看到的问题可能只是一个打印问题。试着提高你的帧率,看看会发生什么。
不过,为了更准确,您可以尝试使用timer类。通常,您可以使滴答发生的速度比帧快得多,这意味着错误的容限将会更低。尽管如此,您仍在使用事件,因此可能会有一些漂移。
为了补偿这一点,您可以检查时间与帧,以确定偏移。这允许您纠正任何漂移。
编辑:此示例直接取自ActionScript 3文档中的this page,请注意它们使用的positionTimer:
package {
import flash.display.Sprite;
import flash.events.*;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.utils.Timer;
public class SoundChannelExample extends Sprite {
private var url:String = "MySound.mp3";
private var soundFactory:Sound;
private var channel:SoundChannel;
private var positionTimer:Timer;
public function SoundChannelExample() {
var request:URLRequest = new URLRequest(url);
soundFactory = new Sound();
soundFactory.addEventListener(Event.COMPLETE, completeHandler);
soundFactory.addEventListener(Event.ID3, id3Handler);
soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
soundFactory.addEventListener(ProgressEvent.PROGRESS, progressHandler);
soundFactory.load(request);
channel = soundFactory.play();
channel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
positionTimer = new Timer(50);
positionTimer.addEventListener(TimerEvent.TIMER, positionTimerHandler);
positionTimer.start();
}
private function positionTimerHandler(event:TimerEvent):void {
trace("positionTimerHandler: " + channel.position.toFixed(2));
}
private function completeHandler(event:Event):void {
trace("completeHandler: " + event);
}
private function id3Handler(event:Event):void {
trace("id3Handler: " + event);
}
private function ioErrorHandler(event:Event):void {
trace("ioErrorHandler: " + event);
positionTimer.stop();
}
private function progressHandler(event:ProgressEvent):void {
trace("progressHandler: " + event);
}
private function soundCompleteHandler(event:Event):void {
trace("soundCompleteHandler: " + event);
positionTimer.stop();
}
}
}https://stackoverflow.com/questions/929949
复制相似问题