Flash/Flex学习札记(24):摄像头/麦克风的视频/音量指示器
在一些实时视频或视频分享应用中,需要动态显示麦克风的音量大小,或者检测视频是不是正在播放,这里演示一种简单的音量指示器
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);
3
//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();