Flex4實現 音頻播放器 顯示語音波形

直接上代碼,在Flash Builder 4中新建 FLEX項目,複製代碼可以可以直接運行

需要將 file = "D:\\voice\\3791.MP3"; 改爲自己的路徑

以後還準備增加流式播放!

 



 

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   minWidth="955" minHeight="600" 
			   creationComplete="initMusic()" 
			   height="304" width="808">
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- 將非可視元素(例如服務、值對象)放在此處 -->
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			import com.adobe.serialization.json.JSON;
			
			import flash.utils.ByteArray;
			
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.core.UIComponent;
			import mx.events.IndexChangedEvent;
			import mx.managers.PopUpManager;
			import mx.printing.FlexPrintJob;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			import mx.rpc.http.HTTPService;

			
			private var serverIP:String = "http://127.0.0.1";
			private var ba:ByteArray = new ByteArray(); 
			private var soundRequest:URLRequest;
			private var sound:Sound = new Sound(); //使用Sound對象來獲取音樂文件播放聲音
			private var chanel:SoundChannel;       //引入SoundChannel對象來精確控制聲音
			private var vol:SoundTransform;        //通過設置SoundTransform對象的volume屬性控制音量
			
			private var stopPosition:int=0;        //使用stopPosition記錄暫停音樂時的位置
			private var soundState:int=1;          //使用soundState記錄是否靜音
			private var soundValue:int=2;          //記錄靜音前的音量
			private var playState:int=0;           //使用playState記錄聲音是否被停止(包括暫停)
			private var totalTime:String = "00:00";//語音文件總時間
			private var params:Object;             //URL參數列表
			private var _sperite:Sprite;           //用於繪製聲音波形
			
			//初始化
			private function initMusic():void{
				var args:Object = getParams();      //獲取URL中的參數列表
				var file:String = serverIP + args.audio+".mp3";//得到語音文件名
//				file = "http://127.0.0.1/voice/3416.mp3";
				
				//對播放控制按鈕和滑動條添加鼠標動作監聽
				soundBtn.addEventListener(MouseEvent.CLICK,onSoundClick);//有聲音
				soundBtnJ.addEventListener(MouseEvent.CLICK,onSoundClick);//靜音
				playBtn.addEventListener(MouseEvent.CLICK,onPlayBtnClick);//播放
				pauseBtn.addEventListener(MouseEvent.CLICK,onPlayBtnClick);//暫停
				proccessBar.addEventListener(MouseEvent.MOUSE_DOWN,onProccessBarDown);//播放進度條
				proccessBar.addEventListener(MouseEvent.MOUSE_UP,onProccessBarUp);//播放進度條
				
				//組件初始狀態設置
				soundSlide.value=2;//默認音量等於2
				
				if(file != null && file != ""){
					var buffer:SoundLoaderContext = new SoundLoaderContext(5000);
					soundRequest = new URLRequest(file);
					sound.load(soundRequest,buffer);
					sound.addEventListener(Event.COMPLETE, loaded);//監聽加載事件
					sound.addEventListener(ProgressEvent.PROGRESS, progressHandler);//緩衝事件
				}
				
				//控制音量
				vol = new SoundTransform();
				vol.volume = soundSlide.value;
				
			}
			
			//緩衝事件方法
			private function progressHandler(event:ProgressEvent):void{
				//計算緩衝方框的寬度(滑塊本身也有一定的寬度,減去約10個像素寬度)
				if (sound.bytesLoaded>0){ 
					bufferRect.width = sound.bytesLoaded / sound.bytesTotal*(proccessBar.width);
				}  
			}
			
			private function onProccessBarDown(e:MouseEvent):void{
				this.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
			}
			
			private function onProccessBarUp(e:MouseEvent):void{
				this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
			}
			
			//讀取語音數據,一邊取一邊畫
			private function loaded(event:Event):void {
				var width:Number = box.width;
				var height:Number =box.height;
				
				//獲取語音長度,毫秒
				var lengthTime:Number = sound.length;
				totalTime = formatTime(lengthTime);
				playTime.text = totalTime;
				
				_sperite = new Sprite();//建立影片精靈   
				var uicomponent:UIComponent = new UIComponent();  
				uicomponent.addChild(_sperite);  
				box.addElement(uicomponent);
				
				doDraw(0.1,0xffffff,0,height/2,width-2,height/2);  //繪製中心軸線
				//繪製橫軸
				for(var i:int=20;i<height;i+=20){
					doDraw(0.1,0xCCCCCC,0,i,width-2,i);  //繪製中心軸線
				}
				//繪製縱軸
				for(var j:int=40;j<width;j+=40){
					doDraw(0.1,0xCCCCCC,j,0,j,height);  //繪製中心軸線
				}
				
				var dataCount:Number = lengthTime*44.1;
				sound.extract(ba, dataCount);  //將所有的語音數據讀取到字節數組裏面
				ba.position = 0;//文件指針的當前位置
				var startX:Number = 0,startY:Number = 100;//開始點
				var m:int = 1;//記錄數據個數
				while(ba.bytesAvailable > 0){
					var value:Number = ba.readFloat();
					var endX:Number = m*width/dataCount;
					var endY:Number = height/2;
					endY = (1-value)*(height/2);//正數
					doDraw(0.1, 0x00FF00, startX, startY, endX, endY);//繪製波形
					startX = endX; startY = endY;
					if(ba.bytesAvailable > 0){
						ba.position += 84;
						m += 11;
					}
				}
				
				//完成自動播放
				playState=1;
				chanel = sound.play(stopPosition);
				chanel.soundTransform=vol;			
				this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
				playBtn.visible=false;
				pauseBtn.visible=true;
				pState.text = "狀態: 播放";
				
				load.visible = false;
			}
			
			//繪製曲線
			private function doDraw(cx:Number,color:uint,startX:Number,startY:Number,endX:Number,endY:Number):void{  
				_sperite.graphics.lineStyle(cx,color,1);  
				_sperite.graphics.moveTo(startX,startY);  
				_sperite.graphics.lineTo(endX,endY);  
			}  
			
			//播放暫停
			private function onPlayBtnClick(e:MouseEvent):void{
				//正常狀態控制播放與暫停
				if(playState==1){
					playState=0;	
					stopPosition = chanel.position; 
					chanel.stop();
					this.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
					playBtn.visible=true;
					pauseBtn.visible=false;
					pState.text = "狀態: 暫停";
				}else if(playState==0){
					playState=1;
					chanel = sound.play(stopPosition);
					chanel.soundTransform=vol;			
					this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
					playBtn.visible=false;
					pauseBtn.visible=true;
					pState.text = "狀態: 播放";
				}
			}
			
			//停止播放
			public function musStop():void{
				playState=0;
				stopPosition = 0; 
				this.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
				proccessBar.value=0;
				playTime.text="00:00/"+totalTime;
				playBtn.visible=true;
				pauseBtn.visible=false;
				pState.text = "狀態: 停止";
				if(chanel!=null){
					chanel.stop();
				}
			}
			
			//靜音處理按鈕
			private function onSoundClick(e:MouseEvent):void{
				//點擊正常狀態的靜音按鈕處理函數
				if(soundState==1){
					soundState=0;
					vol.volume=0;
					soundValue = soundSlide.value;
					soundSlide.value=0;
					soundBtnJ.visible=true;
					soundBtn.visible=false;
				}else if(soundState==0){
					soundState=1;
					soundSlide.value = soundValue;
					vol.volume=soundSlide.value;
					soundBtnJ.visible=false;
					soundBtn.visible=true;
				}
				chanel.soundTransform=vol;
			}
			
			//控制音量大小
			private function soundSlideChange():void{
				vol.volume=soundSlide.value;
				chanel.soundTransform=vol;
			}
			
			//控制播放進度
			private function onEnterFrame(e:Event):void{
				if(chanel!=null){
					proccessBar.value=chanel.position*(100/sound.length);
					playTime.text=formatTime(chanel.position) + "/" + totalTime;
					if(proccessBar.value>99){
						musStop();
					}
				}
			}
			
			//鼠標拖動進度條更改播放進度的處理
			private function changePos():void{
				if(chanel!=null){
					chanel.stop();
					//完成自動播放
					playState=1;
					chanel = sound.play(proccessBar.value*sound.length/100);
					chanel.soundTransform=vol;			
					this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
					playBtn.visible=false;
					pauseBtn.visible=true;
					pState.text = "狀態: 播放";
				}
			}
			
			//時間格式處理
			private function formatTime(time:Number):String{
				var s:String;
				var m:Number = Math.floor(time / 60000);//分鐘
				if(m >= 60){
					//小時
					var h:Number = Math.floor(m / 60);
					if (h < 10)
						s = "0" + h;
					else
						s = String(h);
					
					//分鐘
					m = m - h*60;
					if (m < 10)
						s += ":0" + m;
					else
						s += ":" + String(m);
				}else{
					if (m < 10)
						s = "0" + m;
					else
						s = String(m);
				}
				
				m = Math.floor((time / 1000 ) % 60)
				if (m < 10)
					s += ":0" + m;
				else
					s += ":" + m;
				
				return s;
			}
			
			//從Url中得到參數,得到   ? 以後的所有
			private function getParams():Object {
				params = {};
				//獲取整個URI
				var query:String = ExternalInterface.call("window.location.search.substring", 1);
				var url:String = ExternalInterface.call("window.location.href.toString", 1);
				var index:int = url.indexOf("dsas")
				serverIP = url.substring(0,index-1);
				
				if(query) {
					var pairs:Array = query.split("&");
					for(var i:uint=0; i < pairs.length; i++) {
						var pos:int = pairs[i].indexOf("=");
						if(pos != -1) {
							var argname:String = pairs[i].substring(0, pos);
							var value:String = pairs[i].substring(pos+1);
							params[argname] = value;
						}
					}
				}
				return params;
			}
			
			//下載語音文件
			private function downLoadsVoice():void{
				var args:Object = getParams();      //獲取URL中的參數列表
				var fileName:String = args.audio;
				var file:String = serverIP + fileName + ".mp3";//得到語音文件名
				var urlReq:URLRequest = new URLRequest(file);  
				var fileRef:FileReference = new FileReference(); 
				var index:int = fileName.indexOf("voice/");
				var tempFile:String = fileName.substring(index+6,fileName.length)+".mp3";
				fileRef.download(urlReq,tempFile);
			}
		]]>
	</fx:Script>
	
	<s:Panel id="panel" x="1.3" y="1.35" width="806" height="302" title="乘務員標準化作業語音監控系統" 
			 backgroundColor="#448FF5" backgroundAlpha="0.72" >
		
		<s:Label x="738" y="-24" text="狀態:暫停" id="pState" color="#FF0404" fontWeight="bold"/>
		
		<s:BorderContainer x="2" y="2" width="800" height="200" id="box" backgroundColor="#0211D6">
			<s:Label x="260" y="84" text="語音加載完成後自動播放,請稍後..." id="load" fontSize="20" color="#FC0000" fontWeight="bold" fontStyle="italic" fontFamily="Courier New"/>
		</s:BorderContainer>
		
		<s:BorderContainer id="bufferRect" x="1" y="210" width="7" height="7" buttonMode="true" borderColor="red" backgroundColor="red">
		</s:BorderContainer>
		
		<s:HSlider x="1" y="207" width="801" id="proccessBar" change="changePos()" 
				   minimum="0" maximum="100" snapInterval="0.1" liveDragging="true" 
				   showDataTip="false" height="13" alpha="0.5" buttonMode="true"/>
		
		<mx:Image x="6" y="227" source="assets/play.png" id="playBtn"/>
		<mx:Image x="6" y="227" source="assets/pause.png" id="pauseBtn" visible="false"/>
		<mx:Image x="56" y="227" source="assets/stop.png" id="stopBtn" click="musStop()"/>
		<mx:Image x="106" y="227" source="assets/volume.png" id="soundBtn"/>
		<mx:Image x="106" y="227" source="assets/volumeJ.png" id="soundBtnJ" visible="false"/>
		<s:HSlider x="149" y="238" width="107" id="soundSlide" change="soundSlideChange()" minimum="0" maximum="5"/>
		<s:Label y="224" right="1" text="00:00" id="playTime"/>
		<s:Button x="758" y="247" label="下載" width="46" click="downLoadsVoice()" id="dl"/>
	</s:Panel>
</s:Application>
 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章