简易的 Flex 3.0 流媒体播放器

前段时间做了个 Flex 的小项目,项目中需要流媒体播放器,参考了一些资料,自己做了一个,现发布出来与大家分享

直接上代码:

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="710" height="445"
	 backgroundColor="#000000" creationComplete="completeHandler()"
	 horizontalScrollPolicy="off" verticalScrollPolicy="off">
	<mx:Script>
        <![CDATA[
        	import mx.collections.ArrayCollection;
        	import com.doc.view.docmanager.player.helper.PlayItem;
        	import com.doc.view.docmanager.player.helper.PlayList;
        	import mx.events.FlexEvent;
        	import mx.events.MetadataEvent;
            import mx.events.SliderEvent;
            import mx.core.UIComponent;
            import mx.controls.Alert;
            import mx.utils.StringUtil;
            
            private var _source:String;
            private var _autoPlay:Boolean;
            public var videoWidth:Number = 0;
            public var videoHeight:Number = 0;
            private var nc:NetConnection;
            
            [Bindable] 
            private var ns:NetStream;
            
            private var videoContainer:UIComponent;
            private var video:Video;
            private var rtmpUrl:String;
            private var fileName:String;
            private var timer:Timer;
            private var totalTime:Number;
            
            
            //播放列表
            private var _playList:PlayList;
            //当前播放视频的索引
            private var _currentIndex:int = 0;
            
            
            //用来控制音量的临时变量
            private var volumn:SoundTransform = new SoundTransform();
            //NetStream 对象所引用的client的对象
            private var nsClient:Object;
            //是否已经初始化
            private var isInit:Boolean = false;
            //是否在暂停状态
            private var isPause:Boolean = false;
            //是否在播放状态
            private var isPlay:Boolean = false;
            //是否静音
            private var isMute:Boolean = false;
            //临时保存音量
            private var tmpVolumn:Number = 5;
            
            /*图标定义*/
            //播放
            [Embed(source="assets/player/play.jpg")]
            [Bindable]
            private var playImage:Class;
            [Embed(source="assets/player/play_over.jpg")]
            [Bindable]
            private var playOverImage:Class;
            
            //暂停
            [Embed(source="assets/player/pause.jpg")]
            [Bindable]
            private var pauseImage:Class;
            [Embed(source="assets/player/pause_over.jpg")]
            [Bindable]
            private var pauseOverImage:Class;
            
            //停止
            [Embed(source="assets/player/stop.jpg")]
            [Bindable]
            private var stopImage:Class;
            [Embed(source="assets/player/stop_over.jpg")]
            [Bindable]
            private var stopOverImage:Class;
            
             //上一个
            [Embed(source="assets/player/previous.jpg")]
            [Bindable]
            private var previousImage:Class;
            [Embed(source="assets/player/previous_over.jpg")]
            [Bindable]
            private var previousOverImage:Class;
            
             //下一个
            [Embed(source="assets/player/next.jpg")]
            [Bindable]
            private var nextImage:Class;
            [Embed(source="assets/player/next_over.jpg")]
            [Bindable]
            private var nextOverImage:Class;
            
            //音量
            [Embed(source="assets/player/sound.jpg")]
            [Bindable]
            private var soundImage:Class;
            [Embed(source="assets/player/sound_over.jpg")]
            [Bindable]
            private var soundOverImage:Class;
            
            //静音
            [Embed(source="assets/player/mute.jpg")]
            [Bindable]
            private var muteImage:Class;
            [Embed(source="assets/player/mute_over.jpg")]
            [Bindable]
            private var muteOverImage:Class;
            
            
            // 设置flv地址,rtmp和http都支持,绝对路径
            public function set playList(playList:PlayList):void{ 
				this._playList = playList;
				var data:ArrayCollection = new ArrayCollection();
				for(var i:int = 0; i < playList.size(); i++)
				{
					data.addItem(this._playList.getItem(i).name);
				}
				this.videoList.dataProvider = data;
				setCurrentIndex(0);
            }
            
            //设置当前播放的索引
            private function setCurrentIndex(index:int):void
            {
            	if(this._playList.validIndex(index))
            	{
            		this._currentIndex = index;
            	}
            	else
            	{
            		if(index >= _playList.size())
            		{
            			this._currentIndex = 0;
            		}
            		else
            		{
            			this._currentIndex = _playList.size() - 1;
            		}
            	}
            	this.videoList.selectedIndex = _currentIndex;
            	setSource(this._playList.getItem(this._currentIndex));
            }
            
            //设置当前的播放文件
            private function setSource(playItem:PlayItem):void
            {
            	var beginIndex:int;
                var endIndex:int;
                this._source = playItem.url;
                if(playItem.url.indexOf("rtmp") == 0){
	                endIndex = this._source.lastIndexOf("/");
		            this.rtmpUrl = this._source.substring(0, endIndex);
		            beginIndex = endIndex;
		            endIndex = this._source.lastIndexOf(".");
		            this.fileName = this._source.substring(beginIndex + 1, endIndex);
	            }
	            else{
	            	this.rtmpUrl = null;
	                this.fileName = playItem.url;
	            }
                if(this._autoPlay){
                    this.play();
                }
            }
            
            public function get source():String{
                return this._source;
            }
            
            public function set autoPlay(auto:Boolean):void{
                this._autoPlay = auto;
            }
            
            public function get autoPlay():Boolean{
                return this._autoPlay;
            }
            
            //初始化完毕后设置video对象的大小,要把video对象加入到Flex的UI控件中,必须先用UIComponent或其子类包装。
            private function completeHandler():void{ 
                this.video = new Video();
                this.video.width = this.width * 0.7;
                this.video.height = this.height - this.controlBar.height - this.sliderBar.height;
                this.videoContainer = new UIComponent();
                this.videoContainer.addChild(this.video);
                this.videoBox.addChild(this.videoContainer);
                
                this.videoContainer.addEventListener(MouseEvent.CLICK, videoClickHandler);
                this.isPause = false;
                
                this.addEventListener(FlexEvent.EXIT_STATE, function():void{
                	close();
                });
                
                if(this._autoPlay){
                	this.isPlay = true;
                    changeImage(1);
                    showTip0("正在播放");
                }
                else{
                	this.isPlay = false;
                    changeImage(1);
                    showTip0("可以开始播放");
                }
            }
            
            private function init():void{
                if(StringUtil.trim(this._source) != ""){
                    this.nc = new NetConnection();
                    this.nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
                    this.nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
                    this.nc.connect(this.rtmpUrl);
                    connectStream();
                    this.isInit = true;
                }
            }
            
            private function connectStream():void{
            	this.nsClient = new Object();
            	this.nsClient.onMetaData = metaDataHandler;
            	this.nsClient.onCuePoint = cuePointHandler;
            	
                this.ns = new NetStream(this.nc);
                this.ns.bufferTime = 15;
                this.ns.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                this.ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
                this.ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
                showTip(this.fileName);
                this.ns.play(this.fileName);
                this.ns.client = this.nsClient;
                
                //设置声音
                resetVolumn();
                this.video.attachNetStream(this.ns);
            }
            
            private function netStatusHandler(event:NetStatusEvent):void{
                switch(event.info.code){
                    case "NetConnection.Connect.Success":
                        showTip0("连接成功");
                        break;
                       
                    case "NetConnection.Connect.Rejected":
                        showTip0("没有访问权限");
                        this.slider.setThumbValueAt(0, 0);
                        this.isPause = false;
		                this.isPlay = false;
		                changeImage(1);
                        break;
                    case "NetStream.Play.StreamNotFound":
                        showTip0("找不到文件");
                        this.slider.setThumbValueAt(0, 0);
		                this.isPause = false;
		                this.isPlay = false;
		                changeImage(1);
                        break;
                    case "NetStream.Play.Stop":
                    	this.isPause = false;
                    	this.isPlay = false;
                    	changeImage(1);
//                    	showTip0("已停止");
						next();
                    	break;
                    case "NetStream.Buffer.Empty":
                    	showTip0("正在缓冲");
                    	break;
                    case "NetStream.Buffer.Full":
                    	if(isPlay)
                    	{
                    		showTip0("正在播放");
                    	}
                    	break;
                }
            }
            
            //IO 错误
            private function ioErrorHandler(event:IOErrorEvent):void{
            }
            
            //安全错误
            private function securityErrorHandler(event:SecurityErrorEvent):void{
            }
            
            //同步错误
            private function asyncErrorHandler(event:AsyncErrorEvent):void{
            }
            
            //当获得媒体数据时,开始监听enterFrame事件,该事件是不断发生的,在该事件的handler中更新进度条
            private function metaDataHandler(info:Object):void{
            	this.slider.enabled = true;
                this.totalTime = info.duration;
                this.slider.maximum = this.totalTime;
                this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                this.volumnSlider.setThumbValueAt(0, this.ns.soundTransform.volume * 10);
            }
            
            private function enterFrameHandler(event:Event):void{ //在该事件中不断更新进度条的位置
                this.slider.setThumbValueAt(0, this.ns.time);
                showTip(formatTime(this.ns.time) + "/" + formatTime(this.totalTime));
            }
            
            private function cuePointHandler(info:Object):void{
                 showTip0("cuepoint: time=" + info.time + " name=" + info.name + " type=" + info.type);
            }
            
            //播放当前文件
            public function play():void{
                this.init();
                
                try{
                    this.ns.close();
                    this.ns.play(this.fileName);
                }
                catch(error:Error){
                    showTip0("发生错误:" + error.message);
                    this.isPause = false;
                	this.isPlay = false;
                	changeImage(1);
                }
                this.isPause = false;
                this.isPlay = true;
                changeImage(1);
                showTip0("正在播放");
            }
            
            //播放上一个
            public function previous():void
            {
            	setCurrentIndex(this._currentIndex - 1);
            }
            
            //播放下一个
            public function next():void
            {
            	setCurrentIndex(this._currentIndex + 1);
            }
            
            //单击视频,实现播放暂停
            private function videoClickHandler(event:MouseEvent):void{
                this.playPause();
            }
            
            //播放 or 暂停
            private function playPause():void{
                if(isPlay)
            	{
	                if(isPause){
	                	this.isPause = false;
	                    changeImage(1);
	                    this.ns.resume();
	                    showTip0("正在播放");
	                }
	                else{
	                    this.ns.pause();
	                    this.isPause = true;
	                    changeImage(1);
	                    showTip0("已暂停");
	                }
                }
                else
                {
                	this.play();
                }
            }
            
            //停止播放
            private function stop():void{
                this.ns.seek(0);
                this.ns.pause();
                this.slider.setThumbValueAt(0, 0);
                this.isPause = false;
                this.isPlay = false;
                changeImage(1);
                showTip0("已停止");
            }
           
           //拖拽进度滑块
           private function thumbDragHandler():void{ //拖拽进度条时,删除对enterFrame事件的监听,以便使此时的进度条与播放头脱离
                  if(!this.ns) return;
                  this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
           }
           
           //释放进度滑块
           private function thumbReleaseHandler():void{ //拖拽释放后,根据进度条该点的值让视频的播放头跳到该时间点
                  if(!this.ns) return;
                  this.ns.seek(slider.value);
                  this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
           }
           
           //调整音量事件
           private function volumnChangeHandler():void{ //视频音量控制
                  resetVolumn();
                  this.isMute = false;
                  this.mute.source = soundImage;
           }
           
           //重置NetStream的音量
           private function resetVolumn():void
           {
           		if(!this.ns) return;
           		volumn.volume = this.volumnSlider.value / 10;
                this.ns.soundTransform = volumn;
           }
           
           //格式化音量进度条的提示
           private function formatVolumnSliderTooltip(value:Number):String
           {
           		return (int(value * 10)) + "%";
           }
           
           //格式化播放进度条的提示
           private function formatTime(value:Number):String
           {
           		var hour:int;
           		var minute:int;
           		var second:int;
           		
           		hour = int(value / 3600);
           		minute = int(value / 60) - hour * 60;
           		second = int(value % 60);
           		
           		if(hour > 0)
           		{
           			return (hour < 10 ? ("0" + hour) : hour) + ":" + (minute < 10 ? ("0" + minute) : minute) + ":" + (second < 10 ? ("0" + second) : second);
           		}
           		else
           		{
           			return (minute < 10 ? ("0" + minute) : minute) + ":" + (second < 10 ? ("0" + second) : second);
           		}
           }
           
           //关闭所有连接
           public function close():void
           {
           		if(this.ns) ns.close();
           		if(this.nc) nc.close();
           }
           
           //静音
           private function resetMute():void
           {
           		if(isMute)
           		{
           			this.volumnSlider.value = tmpVolumn;
           			mute.source = soundImage;
           			isMute = false;
           		}
           		else
           		{
           			this.tmpVolumn = this.volumnSlider.value;
           			this.volumnSlider.value = 0;
           			mute.source = muteImage;
           			isMute = true;
           		}
           		resetVolumn();
           }
           
           //全屏, 暂时不用
           private function fullScreen():void
           {
           		stage.displayState = (stage.displayState ==   
              		StageDisplayState.NORMAL?StageDisplayState.FULL_SCREEN:StageDisplayState.NORMAL); 
           }
           
           /*鼠标进入图标时,改变图标*/
           private function changeOverImage(type:int):void
           {
           		// 停止
           		if(type == 0)
           		{
           			this.stopBtn.source = stopOverImage;
           		}
           		//播放
           		else if(type == 1)
           		{
           			if(isPlay)
           			{
	           			if(isPause)
	           			{
	           				this.playPauseBtn.source = playOverImage;
	           			}
	           			else
	           			{
	           				this.playPauseBtn.source = pauseOverImage;
	           			}
           			}
           			else
           			{
           				this.playPauseBtn.source = playOverImage;
           			}
           		}
           		//音量
           		else if(type == 2)
           		{
           			if(isMute)
           			{
           				this.mute.source = muteOverImage;
           			}
           			else
           			{
           				this.mute.source = soundOverImage;
           			}
           		}
           		//上一个
           		else if(type == 3)
           		{
           			this.previousBtn.source = previousOverImage;
           		}
           		//下一个
           		else if(type == 4)
           		{
           			this.nextBtn.source = nextOverImage;
           		}
           }
           
           /*鼠标移出图标时,改变图标*/
           private function changeImage(type:int):void
           {
           		//停止
           		if(type == 0)
           		{
           			this.stopBtn.source = stopImage;
           		}
           		//播放
           		else if(type == 1)
           		{
           			if(isPlay)
           			{
           				if(isPause)
	           			{
	           				this.playPauseBtn.source = playImage;
	           			}
	           			else
	           			{
	           				this.playPauseBtn.source = pauseImage;
	           			}
           			}
           			else
           			{
           				this.playPauseBtn.source = playImage;
           			}
           			
           		}
           		//音量
           		else if(type == 2)
           		{
           			if(isMute)
           			{
           				this.mute.source = muteImage;
           			}
           			else
           			{
           				this.mute.source = soundImage;
           			}
           		}
           		//上一个
           		else if(type == 3)
           		{
           			this.previousBtn.source = previousImage;
           		}
           		//下一个
           		else if(type == 4)
           		{
           			this.nextBtn.source = nextImage;
           		}
           }
           
           //显示提示信息
           private function showTip(msg:String):void
           {
           		this.timpTip.text = msg;
           }
           
           //另一处提示信息
           private function showTip0(msg:String):void
           {
           		this.timpTip0.text = msg;
           }
        ]]>
    </mx:Script>
    <mx:Canvas width="100%" height="100%" x="0" y="0">
    	<mx:Canvas id="playArea" width="500" height="100%" x="-1" y="-1" horizontalScrollPolicy="off" verticalScrollPolicy="off"  borderColor="#FFFFFF" borderStyle="solid">
	    	<mx:Canvas id="videoBox" width="100%" x="0" y="0" height="360"
	    		 horizontalScrollPolicy="off" verticalScrollPolicy="off">
		    </mx:Canvas>
		    <mx:VBox id="sliderBar" y="360" height="18" width="100%" backgroundColor="#000000"
		        horizontalScrollPolicy="off" verticalScrollPolicy="off">
		        <mx:HSlider id="slider" width="498" minimum="0" snapInterval="1"
		        	 showTrackHighlight="true" liveDragging="true" thumbDrag="thumbDragHandler()"
		        	 thumbRelease="thumbReleaseHandler()" dataTipFormatFunction="formatTime"
		        	  allowTrackClick="false" y="420" trackColors="[0xEEEEEE,0x0000FF]" enabled="false">
		        </mx:HSlider>
		    </mx:VBox>
		    <mx:Canvas id="controlBar" width="100%" height="60" y="375" horizontalScrollPolicy="off" verticalScrollPolicy="off">
		    	 <mx:Image source="{stopImage}" id="stopBtn" click="stop()"
			     	 mouseOver="changeOverImage(0)" mouseOut="changeImage(0)"
			     	 width="32" height="32" x="7" y="14"/>
			     
			     <mx:Image source="{previousImage}" id="previousBtn" click="previous()"
			     	 mouseOver="changeOverImage(3)" mouseOut="changeImage(3)"
			     	 width="32" height="32" x="51" y="14"/>
			     
			     <mx:Image source="{playImage}" id="playPauseBtn" click="playPause()"
		    		 mouseOver="changeOverImage(1)" mouseOut="changeImage(1)"
		    		 width="64" height="64" x="85" y="-3"/>
			     
			     <mx:Image source="{nextImage}" id="nextBtn" click="next()"
			     	 mouseOver="changeOverImage(4)" mouseOut="changeImage(4)"
			     	 width="32" height="32" x="152" y="14"/>
			     
			     <mx:Label id="timpTip0" width="87" textAlign="center" x="188" y="22" color="#FFFFFF"/>
			     <mx:Label id="timpTip" width="115" textAlign="center" x="273" y="22" color="#FFFFFF"/>
			     <mx:Image id="mute" click="resetMute()" source="{soundImage}"
			     	 mouseOver="changeOverImage(2)" mouseOut="changeImage(2)"
			     	 width="32" height="32" x="392" y="14"/>
			     <mx:HSlider id="volumnSlider" width="75" value="2" minimum="0" maximum="10" snapInterval="0.1"
			     	 change="volumnChangeHandler()" liveDragging="true" x="421" y="18" dataTipFormatFunction="formatVolumnSliderTooltip"/>
		    </mx:Canvas>
	    </mx:Canvas>
	    <mx:Canvas width="210" height="100%" x="500" y="0">
	    	<mx:VBox width="100%" height="20" y="5" horizontalAlign="center">
	    		<mx:Label textAlign="center" text="播放列表" color="#FFFFFF" width="79" fontFamily="宋体" fontSize="15" fontWeight="bold"/>
	    	</mx:VBox>
	    	<mx:List x="-1" y="25" width="209" height="420" backgroundColor="#000000" color="#FFFFFF" id="videoList" itemClick="{setCurrentIndex(this.videoList.selectedIndex)}"></mx:List>
	    </mx:Canvas>
    </mx:Canvas>
</mx:Canvas>

 

由于时间仓促,所以代码中还有很多可以优化的地方,现提供出来,仅供大家参考。

转载于:https://www.cnblogs.com/MichaelMa80/archive/2011/12/04/2275297.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值