Flash Video Chat¶
Example of a two-directional video chat in a native Flash / Flex application¶
This example is a two-directional video chat using a client Flash application executed as a simple swf file. The example demonstrates operation of a Flash video chat that allows two-directional video communication to the same example for iOS, Android or Web SDK.
The screenshot displays operation of the Flash video chat.
The interface contains input fields to authorize in the video chat:
- WCS server address
- user name (any unique one will do for the sake of testing)
Below the windows, there is a simple text chat to exchange messages.
The Invite
box contains a link to send to the second participant of the chat to invite him or her.
Example files¶
This example is a compiled SWF file embedded to an HTML page using Flex / ActionScript3 and MXML available at:
/usr/local/FlashphonerWebCallServer/client/examples/demo/streaming/flash_client/chat.html
- chat.html - example page
- chat/bin-debug/chat.swf - application file
Working with the source code of the example¶
To analyze the code, let’s take this version of the chat.mxml
file with the hash 8b4bafe2766e0a1b485c41a8c64da80c74070ff1
, located here. The result of compiling the chat.mxml
file is the example application chat.swf
. The compiled swf and the source code are available for download in the corresponding build 0.5.3.1894.
The main example file chat.mxml
is based on several files implementing ROOM API identical to the room-module.js for Web SDK implementation.
- Participant.as - an object describing a participant of the video chat
- RestAppCpmmunicator - an object responsible for sending sendData to the WCS server and receiving inbound messages
- Room.as - an object describing the “room” where all participants of the chat are
- RoomStatus.as - room statuses
- Session.as - an object describing connection to the server
- SessionStatus.as - session statuses
1. Accessing camera and microphone¶
During initialization the application gets access to the camera and the microphone
cam = Camera.getCamera();
localDisplay.attachCamera(cam);
mic = Microphone.getEnhancedMicrophone();
remoteDisplayHolder.addChild(remoteDisplay);
2. Connecting to the server¶
Then, we create a Session object and connect to the WCS server line 144
If connection to the server is successful, the joinRoom() method is invoked to join to the room.
session = new Session(url, username);
session.on(SessionStatus.FAILED, function():void{
setStatus(sessionStatus, SessionStatus.FAILED);
onLeft();
}).on(SessionStatus.DISCONNECTED, function():void {
setStatus(sessionStatus, SessionStatus.DISCONNECTED);
onLeft();
}).on(SessionStatus.ESTABLISHED, function():void {
setStatus(sessionStatus, SessionStatus.ESTABLISHED);
joinRoom();
});
session.connect();
3. Events handling¶
When the participant joins the room, the reactions to various events in the room are added
JOINED
- a new participant has joined the roomLEFT
- a participant has left the roomPUBLISHED
- a participant has published a video streamFAILED
- an error occurred wile communicating with the roomMESSAGE
- an inbound message from a participant in the room
session.join(this.roomName).on(RoomStatus.STATE, function(room:Room):void{
var participants:Array = room.getParticipants();
setInviteAddress(room);
if (participants.length > 0) {
var chatState:String = "participants: ";
for (var i:Number = 0; i < participants.length; i++) {
installParticipant(participants[i]);
chatState += participants[i].getName();
if (i != participants.length - 1) {
chatState += ",";
}
}
addMessage("chat", chatState);
} else {
addMessage("chat", " room is empty");
}
publishLocalMedia(room);
onJoined(room);
}).on(RoomStatus.JOINED, function(participant:Participant):void{
installParticipant(participant);
addMessage(participant.getName(), "joined");
}).on(RoomStatus.LEFT, function(participant:Participant):void{
removeParticipant();
addMessage(participant.getName(), "left");
}).on(RoomStatus.PUBLISHED, function(participant:Participant):void{
playParticipantsStream(participant);
}).on(RoomStatus.FAILED, function(room:Room, info:Object):void{
failedInfo.text = info.info;
session.disconnect();
}).on(RoomStatus.MESSAGE, function(message:Object):void{
addMessage(message.from.getName(), message.text);
});
4. Stream publishing¶
Publishing the video stream from the web camera to the WCS server
private function publishLocalMedia(room:Room):void {
var stream:NetStream = room.publish(mic, cam);
stream.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent):void{
Logger.info("handlePublishStreamStatus: "+event.info.code);
switch (event.info.code) {
case "NetStream.Publish.BadName":
setStatus(streamStatus, "FAILED");
onMediaStopped(room);
break;
case "NetStream.Unpublish.Success":
setStatus(streamStatus, "UNPUBLISHED");
onMediaStopped(room);
break;
case "NetStream.Publish.Start":
setStatus(streamStatus, "PUBLISHING");
onMediaPublished(stream);
break;
}
});
}
5. Stream playback¶
Playing the stream of another participant
private function playParticipantsStream(p:Participant):void
{
var stream:NetStream = p.play();
if (stream != null) {
remoteDisplay.attachNetStream(stream);
stream.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent):void{
Logger.info("handlePlayStreamStatus: "+event.info.code);
switch (event.info.code) {
case "NetStream.Video.DimensionChange":
var res:Object = downScaleToFitSize(remoteDisplay.videoWidth, remoteDisplay.videoHeight, display.width, display.height);
remoteDisplay.width = res.w;
remoteDisplay.height = res.h;
remoteDisplayHolder.width = res.w;
remoteDisplayHolder.height = res.h;
break;
case "NetStream.Play.UnpublishNotify":
case "NetStream.Play.Stop":
remoteDisplay.clear();
break;
}
});
}
}