) Red5 video chat source code

Source: Internet
Author: User
Tags sendmsg

I have been busy for several days, and recently I have basically completed the red5 server.
To get familiar with the server code and the API, I made a multi-person chat room in the same model as that of the FMS. The basic functions include video, group chat, and private chat. It seems that no one has released such source code on the Internet. I just want to be a crab first!
Let's first look at the Code:
Server:
Application. Java
  

Package org. Jerry. videochat;

Import java. util .*;
Import org. red5.server. Adapter. applicationadapter;
Import org. red5.server. API. iconnection;
Import org. red5.server. API. iseries;
Import org. red5.server. API. Service. iservicecapableconnection;
Import org. red5.server. API. So. isharedobject;

Public class application extends applicationadapter {
// Attributes
Private iscope appscope;

Private string username;

Private isharedobject listso;

Private isharedobject msgso;

Private Map <string, iconnection> onlineclient = new hashmap <string, iconnection> ();

// Method
// Method triggered when the application starts running
Public Boolean appstart (iscope APP ){
If (! Super. appstart (APP )){
Return false;
}
Required bytes = app;
Return true;
}

// Method triggered when the client is connected
Public Boolean appconnect (iconnection Conn, object [] Params ){
Username = (string) Params [0];
// At login, the connection ID and connection information are mapped and stored in the online list
String link_id = conn. getclient (). GETID ();
Onlineclient. Put (username, Conn );
// Add attributes to the shared object in the user list
// Create a user list shared object
Listso = getjsondobject (jsonobject, "listso", false );
// Create a user chat content sharing object
Msgso = getdomaindobject (commandid, "msgso", false );
Listso. setattribute (link_id, username );
Return true;
}

// Broadcast messages
Public void broadcastusermsg (string MSG ){
// Public chat
// Refresh shared object attributes
Msgso. setattribute ("MSG", MSG );
}

// Private Chat Information
Public void msgfromprivate (string MSG, string from, string ){
Iservicecapableconnection fc = (iservicecapableconnection) onlineclient
. Get (from );
Iservicecapableconnection Tc = (iservicecapableconnection) onlineclient
. Get ();
FC. Invoke ("showmsgbyprivate", new object [] {MSG });
TC. Invoke ("showmsgbyprivate", new object [] {MSG });
}

// Triggered when the user disconnects
Public void appdisconnect (iconnection conn ){
String dis_link_id = conn. getclient (). GETID ();
String user = (string) listso. getattribute (dis_link_id );
// Delete the corresponding online record by ID
Onlineclient. Remove (User );
// Delete the attributes of the shared object in the user list
Listso. removeattribute (dis_link_id );
}
}

Client code:

Videochat.

