24.3 Creating the Calling Client

The calling client should include the following functionality:

  • The user should be asked to log in before connecting to the FlashCom application and being allowed to place a call.

  • When the client first connects, the user should be presented with a button that enables him to place a call.

  • If the administrator is not online or otherwise cannot accept the call, the Place Call button should change to a Record button to allow the user to record a message.

  • If the user's call is accepted by the administrator, the client should display the video from both the calling client and the administrator client. Additionally, the client should play the audio from the administrator. The button should change to an End Call button, so the user can end the call.

Here are the steps to follow to create the calling client:

  1. Create a new Flash document named callingClient.fla and open it.

  2. Add the PushButton component symbol to the Library. You can do this by dragging an instance of the push button to the Stage and then deleting it.

  3. Add a new video symbol by choosing New Video from the Library panel's pop-up Options menu.

  4. Create a new movie clip symbol named videoMc.

  5. Edit videoMc, and create an instance of the video symbol within it so that the video symbol instance is placed at (0,0).

  6. Name the video symbol instance vid.

  7. Open the linkage properties for videoMc.

  8. Select the Export for ActionScript and Export on First Frame options and set the linkage identifier to VideoMcSymbol.

  9. Add the following code to the first frame of the main timeline:

    // NetDebug.as is part of Flash Remoting.
    #include "NetDebug.as"
    // Include MovieClip.as from Chapter 7 and TextField.as from Chapter 8.
    #include "MovieClip.as"
    #include "TextField.as"
    // Include Table.as and Forms.as from Chapter 11.
    #include "Table.as"
    #include "Forms.as"
    // Create the login form.
    function createLoginForm (  ) {
      // Create a login button.
      _root.attachMovie("FPushButtonSymbol", "loginBtn", _root.getNewDepth(  ));
      // When the user clicks the button to log in, connect the user to the FlashCom
      // application.
      loginBtn.onRelease = function (  ) {
        var un = _root.usernameField.text;
        _root.username = un;
        // Connect the user only if she has entered a username.
        if (un != "") {
          myConnection.connect("rtmp:/communicationCenterApp/", un);
      // Create a label for the input text field.
      _root.createAutoTextField("usernameLabel", _root.getNewDepth(  ));
      usernameLabel.text = "username: ";
      // Create the input text field for the user to enter a username.
      _root.createInputTextField("usernameField", _root.getNewDepth(  ));
      // Use a table to position the elements.
      f0tr0 = new TableRow(5, new TableColumn(5, usernameLabel), 
                              new TableColumn(5, usernameField));
      f0tr1 = new TableRow(5, new TableColumn(5, loginBtn));
      form0Table = new Table(5, 100, 100, f0tr0, f0tr1);
      // Add the elements to a form.
      form0 = new Form(  );
    // Create the form for the main screen.
    function createMainForm (  ) {
      // Create clips for displaying the calling client's and administrator's videos.
      _root.attachMovie("videoMcSymbol", "localVideoMc", _root.getNewDepth(  ));
      _root.attachMovie("videoMcSymbol", "remoteVideoMc", _root.getNewDepth(  ));
      // Create a button so the user can place a call.
      _root.attachMovie("FPushButtonSymbol", "makeCallBtn", _root.getNewDepth(  ));
      makeCallBtn.setLabel("place call");
      // Position the items using a table.
      f1tr0 = new TableRow(5, new TableColumn(5, makeCallBtn));
      f1tr1 = new TableRow(5, new TableColumn(5, localVideoMc), 
                              new TableColumn(5, remoteVideoMc));
      form1Table = new Table(5, 100, 100, f1tr0, f1tr1);
      // Add the elements to a form.
      form1 = new Form(  );
    // Create a multipage form so that only the login screen or the main application
    // screen is visible at once.
    function createMultiForm (  ) {
      mForm = new MultiPageForm(form0, form1);
    myConnection = new NetConnection(  );
    // When the user successfully connects to the FlashCom application, display the
    // main application form.
    myConnection.onStatus = function (infoObject) {
      if (infoObject.code == "NetConnection.Connect.Success") {
    // The acceptCall(  ) method is invoked by the FlashCom application when the
    // administrator accepts a call.
    myConnection.acceptCall = function (  ) {
      _root.doLiveCall(  );
    // The adminEndCall(  ) method is invoked when the administrator disconnects or
    // otherwise ends the call.
    myConnection.adminEndCall = function (  ) {
      _root.endCall(  );
    // The notAvailable(  ) method is invoked when the 
    // administrator does not accept the call. When this occurs, 
    // modify the button so that the user can record a message.
    myConnection.notAvailable = function (  ) {
      _root.makeCallBtn.setLabel("start recording");
    // The placeCall(  ) function is one of the 
    // button's callback functions. It invokes the 
    // server-side placeCall(  ) method to place a call to the administrator.
    function placeCall (  ) {
      myConnection.call("placeCall", null);
    // The response object for when the FlashCom application returns a message ID.
    messageIDRes = new Object(  );
    messageIDRes.onResult = function (result) {
    // The startRecord(  ) function is one of the callback functions for the button,
    // and it initiates the process for recording a message. The getMessageID(  ) 
    // method on the server is invoked to get a new message ID, and the result is
    // returned to the messageIDRes response object.
    function startRecord(pb) {
      pb.setLabel("stop recording");
      myConnection.call("getMessageID", messageIDRes);
    // The doLiveCall(  ) function is invoked when the administrator accepts a call.
    function doLiveCall (  ) {
      // Create the net stream to publish the calling client's video and audio.
      livePublishNs = new NetStream(myConnection);
      livePublishNs.attachVideo(Camera.get(  ));
      livePublishNs.attachAudio(Microphone.get(  ));
      livePublishNs.publish(username + "live", "live");
      // Create the net stream to subscribe to the administrator's video and audio.
      liveSubscribeNs = new NetStream(myConnection);
      // Add the local video to the local video object and add the administrator's
      // video to the remote video object.
      localVideoMc.vid.attachVideo(Camera.get(  ));
      // Modify the button behavior to allow the user to end the call.
      makeCallBtn.setLabel("end call");
    // The endCall(  ) function is invoked when a call is ended by either the calling
    // client or the administrator.
    function endCall (  ) {
      // Reset the button so the user can place another call.
      makeCallBtn.setLabel("place call");
      // Clear all the videos and net streams.
      livePublishNs.close(  );
      liveSubscribeNs.close(  );
      remoteVideoMc.vid.clear(  );
      localVideoMc.vid.clear(  );
      // Call the endCall(  ) method on the server.
      myConnection.call("endCall", null);
    // The doRecord(  ) function is invoked after a new message ID is returned from
    // the server.
    function doRecord(id) {
      // Create a net stream and attach the audio and video to it.
      publishNs = new NetStream(myConnection);
      publishNs.attachVideo(Camera.get(  ));
      publishNs.attachAudio(Microphone.get(  ));
      // Publish a recorded stream.
      publishNs.publish("message" + id, "record");
      // Invoke the recordMessageInfo(  ) method on the server.
      myConnection.call("recordMessageInfo", null, id);
      // Display the camera locally so the user can see what is being recorded.
      localVideoMc.vid.attachVideo(Camera.get(  ));
    // The stopRecord(  ) function is invoked when the user clicks on the button to 
    // stop recording a message.
    function stopRecord(pb) {
      // Clear the video and net stream.
      publishNs.close(  );
      localVideoMc.vid.clear(  );
    createLoginForm(  );
    createMainForm(  );
    createMultiForm(  );

Although there is a lot of code in the client, most of it is nothing you haven't seen before. There are two forms that you create and between which you can switch using a multipage form object. The remainder of the code is primarily user-initiated invocations of server-side functions.

    Part I: Local Recipes
    Part II: Remote Recipes