视频监控WEB观看端,用flash播放监控的视频的小例子
实现主要功能如下
1. 多屏切换,这里主要是tileLayout布局的使用
2. 单个视频双击全屏,整屏全屏
3. 右键菜单和屏蔽系统的右键菜单 主要是这个属性 params.wmode="transparent";
4. flex与JS的交互,(通过js向flex中传递视频播放地址)
1.swf预览图
2. 插入到html的预览图(根据大华的网页弄的一个样式)
3.FlashBuilder目录结构图
4.主应用(BXPlayer.mxml)
<?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"
xmlns:component="com.bx.component.*"
width="960" height="530" initialize="init(event)" >
<fx:Script>
<![CDATA[
import com.bx.component.FLVideo;
import com.bx.util.EventArgExtend;
import com.bx.util.FullScreenUtil;
import com.bx.util.RightClickManager;
import mx.controls.Alert;
import mx.controls.Menu;
import mx.core.UIComponent;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.events.MenuEvent;
//视频Vector数组
private var fVector:Vector.<FLVideo> = new Vector.<FLVideo>();
[Bindable]
private var sqrScreens:int = 1;
[Bindable]
private var text:String;
private function playVideo(videoHost:String, videoName:String):void{
for(var i:int = 0; i < fVector.length; i++){
var flv:FLVideo = fVector[i];
if(!flv.isConStream){
flv.init(videoHost, videoName);
break
}
}
}
protected var rightClickRegisted:Boolean = false;
//初始化
protected function init(event:FlexEvent):void
{
ExternalInterface.addCallback("playVideo",playVideo);
if (!rightClickRegisted)
{
RightClickManager.regist();
rightClickRegisted = true;
}
this.addFLVideo(49); //添加视频
flvContainer.addElement(fVector[0]); //初始化第一屏
}
//切换屏幕
protected function changeScreen(event:MouseEvent):void
{
//初始化选择框的位置
selectRect.width = 0;
selectRect.height = 0;
//获取几屏
var screen:int = int(Button(event.currentTarget).label);
sqrScreens = Math.sqrt(screen);
flvContainer.removeAllElements(); //删除所有元素
for(var i:int = 0; i < screen; i++){
var flVideo:FLVideo = fVector[i];
flVideo.toolTip = flVideo.name;
flvContainer.addElement(flVideo);
}
}
//初始化视频窗口
private function addFLVideo(num:int):void{
var flVideo:FLVideo = null;
for(var i:int = 0; i < num; i++){
flVideo = new FLVideo();
flVideo.name = "第" + i + "个";
flVideo.doubleClickEnabled = true; //允许双击
//视频双击全屏事件
flVideo.addEventListener(MouseEvent.DOUBLE_CLICK,dbFullScreen);
//视频单击事件
flVideo.addEventListener(MouseEvent.CLICK, flVideoClick);
//鼠标右键事件
flVideo.addEventListener(RightClickManager.RIGHT_CLICK, EventArgExtend.create(rightClickHandler,flVideo));
flVideo.addEventListener(MouseEvent.MOUSE_OVER, overHandle);
fVector.push(flVideo);
}
}
private var menu:Menu;
//控件右击事件
private function rightClickHandler(event:ContextMenuEvent, ...arg):void{
removeMenu();
initMenu(arg[0]);
}
//删除右键菜单
private function removeMenu():void
{
if(menu!=null)
{
menu.hide();
menu.removeEventListener(MenuEvent.ITEM_CLICK,menuItemSelected);
menu=null;
}
}
//生成右键菜单
private function initMenu(flVideo:FLVideo):void
{
menu = Menu.createMenu(this, createMenuItems(), false);
//menu.iconField="itemIcon";//右键菜单的图标
//menu.labelField="label"; //右键菜单的名称
menu.variableRowHeight = true;
menu.width=120;
menu.addEventListener(MenuEvent.ITEM_CLICK, EventArgExtend.create(menuItemSelected, flVideo)); //右键菜单的事件
var point:Point = new Point(mouseX,mouseY);
point = localToGlobal(point);
menu.show(point.x,point.y); //显示右键菜单
}
//创建菜单项
private function createMenuItems():Array
{
var menuItems:Array = new Array();
var menuItem1:Object = new Object;
menuItem1.label = '查看URL'; //菜单项名称
//menuItem.itemIcon = this.menu_SX;//菜单项图标
var menuItem2:Object = new Object;
menuItem2.label = '关闭'; //菜单项名称
menuItems.push(menuItem1);
menuItems.push(menuItem2);
return menuItems;
}
//菜单项点击事件
private function menuItemSelected(event:MenuEvent, ...arg):void
{
var menuItem:Object = event.menu.selectedItem as Object;
var flVideo:FLVideo = arg[0];
if(flVideo.isConStream){
switch(menuItem.label){
case "查看URL":
Alert.show("视频URL: " + flVideo.videoHost + "/" + flVideo.videoName)
break;
case "关闭":
flVideo.close();
break;
}
}
}
private function dbFullScreen(event:MouseEvent):void{
this.fullScreen(event.currentTarget as UIComponent);
}
//全屏代码
private function fullScreen(displayObject:UIComponent):void{
if(FullScreenUtil.isFullScreen){
FullScreenUtil.exitFullScreen();
//初始化选择框的位置
selectRect.width = 0;
selectRect.height = 0;
}else{
FullScreenUtil.goFullScreen();
// 加入要全屏的对像.videoDisplay
FullScreenUtil.addChild(displayObject, true, true, true);
}
}
//点击视频窗口的时候重新画一个矩形包围视频
private var closeVideo:FLVideo;
private function flVideoClick(event:MouseEvent):void{
var obj:FLVideo = event.currentTarget as FLVideo;
selectRect.x = obj.x + 2;
selectRect.y = obj.y + 2;
selectRect.width = obj.width;
selectRect.height = obj.height;
closeVideo = obj;
}
private function overHandle(event:MouseEvent):void{
text = event.currentTarget.name + ": (" + event.currentTarget.x + "," + event.currentTarget.y + "),(" + event.currentTarget.width
+ "," + event.currentTarget.height + ")";
}
private function close(event:MouseEvent):void
{
Alert.show(flvContainer.numChildren + "," + flvContainer.numElements);
}
protected function clickPlay(event:MouseEvent):void
{
// TODO Auto-generated method stub
closeVideo.init("rtmp://42.121.0.108:9122/RpServer", "S1304180142");
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visualelements (e.g., services, value objects) here -->
</fx:Declarations>
<s:BorderContainer id="flvContainer" width="960" height="480" backgroundColor="#000000"
borderWeight="2" borderColor="#000000">
<s:layout>
<s:TileLayout verticalGap="2" horizontalGap="2" requestedColumnCount="{sqrScreens}" requestedRowCount="{sqrScreens}" columnAlign="justifyUsingWidth" rowAlign="justifyUsingHeight"/>
</s:layout>
</s:BorderContainer>
<s:BorderContainer id="bd" y="480" width="960" height="50" borderVisible="false" backgroundColor="#E9E8EA">
<s:HGroup x="5" y="5">
<s:Button name="one" label="1" click="changeScreen(event)"/>
<s:Button name="two" label="4" click="changeScreen(event)"/>
<s:Button name="three" label="9" click="changeScreen(event)"/>
<s:Button name="four" label="16" click="changeScreen(event)"/>
<s:Button name="five" label="25" click="changeScreen(event)"/>
<s:Button name="six" label="36" click="changeScreen(event)"/>
<s:Button name="six" label="49" click="changeScreen(event)"/>
<!--<s:Button name="six" label="64" click="changeScreen(event)"/>
<s:Button name="six" label="81" click="changeScreen(event)"/>-->
<s:Button label="全屏" click="fullScreen(flvContainer);"/>
<s:Button label="播放" click="clickPlay(event)"/>
<s:Label id="label" text="{text}"/>
</s:HGroup>
</s:BorderContainer>
<s:Rect id="selectRect">
<s:stroke>
<s:SolidColorStroke color="0xffdd22" weight="2"/>
</s:stroke>
</s:Rect>
</s:Application>
5.组件(FLVideo.mxml)
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
private var conn:NetConnection;
private var stream:NetStream;
private var video:Video;
[Bindable]
private var _videoHost:String = ""; //视频服务器地址
[Bindable]
private var _videoName:String = ""; //视频名称
[Bindable]
private var visibleFlag:Boolean = false;
public var isConStream:Boolean = false;
public function set videoHost(host:String):void{
this._videoHost = host;
}
public function get videoHost():String{
return this._videoHost;
}
public function set videoName(name:String):void{
this._videoName = name;
}
public function get videoName():String{
return this._videoName;
}
//用于主应用程序调用初始化连接
public function init(videoHost:String, videoName:String):void
{
// TODO Auto-generated method stub
_videoName = videoName;
_videoHost = videoHost;
conn=new NetConnection;
conn.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
conn.client = this;
conn.connect(videoHost); //连接Red5服务器
}
public function close():void{
if(conn != null){
conn.close();
}
if(stream != null){
stream.close();
}
if(video != null){
video.clear();
}
isConStream = false;
}
private function securityErrorHandler(event:SecurityErrorEvent):void{
}
private function asyncErrorHandler(event:AsyncErrorEvent):void{
}
public function onBWCheck(... arg):void
{
//do nothing
}
public function onBWDone(... arg):void {
}
public function onMetaData(obj:Object):void{
trace(obj.duration);
}
private function netStatusHandler(event:NetStatusEvent):void{
trace(event.info.code);
switch(event.info.code)
{
case "NetConnection.Connect.Success":
{
visibleFlag = true; //连接成功时缓冲设为可见
connectStream();
break;
}
case "NetStream.Play.StreamNotFound":{
Alert.show("文件不存在!","提示");
break;
}
case "NetStream.Buffer.Full":{
visibleFlag = false; //缓冲到可以播放隐藏
break;
}
case "NetStream.Buffer.Empty":{
visibleFlag = true; //获取不到缓冲流的时候显示
break;
}
case "NetConnection.Connect.Closed":{
visibleFlag = false; //关闭连接的时候显示
break;
}
}
}
private function connectStream():void{
stream=new NetStream(conn);
stream.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler);
stream.client = {}; //这句一定要,不然报错找不到onMetaData方法
stream.bufferTime = 1;
video = new Video(); //定义一个播放器
video.width = vd.width;
video.height = vd.height;
video.smoothing = true;
video.attachNetStream(stream);
stream.play(_videoName);
isConStream = true; //连接播放成功设为true
vd.addChild(video);
}
protected function vd_resizeHandler(event:ResizeEvent):void
{
// TODO Auto-generated method stub
if(video != null){
video.width = vd.width;
video.height = vd.height;
// swfLoader.width =
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<mx:VideoDisplay id="vd" width="100%" height="100%" contentBackgroundColor="0x666666" resize="vd_resizeHandler(event)"/>
<s:SWFLoader horizontalCenter="2" verticalCenter="2"
id="swfLoader" source="com/bx/assets/loading1.swf" width="65" height="55" visible="{visibleFlag}"/>
</s:Group>
说明:在源代码bin-debug文件夹中有bx文件夹,这个文件夹就是上面那个html预览页,打开index.html就可以看到预览图,视频地址是测试的例子