Search code examples
apache-flexvideostreamred5flv

Simulating video chat using RTMP and Red5 without camera and microphone


I am trying to write an application, which will create load on a Red5 server, similar to a load created when a video chat is going on. Everything should run automatically. So, I am trying to understand how a chat application works. Here's what I found out. Please correct me if I am wrong:

User1 and User2 are chatting. A flex client is written, which will be run in the local of User1 and User2. The flex client User1 and User2 simultaneously will start recording a webcam video and microphone audio. This will create a raw video file (what is the format of this video?) streaming. A stream channel will be established with Red5. In the Flex code I will use NetConnection commands to establish a stream to the Red5 application. The raw audio n video from client side will be streamed to the server and will be saved as an FLV file. FLV file from User1 will be saved as .flv and FLV file from User2 will be saved as .flv. Now, User2 will establish a connection with Red5 to stream in .flv, and User1 will establish a connection with Red5 to stream in .flv. Each time the video is updated at any user side, the corresponding FLV file gets updated. The end user still has the stream open and the new video will now get streamed to the end user. This is how video chat works.

Now, if this is the correct understanding, I have the following questions:

  1. To simulate this chat without webcam and microphone, can I write a flex client to just upload an FLV file from client side to server side, through an established stream? From client side I will use NetConnection to connect to the stream. What kind of server side code should be written to receive that FLV from client to save on the server side? And, this streaming should be similar to the streaming of webcam video.

  2. How can I tell User2 to stream download the same FLV file, which has been uploaded by User1? I mean, suppose I want multiple users to "chat". That means, multiple streams are created. How will each end use know, which particular FLV file to download? Also, how will the end user know, when to start downloading the FLV file? User1 is continuously updating the FLV file, which is getting saved on server side. How will User2 know that the video file has been updated and it is time to stream it down.

Your help is appreciated!!


Solution

  • I suppose you are using Red5 1.0 Final version.

    Let's start by answering your question "what is the format of stream video?": Red5 can stream FLV video and MP3 audio, but it record only FLV (now red5 can stream h264 video).

    You asked about using FLV file to replace webcam (...) juste for testing, this is not a good idea, I "don't think" there is a simple way to do it. But you can create many virtual webcams using a third software like manycam.com to help you test your application.

    But if you are interested to upload (not publish - no real time) video to red5 server, so you can do it without red5 services, since red5 is a Tomcat server, so you can upload video just like in Java web application, forgot rtmp and use simple java http file upload, then you can broadcast this video.

    What kind of server side code should be written to receive that FLV? If you just need to stream video you don't have to do any think on server side! just create an application empty folder on red5/webapps/your_application_name. But if you need to do more, so you must implement your application.

    Next is a collection of commented codes that can help you with this!

    Stream Webcam/Microphone to red5 server: This is an exemple code how publish webcam/microphone from client_1 to red5 server:

    var nsOut:NetStream; //Out NetStream var cam:Camera; //camera instance var mic:Microphone;//microphone instance //"nc" is a NetConnection instance connected to red5 application. nsOut = new NetStream(nc); //setting the microphone mic = Microphone.getMicrophone(0); mic.codec = SoundCodec.SPEEX; mic.encodeQuality = 4; mic.setUseEchoSuppression(true); //setting the microphone try{ //Create camera instance using Camera.names array to choose the right one! cam = Camera.getCamera(Camera.names[0]); //Camera.names[1] for second camera and so on. //Camera Settings cam.setKeyFrameInterval (15); cam.setMode (240,180,15,false); cam.setMotionLevel (35,3000); cam.setQuality (40000 / 8,0); }catch(e:Error){ Alert.show("Webcam error!"); } nsOut.attachCamera (cam); // attach camera to NetStream nsOut.attachAudio(mic); //attach microphone to NetStream nsOut.publish ("client_1_stream"); //start streaming //finaly to show outgoing cam video var vid:Video = new Video(160,120); this.addChild (vid); vid.attachCamera(cam);

    Play video Stream: Now we have a NetStream "client_1_stream" published on Red5 server and ready to be played by other connected user, so this is how client_2 can show this stream:

    var nsIn:NetStream; //Incoming NetStream nsIn = new NetStream(nc); nsIn.play("client_1_stream"); //finaly to show incoming video var vid:Video = new Video(160,120); this.addChild(vid); vid.attachNetStream(nsIn);

    Now you have an idea about publish/play video, for this you don't need any server side codes.

    Upload file to red5 server: This is a good post about uploading file to red5 using java servlet. Upload file to Red5 server

    How can I tell client_2 to stream download the same FLV file, which has been uploaded by client_1?

    In this situation our goal is to send the uploaded file name to client_2 to play it. To complete this, client_1 must call a function on server side that call a function in client_2 code. client_1 function -- call --> server function -- call --> client_2 function.

    On client side we need tow functions, and one function on server side! The first client function named fileUploadSuccess() call a function on red5 application userFileUploded(fileName), finaly this function find the right user(s) and call the client_2 function named onFileUploadSuccess(fileName). fileUploadSuccess() -- call --> userFileUploded(fileName) -- call --> onFileUploadSuccess(fileName).

    This is a very known technique used on FMS and red5 application, you can find many exemple on line, else I can share some codes with you, if you need more help.

    You can also do this using red5 sharedObject, but personally I prefer the first solution.

    think you :)