在一些实时视频或视频分享应用中,需要动态显示麦克风的音量大小,或者检测视频是不是正在播放,这里演示一种简单的音量指示器
1.先写一个指示器类
其实就是一个根据百分比来填充的矩形
package { import flash.display.Sprite; //音量指示器(by 菩提树下的杨过 http://yjmyzz.cnblogs.com/) public class Indicator extends Sprite { private var _w:uint; private var _h:uint; private var _bColor:uint; private var _bgColor:uint; private var _fColor:uint; private var _current:Number; public function Indicator(w:uint=150,h:uint=15,borderColor:uint=0x000000,bgColor:uint=0xffffff,fillColor:uint=0xff6600,current:Number=0.3):void { //trace("Indicator"); this._w=w; this._h=h; this._bColor=borderColor; this._bgColor=bgColor; this._fColor=fillColor; this._current=current; if (_current>=1) { _current=1; } else if (_current<=0) { _current=0; } init(); } public function set Current(v:Number):void { _current=v; if (_current>=1) { _current=1; } else if (_current<=0) { _current=0; } init(); } public function get Current():Number { return (_current); } private function init():void { graphics.clear(); graphics.lineStyle(1,_bColor); //先画背景色 graphics.beginFill(_bgColor); graphics.drawRect(-1*_w/2,-1*_h/2,_w,_h); graphics.endFill(); //再画当前值 graphics.lineStyle(1,_bColor,0); graphics.beginFill(_fColor); var _per:Number=_w*_current; graphics.drawRect(-1*_w/2 +0.5 ,-1*_h/2 +0.5,_per,_h-1); graphics.endFill(); } } }
2.如何获取音量大小以及监测摄像头直播状态
音量大小可以通过activityLevel属性获得,但摄像头的画面变化程度却无法直接获取,但每当摄像头画面有活动时ACTIVITY事件将被触发,所以可在该事件中监测最后一次活动的时间与当前时间做比较,从而判断画面有多久没有变化了。
var videoInd:Indicator=new Indicator(100,10,0x000000,0xffffff); var audioInd:Indicator=new Indicator(100,10,0x000000,0xffffff); addChild(videoInd); addChild(audioInd); //初始化视频/音频指示器位置 videoInd.x=stage.stageWidth/2 + 30; videoInd.y=-100; audioInd.x=stage.stageWidth/2 + 30; audioInd.y=-100; txtMsg.y = stage.stageHeight/2 - txtMsg.height/2; txtMsg.width = stage.stageWidth; var cam:Camera; var mic:Microphone; var video:Video; var videoIsWorked=false; var lastVideoActiveData:Date = new Date(); var timer:Timer = new Timer(100,20);//每隔100ms检测摄像头状态,一共检测20次 function startCheckVideo() { cam=Camera.getCamera(); if (cam==null) { txtMsg.text="未安装摄像头!"; return; } cam.addEventListener(StatusEvent.STATUS, statusHandler); cam.addEventListener(ActivityEvent.ACTIVITY,camActivityHandler); video=new Video(cam.width,cam.height); //trace("视频宽度:" + cam.width + ",视频高度:" + cam.height); video.height = 120; video.width = 160; video.x=stage.stageWidth/2-video.width/2; video.y=10; video.attachCamera(cam);//执行这句时,flash才会弹出摄像头是否允许使用提示框 } //摄像头有活动时,被触发 function camActivityHandler(e:ActivityEvent) { //trace("camActivityHandler:" + new Date().toString()); if (!videoIsWorked) { timer.addEventListener(TimerEvent.TIMER,TimerHandler); timer.addEventListener(TimerEvent.TIMER_COMPLETE,timerCompleteHandler); timer.start(); } lastVideoActiveData = new Date();//记录本次视频活动时间 } //回调函数 function TimerHandler(e:TimerEvent):void { txtMsg.text="摄像头视频获取中..." ; if (cam.currentFPS>0) { timer.stop(); addChild(video);//加载到当前舞台中 videoInd.y=video.y+video.height+10; audioInd.y=videoInd.y + videoInd.height + 10; txtVideo.text = "视频状态:" txtVideo.y = videoInd.y - 8 txtVideo.x = videoInd.x - videoInd.width -20 ; txtAudio.text = "音频状态:" txtAudio.y = audioInd.y - 8 txtAudio.x = audioInd.x - audioInd.width -20 ; if (txtMsg!=null) { removeChild(txtMsg); } videoIsWorked=true; //摄像头工作正常 this.addEventListener(Event.ENTER_FRAME,EnterFrameHandler); } } function timerCompleteHandler(e:TimerEvent):void{ txtMsg.text="设备无法使用(有可能被占用)"; } //用户选择"同意"或"不允许"使用摄像头时触发 function statusHandler(e:StatusEvent) { if (e.code=="Camera.Muted") { txtMsg.text="您不允许使用摄像头!"; } else if (e.code == "Camera.Unmuted") { txtMsg.text="摄像头视频获取中..."; camActivityHandler(null);//重要:在release模式下,webCam的Activity事件不会自动触发(Adobe的bug?),所以要显式手动调用一次 } } //开始检测麦克风 function startCheckAudio():void{ mic = Microphone.getMicrophone(); mic.setLoopBack(true);//将采集到的声音回发到扬声器(否则自己听不到自己的声音,不方便测试) } function EnterFrameHandler(e:Event):void{ var curDate:Date = new Date(); var _timeSpan:Number = curDate.time - lastVideoActiveData.time; if (_timeSpan >= 30 * 1000){ trace("您的视频已经超过30秒没动静了!"); videoInd.Current = 0; } else{ videoInd.Current = Math.random() * 0.1;//视频指示器 } if (mic!=null){ audioInd.Current = 0.05 + mic.activityLevel/100;//音量指示器 } } txtMsg.text="正在检测摄像头..."; startCheckVideo(); startCheckAudio();