Chatterbox VOIP in Windows Phone 8.1

Chatter box is an app that uses loop back video and audio to demonstrate the call management, audio and video capture and render, Push notifications and VOIP background agents.

This article discusses:

Structure a VOIP for Windows Phone
Capture and Render Audio/Video
Integrate streaming video in to the app’s UI
Setup a Microsoft Push Notification channel and use it to initiate a VOIP call.

This project has included with 3 more class libraries.

• Agents – This project implements the background agents that help manage the background process. These agents are written in managed code and run at various stages of the VoIP app life cycle such as when an incoming call arrives or when the foreground app is running.
• BackEnd – This project performs the work of managing call state, integrating with the phone’s built-in phone call processes, and managing audio and video streams. This project is written using the Windows Phone Runtime VoIP APIs like the VoIPCallCoordinator and the AudioRoutingManager.
• BackEndProxyStub – This is an out-of-process server written in C that enables communication between the foreground app and the background process.

We just consume these libraries for call management.

Make Outgoing call:

For CallController API, just pass the receipt name and receipt number as below.
CallController.InitiateOutgoingCall(this.RecipientName, this.recipientNumber);

Incoming call:
Send a Push notification to the Push channel URI of this app to simulate an incoming call as below

// Create an HTTPWebRequest that posts the raw notification to the Microsoft Push Notification Service.
// HTTP POST is the only method allowed to send the notification.
                HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(((App)App.Current).PushChannelUri);
                sendNotificationRequest.Method = "POST";

                 // Create the raw message.
                byte[] notificationMessage = null;
                 using (MemoryStream ms = new MemoryStream())
                    Agents.Notification notification = new Agents.Notification();
                    notification.Name = this.CallerName;
                    notification.Number = this.CallerNumber;

                    XmlSerializer xs = new XmlSerializer(typeof(Agents.Notification));
                    xs.Serialize(ms, notification);

                    notificationMessage = ms.ToArray();

                 // Set the required web request headers
                sendNotificationRequest.ContentLength = notificationMessage.Length;
                sendNotificationRequest.ContentType = "text/xml";
                 sendNotificationRequest.Headers["X-NotificationClass"] = "4"; // Class 4 indicates an incoming VoIP call

                 // Write the request body
                sendNotificationRequest.BeginGetRequestStream((IAsyncResult arRequest) =>
                          using (Stream requestStream = sendNotificationRequest.EndGetRequestStream(arRequest))
                               requestStream.Write(notificationMessage, 0, notificationMessage.Length);

                          // Get the response.
                        sendNotificationRequest.BeginGetResponse((IAsyncResult arResponse) =>
                                HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.EndGetResponse(arResponse);
                                string notificationStatus = response.Headers["X-NotificationStatus"];
                                string subscriptionStatus = response.Headers["X-SubscriptionStatus"];
                                string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

                                  // The push notification was sent
                                  this.ShowResult(string.Format("Notification: {0}\r\nSubscription: {1}\r\nDevice: {2}", notificationStatus, subscriptionStatus, deviceConnectionStatus));
                            catch (Exception ex)
                        }, null);

When you get an incoming call, the app’s call in progress screen will be displayed. At the top of the screen are buttons to switch the audio routing to different end points. At the bottom of the screen are buttons to end the call, put the call on hold, or switch video input between the front camera and the back camera. Behind the UI, the live video feed from the camera is shown in a small inset rectangle. Behind this, loopback video simulating incoming network video is shown.

Define the Media Element in UI to show video either from front camera or back camera.
  <MediaElement Visibility="{Binding BigHeadVisibility}" MediaOpened="bigHead_MediaOpened_1" MediaFailed="bigHead_MediaFailed_1" x:Name="bigHead" Source="{Binding BigHeadPreviewUri}" Width="456" Height="480" RenderTransformOrigin="0.5,0.5" >
                              <CompositeTransform Rotation="{Binding CameraRotation}"/>
                    <MediaElement Visibility="{Binding LittleHeadVisibility}" MediaOpened="littleHead_MediaOpened_1" MediaFailed="littleHead_MediaFailed_1" x:Name="littleHead" Source="{Binding LittleHeadPreviewUri}"  Canvas.Top="291" Width="160" Height="120" RenderTransformOrigin="0.5,0.5" >
                              <CompositeTransform Rotation="{Binding CameraRotation}"/>

Rendering Video:
if ((BackEnd.MediaOperations.VideoRender) != BackEnd.MediaOperations.None)
                     // Yes, we are rendering video
                     this.BigHeadPreviewUri = CallStatusViewModel.renderStreamUri;
                      this.BigHeadVisibility = Visibility.Visible;

Set MediaElement source and Rotation based on Front or back camera.
   if (newCameraLocation == BackEnd.CameraLocation.Front)
                     this.CameraToggleButtonText = CallStatusViewModel.CameraToggleBack;
                      this.LittleHeadPreviewUri = new Uri("ms-media-stream-id:camera-FrontFacing");
                    CameraRotation = -90;
                 else if (newCameraLocation == BackEnd.CameraLocation.Back)
                      this.LittleHeadPreviewUri = new Uri("ms-media-stream-id:camera-RearFacing");
                    CameraRotation = 90;

Hang Up Call:

Hold the call:
if (base.CallStatus == BackEnd.CallStatus.Held)
                 // The call is held - resume it
                 // The call is not held - put it on hold

Please refer the below link for detailed information


By Siva Jagan Dhulipalla   Popularity  (1956 Views)