`
zyn010101
  • 浏览: 324527 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

flex + red5实现视频会议

阅读更多

      公司最近要在系统中加视频会议的功能,让我探索,我选择了最流行的red5来实现,网上有一对一聊天的demo,找不到多对多聊天的,也没有具体介绍系统搭建的过程,我通过自己的摸索,将实现的过程和大家一起分享。java的web项目添加flex支持在此不再详述,项目文件结构如图:




 
 


 web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
   version="2.4"
   xmlns="http://java.sun.com/xml/ns/j2ee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--
    ** For use with servlet v2.5 replace the lines above with these
    version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-->
	<display-name>Red5ChartRoom</display-name>

	<context-param>
		<param-name>globalScope</param-name>
		<param-value>default</param-value>
	</context-param>

	<context-param>
		<param-name>parentContextKey</param-name>
		<param-value>default.context</param-value>
	</context-param>

	<context-param>
		<param-name>webAppRootKey</param-name>
		<param-value>@webapp.root.key@</param-value>
	</context-param>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/classes/*-web.xml</param-value>
	</context-param>

	<listener>
		<listener-class>org.red5.server.war.WarLoaderServlet</listener-class>
	</listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

	<servlet>
		<servlet-name>gateway</servlet-name>
		<servlet-class>org.red5.server.net.servlet.AMFGatewayServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet>
		<servlet-name>rtmpt</servlet-name>
		<servlet-class>org.red5.server.net.rtmpt.RTMPTServlet</servlet-class>
		<load-on-startup>2</load-on-startup>
	</servlet>
	
	 <!-- MessageBroker Servlet -->
 <servlet>
  <display-name>MessageBrokerServlet</display-name>
  <servlet-name>MessageBrokerServlet</servlet-name>
  <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
  <init-param>
   <param-name>services.configuration.file</param-name>
   <param-value>/WEB-INF/flex/services-config.xml</param-value>
  </init-param>
  <load-on-startup>11</load-on-startup>
 </servlet>

	<servlet-mapping>
		<servlet-name>gateway</servlet-name>
		<url-pattern>/gateway</url-pattern>
	</servlet-mapping>

    <servlet-mapping>
        <servlet-name>rtmpt</servlet-name>
        <url-pattern>/fcs/*</url-pattern>
    </servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/open/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/idle/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/send/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>rtmpt</servlet-name>
		<url-pattern>/close/*</url-pattern>
	</servlet-mapping>

	 <servlet-mapping>
 		 <servlet-name>MessageBrokerServlet</servlet-name>
 	 	<url-pattern>/messagebroker/*</url-pattern>
 	</servlet-mapping>
 
	<welcome-file-list>
		<welcome-file>login.html</welcome-file>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
	</welcome-file-list>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Forbidden</web-resource-name>
			<url-pattern>/WEB-INF/*</url-pattern>
		</web-resource-collection>
		<auth-constraint />
	</security-constraint>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Forbidden</web-resource-name>
			<url-pattern>/persistence/*</url-pattern>
		</web-resource-collection>
		<auth-constraint />
	</security-constraint>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Forbidden</web-resource-name>
			<url-pattern>/streams/*</url-pattern>
		</web-resource-collection>
		<auth-constraint />
	</security-constraint>

</web-app>


 red5ChartRoom-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<bean id="web.context.chatroom" class="org.red5.server.Context">
	<property name="scopeResolver" ref="red5.scopeResolver"></property>
	<property name="clientRegistry" ref="global.clientRegistry"/>
	<property name="serviceInvoker" ref="global.serviceInvoker"/>
	<property name="mappingStrategy" ref="global.mappingStrategy"/>
</bean>
<bean id="web.scope" class="org.red5.server.WebScope" init-method="register">
	<property name="server" ref="red5.server"/>
	<property name="parent" ref="global.scope"/>
	<property name="context" ref="web.context.chatroom"/>
	<property name="handler" ref="web.handler.chatroom"/>
	<property name="contextPath" value="/Red5ChatRoom"/>
	<property name="virtualHosts" value="*,localhost,localhost:8080,127.0.0.1:8080"/>
</bean>
<bean id="web.handler.chatroom" class="com.chinahrt.chat.VedioChatApplication"/>
</beans>

 

red5.properties

# Socket policy
policy.host=0.0.0.0
policy.port=843

# HTTP
http.host=0.0.0.0
http.port=5080
https.port=8443

# RTMP
rtmp.host=0.0.0.0
rtmp.port=1935
rtmp.io_threads=16
rtmp.connect_threads=4
rtmp.send_buffer_size=271360
rtmp.receive_buffer_size=65536
rtmp.ping_interval=1000
rtmp.max_inactivity=60000
rtmp.tcp_nodelay=true

# RTMPS
rtmps.host=0.0.0.0
rtmps.port=8443
rtmps.ping_interval=5000
rtmps.max_inactivity=60000
rtmps.max_keep_alive_requests=-1
rtmps.max_threads=20
rtmps.acceptor_thread_count=2
rtmps.processor_cache=20
# RTMPS Keystore Password
rtmps.keystorepass=password

# RTMPT
rtmpt.host=0.0.0.0
rtmpt.port=8088
rtmpt.ping_interval=5000
rtmpt.max_inactivity=60000
rtmpt.max_keep_alive_requests=-1
rtmpt.max_threads=20
rtmpt.acceptor_thread_count=2
rtmpt.processor_cache=20

# MRTMP
mrtmp.host=0.0.0.0
mrtmp.server=localhost
mrtmp.port=9035
mrtmp.event_threads_core=4
mrtmp.event_threads_max=32
# event threads queue: -1 unbounded, 0 direct (no queue), n bounded queue
mrtmp.event_threads_queue=0
mrtmp.event_threads_keepalive=60
mrtmp.send_buffer_size=271360
mrtmp.receive_buffer_size=65536
mrtmp.ping_interval=5000
mrtmp.max_inactivity=60000
mrtmp.tcp_nodelay=true

# Debug proxy (needs to be activated in red5-core.xml)
proxy.source_host=127.0.0.1
proxy.source_port=1936
proxy.destination_host=127.0.0.1
proxy.destination_port=1935

# JMX
jmx.rmi.port.registry=9999
jmx.rmi.port.remoteobjects=
jmx.rmi.host=127.0.0.1
jmx.rmi.ssl=false


red5.config_root=red5.config_root
red5.root=E\:apache-tomcat-6.0.33

 

java代码

package com.chinahrt.chat;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.python.antlr.PythonParser.return_stmt_return;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.so.ISharedObject;
import org.red5.server.api.stream.IBroadcastStream;

/**
 * createBy ZYN
 *
 * createTime 2011-9-16 下午03:33:15
 *
 * desc 视频聊天服务器
 *
 */
public class VedioChatApplication extends ApplicationAdapter {
	
	private IScope appScope;
	
	private String userName;
	//共享存贮在线用户
	private ISharedObject listSO;
	
	private Map<String,IConnection> onlineList = new HashMap<String,IConnection> ();//在线用户表
	
	//程序运行
	//程序运行时志向 
	public boolean appStart(IScope app) { 
	  if (!super.appStart(app)) { 
	      return false; 
	  } 
	  appScope = app; 
	  return true; 
	} 
	@Override 
	public boolean appConnect(IConnection arg0, Object[] arg1) { 
	  /** 
	   *  用户首次连接server 时触发,检查用户是否重复登录,将用户添加到在线用户表中 
	   */ 
	  String userId=arg0.getClient().getId(); 
	  if(!super.appConnect(arg0, arg1)){ 
	   return false; 
	  } 
	  if (arg1 != null ) { 
	   userName = (String) arg1[0]; 
	  } 
	  if(onlineList.get(userName) != null){ 
	   rejectClient("请不要重复登录"); 
	   return false; 
	  } 
	  onlineList.put(userName, arg0); 
	  listSO = getSharedObject(appScope, "listSO", false); 
	  listSO.setAttribute(userId, userName); 
	  System.out.println("The user:"+userName+","+userName+" logined successfully"); 
	  return true; 
	} 
	/** 
	  * 通知所有人当前用户登录 
	  * @param params 
	  */ 
	public void getOnloadUser(Object[] params) {   
	  String clientName = params[0].toString();  
	  if(null == clientName || "".equals(clientName)) { 
	     return ; 
	   } 
	  //给所有客户端数据 
	   IScope scope = Red5.getConnectionLocal().getScope(); 
	   Iterator it = scope.getConnections().iterator(); 
	   for (;it.hasNext();) { 
	    Set connections = (Set)it.next(); 
	    IConnection tempConn = (IConnection)connections.iterator().next(); 
	    if (tempConn instanceof IServiceCapableConnection) { 
	     IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	     sc.invoke("result_getOnloadUser", new Object[]{clientName}); 
	    } 
	   } 
	} 
	//聊天 
	  public void sayToAll(Object[] params) { 
	   IConnection conn = Red5.getConnectionLocal(); 
	   String user_id = conn.getClient().getId(); 
	   String clientName =(String) listSO.getAttribute(user_id); 
	   System.out.println("************发言者是:"+clientName); 
	   String sayToName=params[0]==null?"":params[0].toString().trim();   
	   String sayWhat=params[1]==null?"":params[1].toString().trim(); 
	   if("".equals(sayToName)||"All".equals(sayToName))// 发消息给聊天室的所有人. 
	   { 
	    IScope scope = Red5.getConnectionLocal().getScope(); 
	    Iterator it = scope.getConnections().iterator();  
	    for (;it.hasNext();) { 
	      Set connections = (Set)it.next(); 
	      IConnection tempConn = (IConnection)connections.iterator().next(); 
	     if (tempConn instanceof IServiceCapableConnection) { 
	         IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	      // 调用客户端showMessage方法。 
	         sc.invoke("showMessage", new Object[]{clientName+" to All:"+sayWhat}); 
	      } 
	   } 
	   }else{ 
	     IConnection tempConn=onlineList.get(sayToName);     
	     if (tempConn instanceof IServiceCapableConnection) { 
	      IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;     
	      sc.invoke("showMessage", new Object[]{clientName+" to "+sayToName+":"+sayWhat}); 
	      } 
	     IServiceCapableConnection sc = (IServiceCapableConnection) conn; 
	     sc.invoke("showMessage", new Object[]{clientName+" to "+sayToName+":"+sayWhat}); 
	   } 
	  } 
	// 用户断开连接的时候触发 
	  public void appDisconnect(IConnection conn) { 
	   String dis_user_id = conn.getClient().getId(); 
	   String user = (String) listSO.getAttribute(dis_user_id); 
	   // 根据ID删除对应在线纪录 
	   onlineList.remove(user); 
	   // 删除用户列表共享对象的对应属性 
	   listSO.removeAttribute(dis_user_id); 
	   IScope scope = Red5.getConnectionLocal().getScope(); 
	    Iterator it = scope.getConnections().iterator();  
	    for (;it.hasNext();) { 
	     Set connections = (Set)it.next(); 
	     IConnection tempConn = (IConnection)connections.iterator().next(); 
	     if (tempConn instanceof IServiceCapableConnection) { 
	         IServiceCapableConnection sc = (IServiceCapableConnection) tempConn; 
	       // 服务器端调用客户端flash方法。 
	         sc.invoke("disconnectMessage", new Object[]{user}); 
	      } 
	    } 
	  } 
		
		
}

 flex端代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.containers.HBox;
			import mx.controls.Alert;
			
			
			private var listSO:SharedObject;
			private var userArr:Array;
			private var conn:NetConnection;
			private var localUsername:String;
			[Bindable]
			private var cam:Camera;
			[Bindable]
			private var mic:Microphone;
			[Bindable]
			public var cards:ArrayCollection;
			public var videoUsers:Array;
			[Bindable]
			public var videoControlArr:Array;
			
			private var stm:NetStream;
			[Bindable]
			private var video_self:Video;
			
			protected function login(event:MouseEvent):void
			{
				localUsername = txt_name.text;
				if(localUsername== ""){
					Alert.show("用户名不能为空");
				}else{
					if(conn == null){
						conn = new NetConnection();
						conn.client = this;
						conn.addEventListener(NetStatusEvent.NET_STATUS,_statusHandler);
						conn.connect("rtmp://192.168.1.61/Red5ChatRoom",localUsername);
					}
				}
			}
			
			//状态监听
			private function _statusHandler(evt:NetStatusEvent):void
			{
				if(evt.info.code == "NetConnection.Connect.Success"){
					this.currentState = "chat";
					Alert.show("连接成功");
					video_clickHandler();
					this.showJoinInInfo(localUsername);
					_setListSO();
					
					
				}
				if(evt.info.code == "NetConnection.Connect.Failed"){
					Alert.show("连接失败");
				}
				if(evt.info.code == "NetConnection.Connect.Closed"){
					Alert.show("连接关闭");
				}
			}
			
			public function showJoinInInfo(message:String):void
			{
				conn.call("getOnloadUser",null,message);
			}
			
			public function result_getOnloadUser(str:String):void{
				txt_chatmsg.text += str + "加入聊天室" + "\n";
			}
			//创建用户列表共享对象
			private function _setListSO():void
			{
				listSO = SharedObject.getRemote("listSO",conn.uri,false);
				listSO.connect(conn);
				listSO.addEventListener(SyncEvent.SYNC,_listSOSyncHandler);
			}
			
			//用户列表共享对象被更新之后的事件
			private function _listSOSyncHandler(evt:SyncEvent):void{
				_showUserList();//更新用户列表
			}
			
			private function _showUserList():void
			{
				cards = new ArrayCollection(
					[{label:"All"}]
				);
				userArr = new Array();
				//用户数组更新
				for(var tmp:String in listSO.data){
					userArr.push(listSO.data[tmp]);
				}
				//添加到arrayCollection
				for(var i:int = 0; i<userArr.length;i++){
					cards.addItem({label:userArr[i]});
				}
				//将数组添加到列表数组中显示出来
				userList.dataProvider = cards;
				users.dataProvider = cards;
				addVideo(cards);
			}
			
			public function showMessage(message:String):void
			{
				txt_chatmsg.text += message + "\n";
			}
			
			protected function sendMessage(event:MouseEvent):void
			{
				var sendString:String = txt_yousay.text;
				var sendTo:String = userList.selectedItem.label;
				txt_yousay.text = "";
				conn.call("sayToAll",null,sendTo,sendString);
			}
			
			//断线通知
			public function disconnectMessage(disUser:String):void
			{
				txt_chatmsg.text += disUser+"退出聊天室\n";
			}
			//进入视频会议
			public function video_clickHandler():void
			{
				stm = new NetStream(conn);
				cam = Camera.getCamera();
				if(cam==null){
					Alert.show("没有可以使用的摄像头");
					return;
				}else{
					Security.showSettings(SecurityPanel.PRIVACY);
					cam.addEventListener(StatusEvent.STATUS,statusHandler);
					cam.addEventListener(ActivityEvent.ACTIVITY,activityHandler);
					cam.setLoopback(true);
					cam.setMotionLevel(50,100);
					cam.setMode(1280,960,15,true); 
					stm.attachCamera(cam);
				}
				mic = Microphone.getMicrophone();
				mic.addEventListener(StatusEvent.STATUS,micOnstatu);
				if(mic == null){
					Alert.show("没有可以使用的麦克风");
				}else{
					mic.setUseEchoSuppression(true);
					stm.attachAudio(mic);
				}
				stm.play("chinahrt-"+txt_name.text);
				stm.publish("chinahrt-"+txt_name.text,"live");
				video_self = new Video();
				video_self.width = 320;
				video_self.height = 240;
				video_self.attachCamera(cam);
				my_video.addChild(video_self);
				
			}
			
			private function micOnstatu(e:StatusEvent):void
			{
				mic.setLoopBack(true);
				mic.gain = 66;
				mic.rate = 11;
				mic.setUseEchoSuppression(true);
				mic.setSilenceLevel(1,-1);
			}
			
			private function statusHandler(e:StatusEvent):void
			{
				
			}
			
			private function activityHandler(e:ActivityEvent):void
			{
			
			}
			
			private function addVideo(cards:ArrayCollection):void
			{
				label1.text = "我的("+localUsername+")";
				myBox.removeAllChildren();
				var otherPerson:ArrayCollection = new ArrayCollection();
				for(var i:int=0;i<cards.length;i++){
					var o:Object = cards.getItemAt(i);
					if(o["label"]!=localUsername&&o["label"]!="All"){
						otherPerson.addItem(o);			
					}
				}
		//		Alert.show(otherPerson.length+"");
				var yushu:int = 0;
				var yushu:int= otherPerson.length%3;
				var rowNum:int = 0;
				var rowNum:int = otherPerson.length/3;
				
				if(yushu!=0){
					rowNum += 1;
				}
				if(yushu==0){
					for(var i:int=0;i<rowNum;i++){
						var hbox:HBox = new HBox();
						myBox.addChild(hbox);
						for(var ii:int=0;ii<3;ii++){
							var vbox:VBox = new VBox();
							hbox.addChild(vbox);
							var label:Label = new Label;
							label.text = otherPerson.getItemAt(i*3+ii)["label"];
							vbox.addChild(label);
							var videoDisplay:VideoDisplay = new VideoDisplay();
							videoDisplay.live = true;
							videoDisplay.width = 320;
							videoDisplay.height = 240;
							vbox.addChild(videoDisplay);
							var video:Video = new Video();
							video.width = 320;
							video.height = 240;
							var netStream:NetStream = new NetStream(conn);
							video.attachNetStream(netStream);
							netStream.play("chinahrt-"+label.text);
							
							videoDisplay.addChild(video);
						}
					}
				}else{
					for(var i:int=0;i<rowNum-1;i++){
						var hbox:HBox = new HBox();
						myBox.addChild(hbox);
						for(var ii:int=0;ii<3;ii++){
							var vbox:VBox = new VBox();
							hbox.addChild(vbox);
							var label:Label = new Label;
							label.text = otherPerson.getItemAt(i*3+ii)["label"];
							vbox.addChild(label);
							var videoDisplay:VideoDisplay = new VideoDisplay();
							videoDisplay.live = true;
							videoDisplay.width = 320;
							videoDisplay.height = 240;
							vbox.addChild(videoDisplay);
							var video:Video = new Video();
							video.width = 320;
							video.height = 240;
							var netStream:NetStream = new NetStream(conn);
							video.attachNetStream(netStream);
							netStream.play("chinahrt-"+label.text);
							videoDisplay.addChild(video);
						}
					}
					var hbox:HBox = new HBox();
					myBox.addChild(hbox);
					for(var i:int=0;i<yushu;i++){
						var vbox:VBox = new VBox();
						hbox.addChild(vbox);
					//	myBox.addChild(vbox);
						var label:Label = new Label();
						label.text = otherPerson.getItemAt((rowNum-1)*3+i)["label"];
						vbox.addChild(label);
						var videoDisplay:VideoDisplay = new VideoDisplay();
						videoDisplay.live = true;
						videoDisplay.width = 320;
						videoDisplay.height = 240;
						vbox.addChild(videoDisplay);
						var video:Video = new Video();
						video.width = 320;
						video.height = 240;
						var netStream:NetStream = new NetStream(conn);
					//	Alert.show(otherPerson.getItemAt((rowNum-1)*3+i)["label"]);
						video.attachNetStream(netStream);
						netStream.play("chinahrt-"+label.text);
						
						videoDisplay.addChild(video);
					}
				}
				
			}
		]]>
	</mx:Script>
	
	<mx:states> 
		<mx:State id="chatState" name="chat"> 
			<mx:SetProperty target="{form1}" name="width" value="0"/> 
			<mx:SetProperty target="{form1}" name="height" value="0"/> 
			<mx:SetProperty target="{form1}" name="x" value="0"/> 
			<mx:SetProperty target="{form1}" name="y" value="0"/> 
			<mx:AddChild position="lastChild"> 
				<mx:Panel x="10" y="10" width="381" height="370" layout="absolute" title="聊天信息"> 
					
					<mx:TextArea x="10" y="10" width="215" height="235" id="txt_chatmsg"/> 
					<mx:ComboBox x="233" y="34" width="118" id="userList"></mx:ComboBox> 
					<mx:Label x="233" y="11" text="用户列表"/> 
					<mx:DataGrid x="233" y="64" height="256" id="users" width="118"> 
						<mx:columns> 
							<mx:DataGridColumn headerText="用户名" dataField="label"/> 
						</mx:columns> 
					</mx:DataGrid> 
					<mx:TextInput x="10" y="253" height="67" width="150" id="txt_yousay"/> 
					<mx:Button x="168" y="253" label="发送" width="57" click="sendMessage(event)"/> 
				<!--	<mx:Button x="168" y="298" label="进入视频会议" width="57" click="video_clickHandler(event)"/>--> 
				</mx:Panel> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:VideoDisplay live="true" x="10" y="410"  width="320" height="240" id="my_video"/> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:Label id="label1" x="10" y="390" text="我的"/> 
			</mx:AddChild> 
			<!--<mx:AddChild position="lastChild"> 
				<mx:VideoDisplay live="true"  x="399" y="224"  width="320" height="240" id="other_video"/> 
			</mx:AddChild> 
			<mx:AddChild position="lastChild"> 
				<mx:Label x="399" y="198" text="对方的"/> 
			</mx:AddChild> -->
			<mx:AddChild position="lastChild">
				<mx:VBox id="myBox" x="399" y="10"/>
			</mx:AddChild>
		</mx:State> 
	</mx:states> 
	
	<mx:Form x="10" y="10" width="283" height="126" id="form1"> 
		<mx:FormItem label="用户名:"> 
			<mx:TextInput id="txt_name"/> 
		</mx:FormItem> 
		<mx:FormItem> 
			<mx:Button label="登陆" click="login(event)"/> 
		</mx:FormItem> 
	</mx:Form> 
</mx:Application>

 百度网盘:http://pan.baidu.com/s/1hqkgBly

  • 大小: 51.7 KB
  • 大小: 99.5 KB
  • 大小: 84.3 KB
9
3
分享到:
评论
45 楼 lbaaixy 2017-12-06  
楼主,小弟最近也在弄这个东西。有点小问题
java.lang.ClassCastException: org.apache.catalina.deploy.SecurityConstraint cannot be cast to org.apache.catalina.deploy.SecurityConstraint
有这个错误。希望帮个小忙
44 楼 chinaxiaofeng8 2016-12-20  
在吗,兄弟,你那个代码怎么运行看效果的
43 楼 odbcjava 2015-08-13  
麻烦给我一份,多谢,junhu.sun@pcitc.com
42 楼 罗小三 2014-04-25  
楼主发个完整demo吧,十分感谢,急需!!!!!!!!!rondo_aniu@sina.com。多谢!
41 楼 hanshiweihx 2014-01-11  
下载了楼主的源代码,在myeclipse中已经成功导入,但是运行一直出错,因为很急切的要使用这个功能,所以冒昧叨扰楼主,是否有空,可以指点一下,只希望能跑起来即可,可以加我QQ764791256,楼主也可以留下QQ我来加,冒昧打扰,十分抱歉
40 楼 zyn010101 2014-01-10  
梦幻小子 写道
297082744@qq.com

http://pan.baidu.com/s/1hqkgBly
39 楼 zyn010101 2014-01-10  
she2shou 写道
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢

http://pan.baidu.com/s/1hqkgBly
38 楼 zyn010101 2014-01-10  
wcl997670205 写道
楼主,发一份源码吧,灰常感谢 997670205wcl@gmail.com O(∩_∩)O谢谢

http://pan.baidu.com/s/1hqkgBly
37 楼 zyn010101 2014-01-10  
she2shou 写道
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢

http://pan.baidu.com/s/1hqkgBly
36 楼 she2shou 2014-01-10  
很想得到楼主的完整源码来学习啊.
楼主现在有百度云,腾讯微云, 你能上传一份,然后只要给个地址给我们大家就好了. 多谢
35 楼 wcl997670205 2014-01-09  
楼主,发一份源码吧,灰常感谢 997670205wcl@gmail.com O(∩_∩)O谢谢
34 楼 梦幻小子 2014-01-07  
297082744@qq.com
33 楼 梦幻小子 2014-01-07  
楼主  这个发份源码给我学习下好么  万分感谢
32 楼 bin474740536 2013-12-30  
楼主,给我发一份齐全的源码,让我学习一下 474740536@qq.com
31 楼 moonskyii90 2013-12-27  
求楼主传我一份参考 拜谢啊  moonskyii@qq.com
30 楼 chenlk823 2013-12-27  
我最近都被这个烦透了,求demo
chen_like00@163.com
29 楼 IT_ty 2013-12-20  
求楼主源码 643146521@qq.com
28 楼 mzy9950012 2013-12-18  
求发分demo来啊 mzy9950012@163.com
27 楼 hezhaomeng 2013-11-04  
楼主求源码 万分感激 807586760@qq.com
26 楼 cclovehxj52 2013-10-11  
  楼主求一份源码,谢谢 cclovehxj52@163.com

相关推荐

    flex 视频聊天 基于red5

    Flex视频聊天基于Red5是一种利用Adobe Flex技术和OpenSource Media Framework (OSMF)的Red5服务器实现的实时视频通信解决方案。Flex是一种开源的编程框架,主要用于构建富互联网应用程序(RIA),而Red5则是一个开放...

    Flex+Red5+Tomcat视频语音录制、播放

    综上所述,Flex+Red5+Tomcat技术栈提供了一套完整的解决方案,能够实现高效、交互式的视频和音频应用开发。开发者可以利用Flex创建直观的用户界面,通过Red5处理多媒体流的录制和播放,而Tomcat则作为中间层,处理...

    基于flex 和red5的视频聊天

    在IT领域,实时的视频通信技术已经广泛应用,例如在线教育、远程医疗、视频会议等。本文将深入探讨如何利用Flex技术和Red5服务器来构建一个简单的视频聊天应用。Flex是Adobe公司推出的开源框架,用于创建富互联网...

    flex-red5.zip_flex_red5_red5 flex_视频服务器

    总的来说,Flex和Red5的结合提供了一种高效、灵活的解决方案,用于构建实时流媒体应用,无论是在线教育、远程会议,还是娱乐直播,都可以借助这套技术实现高质量的音视频传输。开发者可以通过深入学习这两个技术,...

    red5流媒体视频会议入门实例

    这个入门实例主要面向那些正在为E-learning系统设计视频会议模块的新手开发者,特别是对Red5和ActionScript不太熟悉的人。 首先,我们要搭建Red5流媒体开发环境: 1. **下载安装Red5服务器**: 访问官方网址...

    多人视频会议RED5+FLEX

    import org.red5.server.api.Red5; import org.red5.server.api.service.IServiceCapableConnection; import org.red5.server.api.so.ISharedObject; import org.red5.server.api.ScopeUtils; import org.red5....

    RED5&Flex流媒体应用实战开发视频教程

    本教程有四大部分组成:第一部分讲项目前预备知识,在线播放器程序全程贯穿,后三个部分分别是三个项目,第一个项目是flex多人聊天室,第二个项目是在线秀场,第三个项目是视频会议,三个项目均是精心挑选和专门...

    Red5 + Flex开发实例

    Red5通常用于构建应用程序,如视频会议、在线游戏、直播平台、交互式教育应用等。 Red5的下载和安装包括以下几个步骤: 1. Red5下载:可以从***/red5网站或是Google的***/p/red5网站下载。对于Windows用户,下载...

    red5+flex实现超简易群聊天功能

    标题 "red5+flex实现超简易群聊天功能" 指的是使用Red5服务器和Flex前端技术构建一个简单的多人在线聊天室的应用。这个项目可能是为了展示如何整合这两种技术来创建实时交互的Web应用。 Red5是一款开源的Java流媒体...

    Red5说明文档 flex视频

    Red5是一款开源的、基于Java的流媒体服务器,支持多种流媒体协议,包括RTMP(Real-Time Messaging Protocol),使其成为开发实时通信(如直播、视频会议)的理想平台。Red5能够处理Flash流媒体,这在早期的互联网...

    red5 0.8 + 视频通话

    而"netMeeting.rar"可能包含的是网络会议相关的组件或服务,这可能是对多人视频通话的支持,使得多个用户可以同时参与一个视频会议。 为了实现这个系统,开发者需要掌握以下关键技术: 1. Red5服务器的配置和编程:...

    RED5&Flex流媒体应用实战开发课程1

    二个项目是在线秀场,第三个项目是视频会议,三个项目均是精心挑选和专门设计的。难度由浅入深,知识点由少到多,并且尽量涵盖Red5和Flex方面 的多种知识点,而且避免知识点重复,覆盖面较广,三个项目的实战性均很...

    RED5&Flex流媒体应用实战开发课程2

    二个项目是在线秀场,第三个项目是视频会议,三个项目均是精心挑选和专门设计的。难度由浅入深,知识点由少到多,并且尽量涵盖Red5和Flex方面 的多种知识点,而且避免知识点重复,覆盖面较广,三个项目的实战性均很...

    RED5多人会议源码

    8. **互动功能**:多人会议往往包含文字聊天、白板共享、屏幕共享等功能,这些都是通过RED5服务器和FLEX客户端之间的数据交换来实现的。 9. **录制与回放**:RED5支持流媒体的录制,可以将会议过程保存为文件,供...

    red5视频插件

    1. **流媒体服务**:Red5支持RTMP协议,这使得它可以与Adobe Flash Player或Flex应用程序无缝协作,提供实时视频和音频流。此外,通过RTSP,Red5可以处理IP摄像机和其他设备的视频流。 2. **录制功能**:Red5能够...

    red5 配置详解

    Flex客户端可以利用Red5提供的API与服务器交互,创建、连接和断开视频会议,以及调用服务器上的方法来实现视频流的共享和控制。 总的来说,配置Red5涉及到创建正确的文件结构,设置配置参数,定义应用程序的行为,...

    red5应用程序实例

    本实例中的"red5应用程序"展示了一个完整的Red5应用解决方案,它实现了文件资源路径的自定义,并且能够与Flex客户端配合,提供视频录制和播放功能。 1. **Red5简介** Red5是一款用Java编写的开源流媒体服务器,它...

    Red5入门教程

    通过Red5,开发者可以构建诸如视频播放网站、远程教育平台、视频会议系统、聊天应用和网络游戏等多种实时交互应用。 1. **Red5介绍** - Red5是一个开源的Flash流媒体服务器,提供MP3和FLV的流式传输、流录制、共享...

Global site tag (gtag.js) - Google Analytics