1)把Red5/doc/templates/myapp拷贝到Red5/webapps里面修改名字为自己的项目名字testwebcam,把WEB-INF里面的red5-web.properties,red5-web.xml,web.xml里面的myapp都改成testwebcam
red5-web.xml的myhandler.service节点直接去掉如下
com.Application是自己写的java类此类继承org.red5.server.adapter.ApplicationAdapter;当flex调用java时从此类进入
编译好的classes放在WEB-INF里面
web.xml只需保留如下:
My sample Red5 application
contextConfigLocation
/WEB-INF/red5-*.xml
webAppRootKey
/testwebcam
重启下red5看是否可以正常的启动
2)新建一个flex项目取名testwebcam 这里可以先测试下是否可以连接到red5里面的testwebcam
修改testwebcam.mxml
新建一个testwebcam.as来存放方法代码如下
package com
{
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import mx.containers.Panel;
import mx.controls.Alert;
import mx.controls.Button;
import mx.controls.Label;
import mx.controls.List;
import mx.controls.Text;
import mx.controls.TextArea;
import mx.controls.TextInput;
import mx.controls.VideoDisplay;
import mx.core.Application;
public class testwebcam extends Application
{
private var nc:NetConnection;
[Bindable]
public var main:Panel;
[Bindable]
public var login:Panel;
[Bindable]
public var userNames:List;
[Bindable]
public var sendto:TextInput;
[Bindable]
public var clew:Label;
[Bindable]
public var req_btn:Button;
[Bindable]
public var accept_btn:Button;
[Bindable]
public var userName:TextInput;
[Bindable]
public var userLab:Label;
private var otherName:String;
public function testwebcam()
{
super();
}
//连接red5上的testwebcam服务
public function connect():void{
nc = new NetConnection();
nc.client = this;
nc.addEventListener(NetStatusEvent.NET_STATUS,ncHander);
nc.connect("rtmp://192.168.2.164/testwebcam");
addEventListener(InComeingEvent.INCOMING,inComeingCall);
}
public function inComeingCall(event:InComeingEvent):void{
clew.text = event.name+"来电";
otherName = event.name;
accept_btn.visible = true;
}
private function ncHander(event:NetStatusEvent):void{
if(event.info.code == "NetConnection.Connect.Success"){
}else{
Alert.show("NetConnection error");
}
}
//用户登陆,调用java端loginUser方法
public function loginUser(userName:String):void{
trace(userName);
userLab.text = userName;
if(userName == ""){
Alert.show("input name");
}else{
nc.call("loginUser",null,userName);
login.visible = false;
main.visible = true;
}
}
//用户离开
public function leave():void{
nc.call("leave",null);
login.visible = true;
main.visible = false;
}
//该方法提供给java端使用
public function showUsers(userName:Array):*{
userNames.dataProvider = userName;
}
//发送请求
public function request(userName:String):*{
req_btn.enabled = false;
nc.call("request",null,userName);
}
//双击用户列表时调用
public function list():*{
sendto.text = "";
sendto.text = userNames.selectedItems.toString();
messageSendTo.text = userNames.selectedItems.toString();
}
//该方法提供java端使用,监听是否有请求来
public function incomeing(name:String):void{
trace("来电"+name);
dispatchEvent(new InComeingEvent(InComeingEvent.INCOMING,name));
}
[Bindable]
public var cameraVideo:VideoDisplay;
[Bindable]
public var remoteVideo:VideoDisplay;
private var camera:Camera;
private var pubNetStream:NetStream;
private var playNetStream:NetStream;
//点击按钮,接受请求
public function accept():void{
trace("accept");
nc.call("accepted",null,userLab.text,otherName);
}
//由java调用,当接收请求后,确认双方连接成功
public function connected(publishName:String,playName:String):void{
trace("publishName = "+publishName +" playName = "+playName);
camera = Camera.getCamera();
cameraVideo.attachCamera(camera);
pubNetStream = new NetStream(nc);
pubNetStream.attachCamera(camera);
pubNetStream.publish(publishName,"live");
playNetStream = new NetStream(nc);
var video:Video = new Video();
video.width = remoteVideo.width;
video.height = remoteVideo.height;
video.attachNetStream(playNetStream);
remoteVideo.addChild(video);
playNetStream.play(playName);
}
[Bindable]
public var messageSendTo:Text;
[Bindable]
public var messagesend:TextArea;
public function sendMessage(message:String):*{
if(messageSendTo.text!=""){
messageArea.text += "你对"+messageSendTo.text+"说:"+message+"/n";
}
nc.call("sendMessage",null,userLab.text,messageSendTo.text,message);
messagesend.text = "";
}
[Bindable]
public var messageArea:TextArea;
//对所有的人发送消息,当没有选择特定一个对象的时候调用
public function showMessage(name:String,message:String):*{
trace("111111111111111111");
messageArea.text += name+" 说:"+message+"/n";
}
//对某一个人发送消息
public function showPrivateMessage(name:String,message:String):*{
messageArea.text += name+" 对你说:"+message+"/n";
}
}
}
其中nc.call是调用java端 com.Application里面的方法,此类使用了一个InComeingEvent.as事件代码如下
package com
{
import flash.events.Event;
public class InComeingEvent extends Event
{
public static var INCOMING:String = "incoming";
public var name:String ;
public function InComeingEvent(type:String,name:String)
{
super(type);
this.name = name;
}
}
}
flex端完成
3)编写java端Application类代码:
package com;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
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;
public class Application extends ApplicationAdapter{
private HashMap uM = new HashMap();
//项目启动的时候调用
public boolean appStart( IScope scope ) {
return true;
}
//当有flex客户端连接时候调用
public boolean appConnect(IConnection con, Object[] params) {
System.out.println("new client connectting chat room ==============");
return true;
}
//当flex客户端断开连接的时候调用
public void appDisconnect(IConnection conn) {
System.out.println(conn.getClient().getId() + " disconnect-----------------");
String clientid = Red5.getConnectionLocal().getClient().getId();
uM.remove(clientid);
showUsers();
}
//用户登陆,每当有用户登陆的时候都会通知当前的所有用户
public void loginUser(String userName){
uM.put(Red5.getConnectionLocal().getClient().getId(), userName);
showUsers();
}
//让每个客户都展示现在所有的用户
public void showUsers(){
Object[] s = uM.values().toArray();
IScope scope = Red5.getConnectionLocal().getScope();
Collection> it = scope.getConnections();//得到现在连接到该服务的所有连接
Iterator> iterator = it.iterator();
while(iterator.hasNext()){
Iterator i = iterator.next().iterator();
while(i.hasNext()){
IConnection tempConn = i.next();
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
// 服务器端调用客户端flash方法。
sc.invoke("showUsers", new Object[] { s });
}
}
}
//用户离开
public void leave(){
String clientid = Red5.getConnectionLocal().getClient().getId();
uM.remove(clientid);
showUsers();
}
//请求方法,将请求发送给指定username的连接
public void request(String username){
System.out.println("request+++++++"+username);
String clientidme = Red5.getConnectionLocal().getClient().getId();
String usernameme = uM.get(clientidme);
String sendClientid = null;
Set clientids = uM.keySet();
Iterator iter = clientids.iterator();
while(iter.hasNext()){
String clientid = iter.next();
if(uM.get(clientid).equals(username)){
sendClientid = clientid;
}
}
IScope scope = Red5.getConnectionLocal().getScope();
Collection> it = scope.getConnections();
Iterator> iterator = it.iterator();
// System.out.println(it+"======");
while(iterator.hasNext()){
Iterator i = iterator.next().iterator();
while(i.hasNext()){
IConnection tempConn = i.next();
if(tempConn.getClient().getId().equals(sendClientid)){
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
//调用flex的incomeing方法告知有请求到来
sc.invoke("incomeing", new Object[]{usernameme});
}
}
}
}
//接受方法
public void accepted(String acceptname,String callname){
System.out.println("===="+acceptname+"===="+callname);
Set clientids = uM.keySet();
Iterator iter = clientids.iterator();
String acceptid = null;
String callid = null;
while(iter.hasNext()){
String clientid = iter.next();
if(uM.get(clientid).equals(acceptname)){
acceptid = clientid;
}
if(uM.get(clientid).equals(callname)){
callid = clientid;
}
}
IScope scope = Red5.getConnectionLocal().getScope();
Collection> it = scope.getConnections();
Iterator> iterator = it.iterator();
// System.out.println(it+"======");
while(iterator.hasNext()){
Iterator i = iterator.next().iterator();
while(i.hasNext()){
IConnection tempConn = i.next();
if(tempConn.getClient().getId().equals(acceptid)){
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
//被叫方确认接受请求,调用connected方法
sc.invoke("connected", new Object[]{acceptname,callname});
}
if(tempConn.getClient().getId().equals(callid)){
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
sc.invoke("connected", new Object[]{callname,acceptname});
}
}
}
}
//发送消息方法
public void sendMessage(String name,String toname,String message){
System.out.println(toname+"=name");
if("".equals(toname)){
System.out.println("11111111111111111");
IScope scope = Red5.getConnectionLocal().getScope();
Collection> it = scope.getConnections();
Iterator> iterator = it.iterator();
// System.out.println(it+"======");
while(iterator.hasNext()){
Iterator i = iterator.next().iterator();
while(i.hasNext()){
IConnection tempConn = i.next();
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
System.out.println("22222222222222");
sc.invoke("showMessage", new Object[]{name,message});
}
}
}else{
Set clientids = uM.keySet();
Iterator iter = clientids.iterator();
String toid = null;
while(iter.hasNext()){
String clientid = iter.next();
if(uM.get(clientid).equals(toname)){
toid = clientid;
}
}
IScope scope = Red5.getConnectionLocal().getScope();
Collection> it = scope.getConnections();
Iterator> iterator = it.iterator();
// System.out.println(it+"======");
while(iterator.hasNext()){
Iterator i = iterator.next().iterator();
while(i.hasNext()){
IConnection tempConn = i.next();
if(tempConn.getClient().getId().equals(toid)){
IServiceCapableConnection sc = (IServiceCapableConnection) tempConn;
sc.invoke("showPrivateMessage", new Object[]{name,message});
}
}
}
}
}
}
java端代码完成
将编译好的代码放在WEB-INF里面的classes里面重启red5后确认正常启动后,可以运行flex端进行测试。
felx+red5视频
最新推荐文章于 2023-12-23 14:30:55 发布