Package
{
Import Fl. Controls. Button;
Import Fl. Controls. List;
Import Fl. Controls. textarea;
Import Fl. Controls. textinput;
Import Fl. Data. dataprovider;
Import Fl. Managers. stylemanager;
Import flash. display. Sprite;
Import flash. Events. asyncerrorevent;
Import flash. Events. event;
Import flash. Events. keyboardevent;
Import flash. Events. mouseevent;
Import flash. Events. netstatusevent;
Import flash. Events. securityerrorevent;
Import flash. Events. syncevent;
Import flash. Media. camera;
Import flash. Media. Microphone;
Import flash. Media. video;
Import flash.net. netconnection;
Import flash.net. netstream;
Import flash.net. Export dobject;
Import flash. Text. textfield;
Import flash. Text. textformat;
Import flash. UI. keyboard;

/**
*... Red5 video chat...
* @ Author Jerry
*/
Public class videochat extends sprite {
// Attributes
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: Export dobject;
Private var msgso: Export dobject;
Private var userarr: array;
Private var sendmsg: string;
Private var now: date;
Private var useridobj: object;

// Constructor
Public Function videochat (){
_ Init (); // Initialization
_ Setcomponentstyle (); // set the component style
_ Startconnect (); // start to connect to the server
}

// Initialization
Private function _ Init (){
IP = "192.168.0.10 ";
Redpath = "rtmp: //" + IP + "/videochat ";
NC = new netconnection ();
From. Text = "guest" + int (math. Random () * 1000 );
To. Text = "all ";
Now = new date ();
}

// Set the component style
Private function _ setcomponentstyle (){
VaR mytf: textformat = new textformat ();
Mytf. size = 12;
Mytf. font = "";
Stylemanager. setstyle ("textformat", mytf );
}

// Start the connection
Private function _ startconnect (){
NC. addeventlistener (netstatusevent. net_status, _ statushandler );
NC. addeventlistener (securityerrorevent. security_error, _ securityhandler );
NC. addeventlistener (asyncerrorevent. async_error, _ asynchandler );
NC. Connect (Redpath, from. Text );
NC. Client = this;
}

// Status listening
Private function _ statushandler (EVT: netstatusevent ){
If (evt.info. Code = "netconnection. Connect. Success "){
Chatcon. Text + = "connection successful! /N ";
_ Scrolltoend ();
_ Publishvideo (); // publish your own video
_ Setlistso (); // create a user list shared object
_ Setmsgso (); // create a speaker Information Sharing object
Sendbtn. addeventlistener (mouseevent. Click, _ sendbtnbyclick); // click send message
Stage. addeventlistener (keyboardevent. key_down, _ sendbtnbykey); // press enter to send the message.
}
If (evt.info. Code = "netconnection. Connect. Failed "){
Chatcon. Text + = "connection failed! /N ";
_ Scrolltoend ();
}
If (evt.info. Code = "netconnection. Connect. Closed "){
Chatcon. Text + = "Connection closed! /N ";
_ Scrolltoend ();
}
}

// Security listening
Private function _ securityhandler (EVT: securityerror ){
Chatcon. Text + = "security error! /N ";
_ Scrolltoend ();
}

// Asynchronous Error
Private function _ asynchandler (EVT: asyncerrorevent ){
Chatcon. Text + = "Asynchronous error! /N ";
_ Scrolltoend ();
}

// Publish your own video
Private function _ publishvideo (){
NS = new netstream (NC );
Cam = camera. getcamera ();
MIC = microphone. getmicrophone ();
Livevideo. 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 (from. Text, "live ");
Whosevideo. Text = from. Text + "video ";
}

// Create a user list shared object
Private function _ setlistso (){
Listso = export dobject. getremote ("listso", NC. Uri, false );
Listso. Connect (NC );
Listso. addeventlistener (syncevent. Sync, _ listsosynchandler );
}

// Create a speaker sharing object
Private function _ setmsgso (){
Msgso = export dobject. getremote ("msgso", NC. Uri, false );
Msgso. addeventlistener (syncevent. Sync, _ msgsosynchandler );
Msgso. Connect (NC );
}

// Events after the shared object in the user list is updated
Private function _ listsosynchandler (EVT: syncevent ){
_ Showuserlist (); // update the user list
// Add mouse events to the user list
Userlist. addeventlistener (mouseevent. Click, _ updatechatto );
Userlist. addeventlistener (mouseevent. double_click, _ updatevideoshow );
}

// Post-update event of the speaker Information Sharing object
Private function _ msgsosynchandler (EVT: syncevent ){
// Update the chat content
For (var I in msgso. Data ){
Chatcon.html text + = msgso. Data [I];
}
}

// Update the user list
Private function _ showuserlist (){
Userarr = new array ();
// User Group Update
For (var tmp in listso. Data ){
Userarr. Push (listso. Data [TMP]);
}


// Add dataprovider
VaR tmpdp: dataprovider = new dataprovider ();
For (VAR I = 0; I <userarr. length; I ++ ){
Tmpdp. additem ({label: userarr [I]});
}
// Sort names
Tmpdp. sorton ("label ");
// Add "everyone" to the top of the user list"
Tmpdp. additemat ({label: "All"}, 0 );
// Add the array to the list for display
Userlist. dataprovider = tmpdp;
}

// Update the chat object
Private function _ updatechatto (EVT: mouseevent ){
To. Text = userlist. selecteditem. label;
}

// Update video display and video text display
Private function _ updatevideoshow (EVT: mouseevent ){
NS2. = new netstream (NC );
If (from. Text = to. Text ){
// Display my videos
Ns2.close ();
Livevideo. Clear ();
Whosevideo. Text = "My videos ";
Livevideo. attachcamera (CAM );
}
Else {
// Display videos of others
Whosevideo. Text = to. Text + "video ";
Ns2.client = this;
Ns2.addeventlistener (netstatusevent. net_status, _ statushandler );
Ns2.addeventlistener (asyncerrorevent. async_error, _ asynchandler );
Livevideo. attachnetstream (NS2 );
Ns2.play (to. Text );
}
}

// Click send message
Private function _ sendbtnbyclick (EVT: mouseevent ){
_ Sendmsg ();
}

// Press enter to send the message
Private function _ sendbtnbykey (EVT: keyboardevent ){
If (EVT. keycode = keyboard. Enter ){
_ Sendmsg ();
}
}


// Sending information processing method
Private function _ sendmsg (){
Sendmsg = "<font color = '# ff0000'>" + from. text + "</font>" + "to" + "<font color = '# ff0000'>" +. text + "</font>" + "say" + "(" + "<font color = '# 0000ff'>" + now. gethours () + ":" + (now. getminutes () <10? "0" + now. getminutes (): Now. getminutes () + ":" + (now. getseconds () <10? "0" + now. getseconds (): Now. getseconds () + "</font>" + ")" + ":" + "/t" + msginput. text + "/N ";

If (from. Text = to. Text ){
// Do not speak to yourself
Chatcon. Text + = "sorry, you cannot speak to yourself! ";
_ Scrolltoend ();
}
Else if (msginput. Text = ""){
// The statement cannot be blank.
Chatcon. Text + = "Enter the speech content in the text box below! ";
_ Scrolltoend ();
}
Else if (to. Text = "all "){
// Call the server broadcast Method
NC. Call ("broadcastusermsg", null, sendmsg );
Msginput. Text = "";
}
Else {
// Private Chat
NC. Call ("msgfromprivate", null, sendmsg, from. Text, To. Text );
Msginput. Text = "";
}
}

// Scroll the scroll bar to the bottom
Private function _ scrolltoend (){
Chatcon. verticalscrollposition = chatcon. maxverticalscrollposition;
}

// Private Chat method (called by the server)
Public Function showmsgbyprivate (_ MSG: string ){
Chatcon.html text + = _ MSG;
_ Scrolltoend ();
}
}

}

The comments are still detailed. I think most people can understand them. If you really don't understand them, read the official API documentation of red5.

Here we need to talk about an episode in production.

In the FMS, the code for creating shared objects is written in the method enabled by the server. I thought it was feasible to use this method in red5, but the problem came out, the shared object mechanism of red5 is a little different from that of the FMS. The shared object mechanism of red5 is like this. After a shared object is created, it is disconnected after a client is connected, the shared object will be automatically destroyed. When a client is connected again, the server will automatically generate a shared object for the client (note: the shared object is "client "), because the previous client-registered event targets the destroyed server-side shared object, one occurs. In other words, it is "unexpected problems ".

In my tests, this problem was obviously exposed.

At first, I wrote the code for creating shared objects in the method for the server to start running, and then a strange phenomenon occurs: After a client is connected and disconnected at the beginning, log on again, and the user list displays only "everyone" (shared objects are used in the user list ). In another situation, this problem does not occur if a client is always connected to the server. What I thought at the time was that the producer dobject on the server may be destroyed. I found that the API could not find shared objects, so I could not verify my guess, so I had to give up and switch to Google. Google found an article, of course, in English. Fortunately, my English skills are enough to understand the content of the article, and I finally verified my guess. (PS: it seems that this problem does not occur when you use the room creation method. Because this test is not performed, you do not know the situation. You can modify it based on my code, I 'd better tell you the result. I am also a relatively lazy programmer .)

The source code is released here. As for the package source code, I can't do it because Baidu does not provide the upload, but if you want to leave an e-mail address, I will send it to you later. Share more, so that everyone can make progress together! Haha!

Also, you can go to the "corner stone conference" forum and the "open red5" forum to download them. I posted all the posts there.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.