flex视频\声音录制及播放
<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" height="312" width="328" creationComplete="init()"><mx:Script> <![CDATA[ //预定义声明 import mx.controls.Alert; import mx.events.SliderEvent; //创建一个基本的网络连接对象 private var vi:Video; private var cam:Camera; //定义一个摄像头 private var inNs:NetStream; private var outNs:NetStream; private var nc:NetConnection; //private var mic:Microphone; //定义一个麦克风 private var _duration:Number; //视频播放时间 private var playPosition:Number; //定义播放进度位置 //private var soundPosition:Number; //定义声音大小控制条的位置 private var flag:Boolean = false; private var lastVideoName:String = ""; //视频录制后保存的名字 private var _url:String = "rtmp://127.0.0.1:1935/videoRec"; public function init():void{ setupCamera(); //初始化摄像头信息 } //开始录制按扭点击 public function clickConnect():void{ nc = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS,nsHandler); nc.connect(_url); //连接red5服务器 } public function nsHandler(evt:NetStatusEvent):void{ if (evt.info.code == "NetConnection.Connect.Success"){ //如果连接成功 playClick(); }else{ Alert.show("连接失败"); } } //开始录制 public function playClick():void{ if(vi != null){ vi.clear(); vdisplay.removeChild(vi); vi = new Video(); vi.width = 320; vi.height = 240; vi.attachCamera(cam); vdisplay.addChild(vi); } outNs = new NetStream(nc); outNs.attachCamera(cam); //把摄像头存入outNs //outNs.attachAudio(mic); //把麦克风存入outNs lastVideoName = "red5RecordDemo_" + Math.random()+getTimer(); outNs.publish(lastVideoName, "record"); startRec.enabled = false; stopRec.enabled = true; } //停止录制 public function stopClick():void{ //关闭ns与red5的连接 outNs.close(); vi.clear(); vdisplay.removeChild(vi); //锁定开始按键使其生效 startRec.enabled = true; //锁定停止按键使其失效 stopRec.enabled = false; } //录制完以后播放 public function playLastVideo():void{ if(nc!=null){ //addEventListener(Event.ENTER_FRAME,onEnterFrame); inNs = new NetStream(nc); //定义onMetaData,获取视频相关数据 var customClient:Object = new Object(); customClient.onMetaData = function(metadata:Object):void{ _duration = metadata.duration; //获取视频持续时间 t_sh.maximum = _duration; } inNs.client = customClient; //删除原_localVideo,便于在录制和播放视频之间切换 vi = new Video(); vi.width = 320; vi.height = 240; vi.attachNetStream(inNs); vdisplay.addChild(vi); inNs.play(lastVideoName+".flv"); addEventListener(Event.ENTER_FRAME,onEnterFrame); } } //初始化摄像头 public function setupCamera():void{ //启动摄像头 cam = Camera.getCamera(); if(cam != null){ cam.addEventListener(StatusEvent.STATUS,onStatusHandler); cam.setMode(320,240,30); cam.setQuality(0,70); //设置清晰度 vi = new Video(); vi.width = 320; vi.height = 240; vi.attachCamera(cam); vdisplay.addChild(vi); }// mic = Microphone.getMicrophone();// if(mic != null){// mic.setSilenceLevel(0,-1); //设置麦克风保持活动状态并持续接收集音频数据// mic.gain = 80; //设置麦克风声音大小// } } private function onStatusHandler(event:StatusEvent):void{ if(!cam.muted){ //判断摄像头存不存在 startRec.enabled = true; }else{ Alert.show("错误:无法链接到活动摄像头!") } cam.removeEventListener(StatusEvent.STATUS,onStatusHandler); } public function thumbPress(event:SliderEvent):void{ inNs.togglePause(); removeEventListener(Event.ENTER_FRAME,onEnterFrame); } private function thumbChanges(event:SliderEvent):void{ playPosition = t_sh.value; //当前播放视频进度的位置=当前播放进度条的位置 inNs.seek(playPosition); addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function thumbRelease(event:SliderEvent):void{ //释放mouse后执行 inNs.seek(playPosition); //查找当前进度条位置 inNs.togglePause(); addEventListener(Event.ENTER_FRAME,onEnterFrame); } public function onEnterFrame(event:Event):void{ if(_duration > 0 && inNs.time > 0){ //如果视频时间和正在播放视频的时间大于0 t_sh.value =inNs.time; lbtime.text = formatTimes(inNs.time) + " / "+ formatTimes(_duration); } if(formatTimes(inNs.time)==formatTimes(_duration)){ //如果播放完毕,则关毕流,初始化摆放时间的label if(flag==true){ //如果是加载,就不执行 ||false代表是加载,true代表是播放结束 removeEventListener(Event.ENTER_FRAME,onEnterFrame); inNs.close(); lbtime.text = "0:00 / "+ formatTimes(_duration); } setTimeout(function():void{flag = true;},1000); } } //时间格式操作 private function formatTimes(value:int):String{ var result:String = (value % 60).toString(); if (result.length == 1){ result = Math.floor(value / 60).toString() + ":0" + result; } else { result = Math.floor(value / 60).toString() + ":" + result; } return result; } //声音音量控制// private function sound_thumbChanges(event:SliderEvent):void{// soundPosition = th_sound.value;// }// private function sound_thumbRelease(event:SliderEvent):void{// vdisplay.volume = soundPosition;// } ]]></mx:Script> <mx:VideoDisplay x="0" y="0" width="324.5" height="240" id="vdisplay"/> <mx:Button x="10" y="250" label="开始录制" id="startRec" click="clickConnect()" enabled="false" /> <mx:Button x="10" y="280" label="停止录制" width="70" id="stopRec" click="stopClick()" enabled="false" /> <mx:Button x="253" y="268" label="播放" click="playLastVideo()" /> <mx:HSlider x="98" y="248" width="143" id="t_sh" thumbPress="thumbPress(event)" thumbRelease="thumbRelease(event)" change="thumbChanges(event)"/> <mx:Label x="237" y="242" text="0:00/0:00" width="89" textAlign="center" height="18" id="lbtime"/> <!--mx:HSlider x="98" y="278" width="91" id="th_sound" minimum="0" maximum="1" value="{vdisplay.volume}" change="sound_thumbChanges(event)" thumbRelease="sound_thumbRelease(event)"/> <mx:Label x="187" y="270" text="sound" height="20" width="44" textAlign="center"/--> </mx:Application>注:1.red5做服务器,后面代码其实什么也没有,最关键的还是前端flex代码,当然还有些配置问题,相信做过red5 simple demo的朋友应该知道,在这就不一一细说了.2.文章中注释地方是音频的录制,因为本机上无麦克风所以就屏掉了。如果要加上些功能,去掉注释即可。3.以下是前端显示图