0 votes

Synchronisation des images avec l'audio et précision de la position du canal

En appelant channel.position sur un événement ENTER_FRAME, je remarque qu'il n'est pas mis à jour à chaque image, mais plutôt toutes les images et demie.

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));
});

donnera quelque chose comme (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
   ...

Quelqu'un a-t-il déjà remarqué ce comportement ? Existe-t-il des techniques pour déterminer quelle "image" de l'audio est jouée, compte tenu de cette imprécision ?

0voto

Soviut Points 26384

Oui, il s'agit d'un comportement normal, car les événements sont liés à des threads et appellent donc leurs délégués chaque fois que leur thread a la priorité. L'impression sur la console est également threadée, il se peut donc qu'elle n'imprime pas toujours les messages au bon moment. En fait, le problème que vous rencontrez est probablement un problème d'impression. Essayez d'augmenter votre framerate, voyez ce qui se passe.

Cependant, pour être plus précis, vous pouvez essayer d'utiliser la classe timer. En règle générale, vous pouvez faire en sorte que les tics se produisent beaucoup plus rapidement que vos images, ce qui signifie que la marge d'erreur sera plus faible. Cependant, vous utilisez l'événement, il peut donc y avoir une certaine dérive.

Pour compenser cela, vous pouvez vérifier le temps par rapport aux images pour déterminer le décalage. Cela vous permet de corriger toute dérive.

EDIT : Cet exemple est tiré directement de cette page dans la documentation d'ActionScript 3, vous remarquerez que l'option positionTimer qu'ils utilisent :

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();
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X