Flex播放器(實現播放、緩衝進度條和音訊曲線顯示)

高洛峰
發布: 2016-12-27 16:51:42
原創
1333 人瀏覽過

一時興起,玩起了Flex,本來還想要做個Flex博客,不過目前還只能在裡面樹個公告。 。 。沒辦法做完啊,河蟹的個杯具的! Flex佈局不像是CSS,精美Flash動畫不是拖一個兩個控制項就能做出來滴,而是一筆一條線繪製出來滴!這些我都還不熟悉,所有折騰快一個星期了,每天都是搞到頭大才睡覺,今天終於能出一個簡單的播放器。

一直很喜歡音樂這個東西,喜歡Jay,更喜歡他的歌,也很崇拜小豬,他的一段灰色空間曾讓我激流奮進,想過自己能做個播客放自己喜歡聽的歌曲,出於自戀那樣會更有一點點滿足感。呃~分心了,前二天無意看到一群教師的個人博客,深深的被他們的博文所吸引,無論是談技術還是記錄生活的,寫得都是那麼的真切,還有堅持每日一博的,堅持不放棄...

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毫秒重新設置他們的控件Y位置以呈現出變幻曲線的效果,程式碼只有三行很簡單,具體可參考我下面源碼給出的timerTick事件。這裡為什麼要用定時器呢?在網路上看別人是監聽Event.ENTER_FRAME事件重繪音訊曲線的,不想搞那麼麻煩就直接用定時器了,隨便根據bytesTotal和bytesLoaded計算下歌曲播放時間,使用100毫秒的定時器也並好耗站資源,CPU沒有漲很高。

效果圖:

Flex播放器(實現播放、緩衝進度條和音訊曲線顯示)

mxml程式碼如下:

   =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; } ]]>                   
登入後複製

更多Flex播放器(實作播放、緩衝進度條與音訊曲線顯示)相關文章請關注PHP中文網!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門推薦
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板
    關於我們 免責聲明 Sitemap
    PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!