Walkthrough: Change the Media Device in an Active Conversation (Lync 2010 SDK)
The Microsoft Lync 2010 conversation window includes a Settings option on the menu bar that lets you configure the audio or video device that you are using in a conversation. However, when you configure Lync 2010 to run in UI suppressed mode, conversations are hosted in a Microsoft Windows form that you create. To let a user switch media devices by using your conversation window, you write code that is patterned after the code in this walkthrough. The technique in this walkthrough is typically used to switch a conversation audio device between a unified communications-enabled desktop telephone and a USB audio headset. You can also use the code in this walkthrough to switch between two or more webcams installed on a computer.
Active Audio and Video Device Properties
The DeviceManager.ActiveVideoDevice and DeviceManager.ActiveAudioDevice properties represent the devices that are used in an active conversation or the default devices that are used in future conversations. To set the default device for a future conversation, you set the active device to one of the collection of devices of that type when no conversations are active. To configure the device that is used in an active conversation, you write to the same properties. However, to complete the configuration, you must also hold and retrieve the audio video modality.
Important
If you want to configure the default media device, then you must ensure that no conversations are active. When no conversations are active, you set the DeviceManager.ActiveVideoDevice property to the Microsoft.Lync.Model.Device.VideoDevice instance that you want as the default device. This rule is also true for audio devices.
Microsoft Lync 2010 API only returns audio devices that have both a microphone and speaker such as a headset with a microphone. A webcam does not have a speaker and is not considered an audio device.
Changing the media device that is used in an active conversation involves the following steps:
Get a list of installed audio and video devices.
Build a selection of UI device choices for users.
Respond to user’s device selection by placing the audio/video modality on hold.
When modality is on hold, ensure that the active device matches the user’s choice.
Cancel modality hold status and then resume call with new device.
Declaring Private Class Fields
The following example declares the class fields that are used to support the examples in this walkthrough. The walkthrough shows only the code that switches webcams. For a complete example of a video conversation, see Walkthrough: Start a Video Conversation (Lync 2010 SDK).
#region private fields
LyncClient _LyncClient = null;
/// <summary>
/// The audio/video modality of _Conversation
/// </summary>
private AVModality _AVModality;
/// <summary>
/// The video channel of the audio/video modality of _Conversation.
/// </summary>
private VideoChannel _VideoChannel;
/// <summary>
/// Holds a reference to the conversation initiated locally with the "Start Conversation" button.
/// or remotely when a user calls the local user
/// </summary>
private Conversation _Conversation = null;
#endregion
Getting Installed Webcams
Before you write code to obtain installed webcams, add the following line before the namespace declaration: Using Microsoft.Lync.Model.Device;. This code adds the Lync 2010 API namespace that contains the media device-related classes that you need.
To display a list of webcams that are installed on a computer, you should first verify the number of installed webcams on the Lync client platform. These webcams are represented by a collection of video devices whose Device.Name property is used to fill the list that appears in your UI.
To get installed webcams
Get the device manager by reading the LyncClient.DeviceManager property.
Ensure that webcams are installed on the computer. Read the DeviceManager.AudioDevicesCount property. The returned value is the number of webcams installed on the computer.
Iterate on the collection of webcams that are exposed by the VideoDevices property.
Read the Name property on the Microsoft.Lync.Model.Device.VideoDevice instance and then add the returned string to your UI list.
The following example declares a UI list that is displayed in a custom conversation window.
private System.Windows.Forms.ComboBox WebCam_ComboBox;
//
// WebCam_ComboBox
//
this.WebCam_ComboBox.FormattingEnabled = true;
this.WebCam_ComboBox.Location = new System.Drawing.Point(85, 315);
this.WebCam_ComboBox.Name = "WebCam_ComboBox";
this.WebCam_ComboBox.Size = new System.Drawing.Size(190, 21);
this.WebCam_ComboBox.TabIndex = 33;
this.WebCam_ComboBox.SelectedIndexChanged += new System.EventHandler(this.WebCam_ComboBox_SelectedIndexChanged);
The following example gets the video devices that are installed on a computer and then adds the device names to the list declared in the previous example.
/// <summary>
/// Loads active webcam device names into webcam_combobox
/// </summary>
private void LoadWebcams()
{
//Empty any previously loaded webcam names.
WebCam_ComboBox.Items.Clear();
//If no webcam devices are installed on the computer, then the Count property
//is zero.
if (_LyncClient.DeviceManager.VideoDevices.Count > 0)
{
foreach (Device videoDevice in _LyncClient.DeviceManager.VideoDevices)
{
WebCam_ComboBox.Items.Add(videoDevice.Name);
}
}
}
Responding to User Request to Change Webcam
When a user selects a webcam from the list that is loaded in the previous example, the conversation audio/video modality is put on hold. The webcam is switched after the modality hold operation is complete. The webcam switching logic appears in the next code example.
The following example handles the selected index changed event that is raised when a user selects a webcam.
/// <summary>
/// Handles the event raised when a user selects a webcam from the UI list
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WebCam_ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox sendingBox = (ComboBox)sender;
// Place the conversation on hold so that the webcam can be switched.
_Conversation.Modalities[ModalityTypes.AudioVideo].BeginHold(HoldCallback, sendingBox.SelectedItem.ToString());
}
Switching the Conversation Webcams in the BeginHold Callback
When the modality hold operation is complete, the Lync 2010 platform invokes the callback method that you supply as the first argument of the Modality.BeginHold method. Use the callback method to switch the webcam.
To switch the conversation webcam
Check the IsCompleted property of IAsyncResult. If the property value is true, the hold operation is complete.
End the modality hold operation by calling the Modality.EndHold method.
Iterate on the collection of video devices that are returned by reading the value of the DeviceManager.VideoDevices property.
Compare the name of each video device in the collection to the user’s selected video device name.
When a match is found, set the corresponding video device as the new value of the DeviceManager.ActiveVideoDevice property.
Retrieve the video modality from hold by calling the Modality.BeginRetrieve method.
The following example is invoked by the Lync 2010 platform when the modality hold operation is complete.
/// <summary>
/// Invoked when the modality hold operation is completed. A video device whose name matches a
/// user's choice is found, the corresponding video device is set as active device, and the
/// held call is retrieved.
/// </summary>
/// <param name="ar"></param>
private void HoldCallback(IAsyncResult ar)
{
if (ar.IsCompleted == true)
{
// end the modality hold operation
_Conversation.Modalities[ModalityTypes.AudioVideo].EndHold(ar);
// look for a video device in the collection of installed video devices that
// match the name chosen by user from the webcam list on the UI
foreach (Device d in _ClientModel.Lync_Client.DeviceManager.VideoDevices)
{
if (d.Name == ar.AsyncState.ToString())
{
// Set the active video device.
_ClientModel.Lync_Client.DeviceManager.ActiveVideoDevice = (VideoDevice)d;
break;
}
}
// Retrieve the video modality that was placed on hold. The new webcam will be used when
// the retrieve operation is completed.
_Conversation.Modalities[ModalityTypes.AudioVideo].EndRetrieve(
_Conversation.Modalities[ModalityTypes.AudioVideo].BeginRetrieve(RetreiveCallback, null));
}
}