actionscript-3 - 将帧同步到音频和 channel.position 精度

标签 actionscript-3 actionscript synchronization audio

在 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
   ...

以前有没有人注意到这种行为?知道这种不准确性,是否有任何技术可以确定正在播放的音频“帧”?

最佳答案

是的,这是正常行为,因为事件是线程化的,因此只要线程具有优先级,就会调用它们的委托(delegate)。打印到控制台也是线程化的,因此它也可能并不总是在正确的时间打印消息。事实上,您看到的问题可能只是打印问题。尝试提高帧率,看看会发生什么。

不过,为了更准确,您可以尝试使用计时器类。通常,您可以使滴答声发生得比帧快得多,这意味着误差幅度会更低。不过,您正在使用该事件,因此可能会有一些偏差。

为了弥补这一点,您可以检查时间与帧以确定偏移量。这使您可以纠正任何漂移。

编辑:这个例子是直接从 this page 中提取的。在 ActionScript 3 文档中,请注意 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();
        }
    }
}

关于actionscript-3 - 将帧同步到音频和 channel.position 精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/929949/

相关文章:

apache-flex - Flex dataGrid 使用ItemRenderer 在datagridcolumn 中添加按钮?

java - 访问 Flex 对象中的 java 方法

javascript - 功能增量与视频同步(或自动增量)

c - 信号量问题,不要等待

javascript - 如何将 sharethis 按钮添加到我的 Flash 文件中?

android - 在 Flash AS3 中使用 Adob​​e Air 重新启动/重新启动 Android 应用程序

apache-flex - 如何设置xml :space ="preserve" from Flex/Actionscript

c++ - 信号量与条件变量——抽象层次

arrays - 在 ActionScript 数组 (Object[]) 和 Vector.<Object> 之间转换

flash - ActionScript3 用户界面组件?