广告位联系
返回顶部
分享到

Flex播放器(实现播放、缓冲进度条和音频曲线显示)

Flex 来源:互联网搜集 作者:酷站 发布时间:2018-07-21 08:23:23 人浏览
摘要

今天小编给大家带来Flex播放器(实现播放、缓冲进度条和音频曲线显示)的教程 mx:ProgressBar实现加载歌曲缓冲进度条 ProgressBar有三大mode模式,分别为event、manual、polled,event为基于事件驱动模式,可设置source对象自动显示加载进程;manual为手动模式

今天小编给大家带来Flex播放器(实现播放、缓冲进度条和音频曲线显示)的教程

mx:ProgressBar实现加载歌曲缓冲进度条

 

ProgressBar有三大mode模式,分别为event、manual、polled,event为基于事件驱动模式,可设置source对象自动显示加载进程;manual为手动模式,需要调用ProgressBar.setProgress()方法设置滚动条进度;polled为轮询模式,本例使用的manual模式,Sound加载load请求歌曲添加一个ProgressEvent.PROGRESS处理中监听事件,然后根据Sound已加载的bytes和bytesTotal数,设置setProgress进度。这里需要注意在切换歌曲的时候先要移除ProgressEvent.PROGRESS事件,否则之前播放歌曲还未加载完又切换load新歌曲时回出现ProgressBar触发多个PROGRESS事件被设置进度出现来回滚动的问题。
 

mx:HSlide调节滑秆
 

这个控件在本例中2处使用,实现对播放进度和声音大小的控制。最一开始调整播放进度的问题难倒了我很久,因为在歌曲播放过程中HSlide要自动滑动当前播放位置,同时又需要能手动拖动播放位置,HSlide本来有一个很好的change事件用来侦听改变,但是我使用定时器设置HSlide的value的时竟然也给我触发change事件,参考了Adobe哥官网的帮助文档,说是Slider 组件的值因鼠标或键盘交互操作而改变时调度,如果 liveDragging 属性是 true,则在用户移动滑块时持续调度该事件。 如果 liveDragging 是 false,则在用户释放滑块时调度该事件。但是无论我怎么设置,在代码里改变了HSlide的value值怎会触发change事件,不是说在用户交互操作而改变时调度吗?无赖啊,后来只能折中采取监听thumbDrag滑秆拖动时事件,这个事件Adobe哥的解释是当按下滑块并随后随鼠标移动时调度,这样会有一个小问题,就是需要拖动滑秆按下时才会触发,点击无效。
 

SoundMixer.computeSpectrum()分析音频曲线
 

本例你看到显示的音频曲线其实是右64个绘制成条状的Canvas控件排列而成,然后使用定时器每间隔100毫秒重新设置他们的scaleY位置以呈现出变幻曲线的效果,代码只有三行很简单,具体可参见我下面源码给出的timerTick事件。这里为什么要用定时器呢?在网上看别人是监听Event.ENTER_FRAME事件重绘音频曲线的,不想搞那么麻烦就直接用定时器了,随便根据bytesTotal和bytesLoaded计算下歌曲播放时间,使用100毫秒的定时器也并好耗站资源,CPU没有涨很高。


效果图:
 


 

mxml代码如下:

<?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>
 




版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计