Maison  >  Article  >  php教程  >  Lecteur Flex (implémentant la lecture, la barre de progression de la mise en mémoire tampon et l'affichage de la courbe audio)

Lecteur Flex (implémentant la lecture, la barre de progression de la mise en mémoire tampon et l'affichage de la courbe audio)

高洛峰
高洛峰original
2016-12-27 16:51:421403parcourir

J'ai commencé à jouer avec Flex sur un coup de tête. Au départ, je voulais créer un blog Flex, mais pour l'instant je ne peux y faire qu'une annonce. . . Il n’y a aucun moyen de le finir, tu es vraiment en désordre ! La mise en page Flex n'est pas comme CSS. Les belles animations Flash ne sont pas créées en faisant glisser un ou deux contrôles, mais en les dessinant un trait à la fois ! Je ne connais rien de tout cela pour l'instant. Cela fait presque une semaine que je travaille dessus et je ne me couche que lorsque je suis fatigué tous les jours. Aujourd'hui, j'ai enfin un lecteur simple.

J'ai toujours aimé la musique. J'aime Jay, et ses chansons encore plus. J'admire aussi Xiaozhu. Un morceau de son Grey Space m'a fait travailler dur. à. Les chansons issues du narcissisme vous apporteront un peu plus de satisfaction. Euh ~ J'ai été distrait. J'ai accidentellement vu les blogs personnels d'un groupe d'enseignants il y a deux jours. J'ai été profondément attiré par leurs articles de blog. Qu'ils parlaient de technologie ou d'enregistrement de la vie, ils étaient tous écrits de manière si réaliste et ils insistaient. bloguer tous les jours. Oui, persistez et n'abandonnez jamais...

mx : ProgressBar implémente la barre de progression du chargement du tampon de chanson

ProgressBar a trois modes principaux, à savoir événement, manuel et événement interrogé. est basé sur le mode événementiel. L'objet source peut être configuré pour afficher automatiquement le processus de chargement ; manuel est le mode manuel, vous devez appeler la méthode ProgressBar.setProgress() pour définir la progression de la barre de défilement interrogée ; mode manuel utilisé dans cet exemple, Sound charge la chanson de demande de chargement pour ajouter un ProgressEvent.PROGRESS Écoutez l'événement pendant le traitement, puis définissez la progression setProgress en fonction du nombre d'octets et de bytesTotal que Sound a chargé. Il convient de noter ici que lorsque vous changez de chanson, vous devez d'abord supprimer l'événement ProgressEvent.PROGRESS. Sinon, lorsque vous passez au chargement d'une nouvelle chanson avant la fin du chargement de la chanson précédemment jouée, la ProgressBar déclenchera plusieurs événements PROGRESS et la progression sera faites défiler d'avant en arrière.

mx:HSlide ajuste le curseur

Ce contrôle est utilisé à 2 endroits dans cet exemple pour contrôler la progression de la lecture et le volume sonore. Le problème de l'ajustement de la progression de la lecture m'a longtemps déconcerté au début, car pendant la lecture d'une chanson, HSlide doit automatiquement faire glisser la position de lecture actuelle, et en même temps, il doit pouvoir faire glisser manuellement la position de lecture. a à l'origine un bon événement de changement à détecter. Écoutez les modifications, mais lorsque j'utilise une minuterie pour définir la valeur de HSlide, l'événement de changement est également déclenché pour moi. Je me réfère au document d'aide sur le site officiel d'Adobe, qui indique que c'est le cas. est planifié lorsque la valeur du composant Slider change en raison d'une interaction avec la souris ou le clavier. Si liveDragging Si la propriété est vraie, l'événement continuera à être distribué lorsque l'utilisateur déplace le curseur. Si liveDragging est faux, cet événement est distribué lorsque l'utilisateur relâche le curseur. Mais quelle que soit la façon dont je l'ai configuré, comment l'événement de changement peut-il être déclenché lorsque la valeur de HSlide est modifiée dans le code ? Cela ne signifie-t-il pas qu'il est planifié lorsque la valeur change en raison de l'interaction de l'utilisateur ? Quel dommage, j'ai donc dû faire des compromis en surveillant l'événement thumbDrag. Adobe a expliqué que cet événement est programmé lorsque le curseur est enfoncé puis déplacé avec la souris. Il y a un petit problème, c'est-à-dire que le curseur doit être déplacé. Il ne se déclenchera que lorsque la manette sera enfoncée, et les clics n'auront aucun effet.

SoundMixer.computeSpectrum() analyse la courbe audio

Dans cet exemple, la courbe audio que vous voyez affichée est en fait un arrangement de 64 contrôles Canvas dessinés en bandes sur la droite, puis un minuteur est utilisé chaque Réinitialiser leur position scaleY toutes les 100 millisecondes pour montrer l'effet du changement de courbes. Le code ne comporte que trois lignes et est très simple. Pour plus de détails, veuillez vous référer à l'événement timerTick donné dans mon code source ci-dessous. Pourquoi utiliser une minuterie ici ? J'ai vu sur Internet que d'autres écoutent l'événement Event.ENTER_FRAME et redessinent la courbe audio. Si je ne veux pas causer autant de problèmes, j'utilise simplement une minuterie, je peux calculer la durée de lecture de la chanson en fonction de bytesTotal et bytesLoaded. L'utilisation d'un minuteur de 100 millisecondes ne consomme pas beaucoup de ressources du site, le processeur n'a pas augmenté très haut.

Rendu :

Lecteur Flex (implémentant la lecture, la barre de progression de la mise en mémoire tampon et laffichage de la courbe audio)

Le code mxml est le suivant :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="0" scroll="false" backgroundAlpha="0"
     horizontalScrollPolicy="off" verticalScrollPolicy="off" verticalAlign="middle" horizontalAlign="center"
     initialize="init(event)" layout="vertical" fontSize="14" paddingLeft="0" paddingTop="0" paddingRight="0" paddingBottom="0" >
    <mx:Script>
        <![CDATA[
            import mx.formatters.DateFormatter;
        
            import mx.effects.SoundEffect;
            import mx.events.SliderEvent;
            import mx.core.SoundAsset;
        
            import mx.controls.Alert;
            import mx.managers.CursorManager;
            import flash.media.*;
            
            import flash.utils.Timer;
            
            [Embed(source="images/cursor.gif")] 
            private var cursorHand : Class;//图标
            
            private var xml:XML; 
            private var xmlPath:String = "/flex/bin-debug/song.xml";
            private var currIndex : Number = 0; 
            
            private var song :Sound;
            private var channel :SoundChannel;
            private var position : Number = 0;
            // 保存 512 个声音波形的快照
            private var bytes:ByteArray = new ByteArray();
            // SoundBar 的个数
            private var barNum:uint = 64;
            // 保存所有 SoundBar 的引用
            private var soundBars:Array = new Array();
            
            //定时器
            private var timer : Timer;
            
            //Application的initialize初试化事件
            private function init(event:Event):void
            {
                var loader:URLLoader = new URLLoader(); 
                loader.load(new URLRequest(xmlPath)); 
                loader.addEventListener(Event.COMPLETE,Xml_Complete);
                
                timer = new Timer(100);
                timer.addEventListener(TimerEvent.TIMER,timerTick);
                
                var barWidth:Number = boxSoundBar.width*1.00/barNum;
                // 初始化Canvas为音频条,放入舞台并加入数组
                for (var i:uint = 0; i < barNum; i++)  {
                   var soundBar:Canvas = new Canvas();
                   soundBar.width = barWidth;
                   soundBar.height = boxSoundBar.height;
                   soundBar.x = i * barWidth;
                      soundBar.y =  0;
                   var g:Graphics = soundBar.graphics;
                   g.lineStyle(1,0x6688AA,1);
                   g.beginGradientFill(GradientType.RADIAL,[0x33cc00,0x456628],[1,1],[0,255],null,SpreadMethod.REFLECT,InterpolationMethod.RGB,0);
                   g.drawRect(0,0,soundBar.width,soundBar.height);
                   g.endFill();
                   boxSoundBar.addChild(soundBar);
                   soundBars.push(soundBar);
                }
                // 隐藏一些内建的鼠标右键菜单项
                this.contextMenu.hideBuiltInItems(); 
                var contextMenuItem : ContextMenuItem = new ContextMenuItem("Powered By: Jonllen");
                contextMenuItem.enabled = false;
                contextMenu.customItems.push(contextMenuItem);
                this.contextMenu.customItems.push(contextMenuItem);
                
                //更改鼠标图标
                CursorManager.setCursor(cursorHand);
            }
            
            //读取XML文件完成事件
            private function Xml_Complete(event:Event):void 
            {
                xml = new XML(event.target.data);
                if(xml.item.length()>=1)
                {
                    listSong.dataProvider= xml.item.name;
                    listSong.selectedIndex = 0;
                    //手动触发List的Change事件
                    listSong.dispatchEvent(new mx.events.ListEvent(Event.CHANGE, true, false));
                }
            }
            
            //List选择歌曲改变事件
            private function Xml_Change(event:Event):void
            {
                currIndex = event.target.selectedIndex;
                
                timer.stop();
                
                //停止声音文件的加载
                if( song!=null )
                {
                    //移除之前加载PROGRESS事件对songProgress进度条的控制
                    song.removeEventListener(ProgressEvent.PROGRESS,songProgress_Change);
                    if( song.isBuffering )
                        song.close();
                }
                
                song = new Sound();
                var url : String = xml.item[currIndex].url;
                var source:URLRequest = new URLRequest(url);
                song.load(source);
                song.addEventListener(ProgressEvent.PROGRESS, songProgress_Change);
                song.addEventListener(IOErrorEvent.IO_ERROR, songProgress_Error);
                
                position = 0;
                songStart();
            }
            
            //歌曲播放完成
            private function songProgress_Complete(e:Event):void {
                if(currIndex == xml.item.length()-1) {
                    currIndex = 0;
                }else {
                    currIndex++;
                }
                listSong.selectedIndex = currIndex;
                listSong.dispatchEvent(new mx.events.ListEvent(Event.CHANGE, true, false));
            }
            
            //加载歌曲失败
            private function songProgress_Error(e:IOErrorEvent):void {
                Alert.show("文件不存在!","系统提示");
            }
            
            //开始播放歌曲
            private function songStart():void {
                
                if ( channel != null ){
                    channel.stop();
                }
                
                lblName.text = xml.item[currIndex].name;
                channel = song.play(position,int.MAX_VALUE);
                
                var length :Number = song.length*song.bytesTotal/song.bytesLoaded;
                var date : Date = new Date();
                date.time = length;                
                var dt : DateFormatter = new DateFormatter();
                dt.formatString="NN:SS";
                var totalTime : String = dt.format(date);
                
                date.time = channel.position;
                lblTime.text = dt.format(date) + " | " + totalTime;
                lblStatus.text = "播放";
                
                var soundcontrol : SoundTransform = channel.soundTransform;
                soundcontrol.volume = volumeSlider.value;
                channel.soundTransform= soundcontrol;
                
                timer.start();
                boxSoundBar.visible = true;
            }
            
            //停止歌曲播放
            private function songStop():void {
                timer.stop();
                position = 0;
                boxSoundBar.visible = false;
                lblTime.text = "00:00 |"+lblTime.text.split("|")[1];
                lblStatus.text = "停止";
                songSlider.value = songSlider.minimum;
                songProgress.setProgress(songProgress.minimum,songProgress.maximum);
                if ( channel != null )
                {
                    channel.stop();
                }
            }
            
            //暂停歌曲播放
            private function songPause():void {
                if ( channel != null ){
                    timer.stop();
                    position = channel.position;
                    channel.stop();
                    lblStatus.text = "暂停";
                }
            }
            
            //加载歌曲进度条显示
            private function songProgress_Change(e:ProgressEvent):void {
                var percent:int = Math.round(e.bytesLoaded * 100 / e.bytesTotal);
                songProgress.setProgress(e.bytesLoaded,e.bytesTotal);
            }
            
            //定时器方法
            private function timerTick( e:TimerEvent):void {
                
                if( channel!=null) {
                    
                    var length :Number = song.length*song.bytesTotal/song.bytesLoaded;
                    var date : Date = new Date();
                    date.time = length;                
                    var dt : DateFormatter = new DateFormatter();
                    dt.formatString="NN:SS";
                    var totalTime : String = dt.format(date);
                    
                    date.time = channel.position;
                    lblTime.text = dt.format(date) + " | " + totalTime;
                    
                    songSlider.value=100*channel.position/length;
                    if( songSlider.value>=songSlider.maximum){
                        timer.stop();
                        songProgress_Complete(null);
                        return;
                    }
                    
                    SoundMixer.computeSpectrum(bytes, false, 0);
                    for (var i:uint = 0; i < barNum; i++)  {
                       soundBars[i].scaleY = bytes.readFloat();
                    }
                    
                }
            }
            
            //歌曲进度调整事件
            internal function songSlider_Change(e:SliderEvent):void{
                timer.stop();
                if ( channel != null ){
                    var length :Number = song.length*song.bytesTotal/song.bytesLoaded;
                    position = e.value*length/100;
                    songStart();
                }
            }
            
            //声音大小调整事件
            internal function changeVolume(evt:SliderEvent):void{
                if ( channel != null ){
                    var soundcontrol : SoundTransform = channel.soundTransform;
                    soundcontrol.volume = evt.value;
                    channel.soundTransform= soundcontrol;
                }
            }
            
            //设置歌曲播放时间和总时间
            private function setTimeStatus():void {
                var length :Number = song.length*song.bytesTotal/song.bytesLoaded;
                var date : Date = new Date();
                date.time = length;                
                var dt : DateFormatter = new DateFormatter();
                dt.formatString="NN:SS";
                var totalTime : String = dt.format(date);
                
                date.time = channel.position;
                lblTime.text = dt.format(date) + " | " + totalTime;
            }
            
        ]]>
    </mx:Script>
    <mx:HBox width="100%" verticalGap="0" verticalAlign="middle" horizontalAlign="center">
        <mx:Canvas width="440" borderColor="#CCCCCC" borderStyle="solid" height="171">
            <mx:Label id="lblName" x="5" fontSize="18" y="10" text=""/>
            <mx:HBox id="boxSoundBar" horizontalGap="0" verticalAlign="middle"
                 width="192" height="50" x="5" y="39" visible="false"></mx:HBox>
            <mx:ProgressBar id="songProgress" label="" 
                width="290" height="3" mode="manual" textAlign="left" 
                labelPlacement="center" fontSize="3" x="10" y="97" 
                minimum="0" maximum="100" barColor="yellow"
                trackColors="[white, haloSilver]"/>
            <mx:HSlider id="songSlider" styleName="song" value="0"
                 showTrackHighlight="true" x="5" y="85" thumbDrag="songSlider_Change(event)"
                 width="300" height="22" minimum="0" maximum="100" 
                 liveDragging="false" snapInterval="1"  toolTip="拖动调整播放进度">
            </mx:HSlider>
            <mx:Label id="lblStatus" x="243" y="41" text=""/>
            <mx:Label id="lblTime" x="205" y="66" text="00:00 | 5:23"/>
            <mx:Button x="10" y="124" label="Play" click="songStart()"/>
            <mx:Button x="74" y="124" label="Pause" click="songPause()"/>
            <mx:Button x="152" y="124" label="Stop" click="songStop()"/>
            <mx:HSlider id="volumeSlider" styleName="volume" change="changeVolume(event)"
                 showTrackHighlight="true" value="0.5" x="222" y="133"
                  width="81" minimum="0" maximum="10" liveDragging="true"
                   snapInterval="0.1" toolTip="音量调节" />
            <mx:Label x="308" fontSize="18" y="10" text="歌曲列表"/>
            <mx:List id="listSong" alpha="0.25" x="308" y="43" height="116"
                 change="Xml_Change(event)" width="130" toolTip="点击选择歌曲"></mx:List>
        </mx:Canvas>
    </mx:HBox>
</mx:Application>

Plus de lecteurs Flex (implémenter la lecture, la barre de progression de la mise en mémoire tampon et l'audio affichage de la courbe) Pour les articles connexes, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn