写这段代码的时候,只是一个新手,所以注释就忘了加上,自己勉强看了一遍代码,有部分地方可能不是很好理解,得罪了。有朋友到我空间去要过代码,在这里只能说抱歉了,我到今天才看到你们的申请,都已经好几年了。
red5视频聊天(服务器)
package red5.example.red5server;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.so.ISharedObject;
import com.makefriend.entity.UserInfo;
import com.makefriend.service.UserInfoService;
import com.makefriend.service.impl.UserInfoServiceImpl;
public class Application extends ApplicationAdapter {
private IScope appScope;
private String username;
private ISharedObject listSO;
private ISharedObject msgSO;
private Map<String, IConnection> onLineClient = new HashMap<String, IConnection>();
@Override
public boolean appStart(IScope scope) {
if (!super.appStart(scope)) {
return false;
}
appScope = scope;
return true;
}
@Override
public boolean appConnect(IConnection conn, Object[] params) {
System.out.println("red5Server--有客户端要建立连接...");
username = (String) params[0];
UserInfoService userInfoServer = new UserInfoServiceImpl();
UserInfo user = userInfoServer.getUserInfo(username);
if (user == null) {
return false;
}
if (!user.getUserPassword().equals(params[1].toString())) {
return false;
}
String link_id = conn.getClient().getId();
onLineClient.put(username, conn);
listSO = getSharedObject(appScope, "listSO", false);
msgSO = getSharedObject(appScope, "msgSO", false);
listSO.setAttribute(link_id, username);
return true;
}
/**
* 消息群发
*
* @param msg
*/
public void broadcastUserMsg(String msg) {
msgSO.setAttribute("msg", msg);
Collection<IConnection> cons= onLineClient.values();
for(IConnection i : cons){
IServiceCapableConnection ic=(IServiceCapableConnection) i;
ic.invoke("showMsgByPrivate", new Object[] { msg });
}
}
/**
* 私聊信息
*
* @param msg
* @param from
* @param to
*/
@SuppressWarnings("unchecked")
public void msgFromPrivate(String msg, String from, String to) {
IServiceCapableConnection fc = (IServiceCapableConnection) onLineClient
.get(from);
IServiceCapableConnection tc = (IServiceCapableConnection) onLineClient
.get(to);
fc.invoke("showMsgByPrivate", new Object[] { msg });
tc.invoke("showMsgByPrivate", new Object[] { msg });
}
@Override
public void appDisconnect(IConnection conn) {
System.out.println("red5Server--客户端断开连接...");
String dis_link_id = conn.getClient().getId();
String user = (String) listSO.getAttribute(dis_link_id);
onLineClient.remove(user);
listSO.removeAttribute(dis_link_id);
super.appDisconnect(conn);
}
}
首先说几句吧,这项技术是在几年之前,我无聊的时候实现的。现在已经有一段时间,很多东西也不记得了。那个时候只是一个新手,特别的骄傲,发了帖子却没有发代码,对此十分抱歉,今天整理了一下,把源码全部放出来,有写的不好的地方,希望多多包含,每个人应该都有这样的感觉,看以前的代码,很难受!
red5视频聊天源码(客服端)
经过一段时间的研究,视频聊天在今天终于告一段落了,特此发码
<?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" width="800" height="600"
creationComplete="init()">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.IList;
import mx.collections.XMLListCollection;
import mx.controls.Alert;
private var IP:String;
private var redPath:String;
private var nc:NetConnection;
private var ns:NetStream;
private var ns2:NetStream;
private var cam:Camera
private var mic:Microphone;
private var listSO:SharedObject;
private var msgSO:SharedObject;
[Bindable]
private var userArr:ArrayCollection;
private var sendMsg:String;
private var now:Date;
private var userIDObj:Object;
private var video:Video;
private function init():void{
IP="192.168.1.100";
redPath="rtmp://"+IP+"/makeFriend";
nc=new NetConnection();
now=new Date();
main.visible=false;
login.visible=true;
userList.visible=true;
chatVideo.visible=false;
}
private function startConnect():void{
nc.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityHandler);
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncHandler);
nc.connect(redPath,username.text,userpwd.text);
nc.client=this;
}
private function statusHandler(e:NetStatusEvent):void{
if(e.info.code=="NetConnection.Connect.Success"){
Alert.show("登录成功");
login.visible=false;
main.visible=true;
publishVideo();
setListSO();
setMsgSO();
btnSend.addEventListener(MouseEvent.CLICK,sendBtnByClick);
main.addEventListener(KeyboardEvent.KEY_DOWN,sendBtnByKey);
}
if(e.info.code=="NetConnection.Connect.Failed")
{
Alert.show("连接失败");
}
if(e.info.code=="NetConnection.Connect.Closed")
{
Alert.show("账号密码不正确,请重新输入!!!");
}
}
private function securityHandler(e:SecurityError):void{
Alert.show("低调的安全沙箱错误");
}
private function asyncHandler(e:AsyncErrorEvent):void{
Alert.show("低调的异步错误");
}
private function publishVideo():void{
ns=new NetStream(nc);
cam=Camera.getCamera();
mic=Microphone.getMicrophone();
myVideo.attachCamera(cam);
ns.client=this;
ns.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncHandler);
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.publish(username.text,"live");
}
private function setListSO():void{
listSO=SharedObject.getRemote("listSO",nc.uri,false);
listSO.connect(nc);
listSO.addEventListener(SyncEvent.SYNC,listSOSyncHandler);
}
private function setMsgSO():void{
msgSO = SharedObject.getRemote("msgSO", nc.uri, false);
msgSO.addEventListener(SyncEvent.SYNC, msgSOSyncHandler);
msgSO.connect(nc);
}
private function msgSOSyncHandler():void{
for (var i in msgSO.data) {
txtmessage.text =txtmessage.text+ msgSO.data[i];
}
}
private function listSOSyncHandler(e:SyncEvent):void{
showUserList();
userList.addEventListener(MouseEvent.CLICK,updateChatTo);
userList.addEventListener(MouseEvent.DOUBLE_CLICK,updateVideoShow);
}
private function showUserList():void{
userArr=new ArrayCollection();
for(var tmp in listSO.data){
userArr.addItem(listSO.data[tmp]);
}
userArr.addItemAt("所有人",0);
this.userList.dataProvider=userArr;
}
private function updateChatTo(e:MouseEvent):void{
main.title="您正与"+userList.selectedItem+"聊天中";
}
private function updateVideoShow(e:MouseEvent):void{
if(userList.selectedItem=="所有人"||userList.selectedItem=="")
{
Alert.show("不能和所有人进行视频聊天。");
return ;
}
userList.visible=false;
chatVideo.visible=true;
video=new Video();
ns2=new NetStream(nc);
ns2.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
ns2.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncHandler);
ns2.play(userList.selectedItem);
ns2.client=this;
video.attachNetStream(ns2);
video.width=288;
video.height=218;
chatVideo.addChild(video);
chatVideo.play();
}
private function sendBtnByClick(e:MouseEvent):void{
sendMsge();
}
private function sendBtnByKey(e:KeyboardEvent):void{
if(e.keyCode==Keyboard.ENTER&&e.ctrlKey==true)
{
sendMsge();
}
}
private function sendMsge():void{
var mess:String=username.text+"说:"+sendmessage.text+"\r\n";
if(username.text==userList.selectedItem){
Alert.show("您不能与自己聊天,请重新更换聊天对象");
return;
}
if(sendmessage.text==""){
Alert.show("发送信息不能为空");
return ;
}
if(userList.selectedItem=="所有人"){
nc.call("broadcastUserMsg",null,mess);
sendmessage.text="";
return;
}
if(userList.selectedItem!=null){
nc.call("msgFromPrivate",null,mess,username.text,userList.selectedItem);
sendmessage.text="";
}
}
public function showMsgByPrivate (msg:String):void{
txtmessage.text=txtmessage.text+msg;
}
]]>
</fx:Script>
<s:Panel id="login" title="欢迎您的访问" width="100%" height="100%">
<s:Label x="381" y="109" text="登 录" width="192" height="35" fontSize="25"
verticalAlign="middle" textAlign="center" fontWeight="normal" fontStyle="normal"/>
<s:Label x="353" y="167" text="用户名:" width="73" height="24" verticalAlign="middle"
fontSize="16"/>
<s:Label x="353" y="212" text="密 码:" width="73" height="24" verticalAlign="middle"
fontSize="16"/>
<s:TextInput id="username" x="446" y="168" width="154" textAlign="left"
maxChars="18"/>
<s:TextInput id="userpwd" x="445" y="214" width="154" textAlign="left"
displayAsPassword="true" maxChars="18"/>
<s:Button x="373" y="257" label="登录" id="btnsub" click="startConnect()"/>
<s:Button x="501" y="257" label="取消" id="cancel" click="navigateToURL(new URLRequest
('javascript:window.close()'),'_self')"/>
</s:Panel>
<s:Panel id="main" width="100%" height="100%">
<mx:VideoDisplay id="myVideo" x="468" y="276" width="288" height="217" />
<s:Group x="468" y="24" width="288" height="218">
<mx:VideoDisplay id="chatVideo" width="100%" height="100%"/>
<s:List id="userList" width="100%" height="100%" doubleClickEnabled="true"
doubleClick="updateVideoShow(event)" />
</s:Group>
<s:Button id="btnSend" x="279" y="519" label="发送"/>
<s:TextArea enabled="false" id="txtmessage" x="46" y="26" width="402" height="292"/>
<s:TextArea id="sendmessage" x="47" y="348" width="397" height="145"/>
<s:Button id="btnexit" x="374" y="519" label="退出"/>
</s:Panel>
</s:Application>
这个版本只是一个基本的实现功能,在界面上没有什么美化,但是理解起来应该比较简单,想学的人自己看吧。