论坛首页 编程语言技术论坛

Flex4实现 音频播放器 显示语音波形

浏览 5583 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-06-17  

直接上代码,在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>
 

 

 

 

 

  • 大小: 84 KB
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics