Pages Menu
TwitterRssFacebook

Posted by on Jun 3, 2015 in Learn Skype Web SDK

Learn Skype Web SDK Day 25 : Listing & Changing Devices

Learn Skype Web SDK Day 25 : Listing & Changing Devices

[contemplate-1]
View Demo

You can make or receive audio and video calls with Skype Web SDK without ever worrying about what devices are going to be used – by default Skype Web SDK will choose some sensible defaults for you. However, eventually your users might wonder why they can’t select a different webcam, or you may want to offer them the option of switching between devices.

Preview Code Alert! – At the time of writing, the code on this page didn’t appear to work with Google Chrome. In addition, when used in Internet Explorer, some inconsistencies were seen with the list of speakers, with some devices being listed twice. Expect this to be resolved when the SDK goes to GA – but for now it’s something you’ll want to be aware of.

The chosen camera, microphone and speaker are managed in Skype Web SDK by the devicesManager. This object is accessible from the main client object, and lets you see:

  • a list of all cameras, microphones & speakers available to Skype Web SDK
  • the currently selected camera, microphone & speaker
  • events when cameras, microphones or speakers are added, removed, or the select device is changed
  • the ability to change the selected device

Like the rest of the SDK, this information is only surfaced when you ask for it and arrives asynchronously. Therefore, to build up a list of available cameras, you would first listen for the cameras.added event, then subscribe to the cameras collection:

client.devicesManager.cameras.added(function (newCamera) {
     $('#cameras')
         .append($("<option></option>")
         .attr("value",newCamera.id())
         .text(newCamera.id())); 

});

client.devicesManager.cameras.subscribe();

You can listen for selectedCamera in exactly the same way. The call to cameras.subscribe will ensure that the selectedCamera.changed event is also fired.

You can also subscribe to the cameras.removed event to receive notification of when the camera is no longer available (maybe it’s been pulled out or turned off!). If you’re maintaining a list of devices in your Skype Web SDK application this information will likely be useful.

To change the current camera you just set the selectedCamera object with the camera object you want to switch to. It’s that simple!

Listing and Changing using the microphones and speakers objects are exactly the same, with selectedMicrophone and selectedSpeaker objects.

The code sample for this post lists the currently selected camera, microphone and speaker. All available devices are also listed in drop-downs, and choosing a different device will make that device the selected device. For simplicity devices being removed isn’t supported in the example (but could be easily added):


  <div class="form-horizontal">
    <div class="form-group">
      <label for="username" class="col-sm-2 control-label">Username</label>
      <div class="col-sm-10">
        <input type="email" class="form-control" id="username" placeholder="Email">
      </div>
    </div>
    <div class="form-group">
      <label for="password" class="col-sm-2 control-label">Password</label>
      <div class="col-sm-10">
        <input type="password" class="form-control" id="password" placeholder="Password">
      </div>
    </div>

    <div class="form-group">
      <div class="col-sm-offset-2 col-sm-10">
        <button class="btn btn-default" id="btnLogIn">Log in</button>
      </div>
    </div>

    <div class="form-group">
      <div class="col-sm-offset-2 col-sm-10">
        <button class="btn btn-default" id="btnLogOut">Log out</button>
      </div>
    </div>
  </div>

  <div>
    <span id="loginStatus"></span><br/>
	<h3>
	Selected Camera: <span id="selectedCamera"></span><br/>
	Selected Microphone: <span id="selectedMicrophone"></span><br/>
	Selected Speaker: <span id="selectedSpeaker"></span><br/>
	</h3>
  </div>

  <hr/>

  <div class="form-horizontal">
    <div class="form-group">
      <label for="cameras" class="col-sm-2 control-label">Change Camera</label>
      <div class="col-sm-10">
       <select class="form-control" id="cameras"></select>
      </div>
    </div>  
	
	  <div class="form-group">
      <label for="mics" class="col-sm-2 control-label">Change Microphone</label>
      <div class="col-sm-10">
       <select class="form-control" id="mics"></select>
      </div>
    </div>  
	
	  <div class="form-group">
      <label for="speakers" class="col-sm-2 control-label">Change Speaker</label>
      <div class="col-sm-10">
       <select class="form-control" id="speakers"></select>
      </div>
    </div>  

   
  </div>
  

<div id="footer"></div>
  
  <!-- This is not needed for the samples to run, but adds standard headers and footers to the samples, to display title, instructions, about etc.
       If you're taking this code and using it yourself, you can remove this.-->
   <script type="text/javascript" src="../../assets/layoutcodesample-min.js"></script>
  
  <script type="text/javascript">

  <!-- These variables are only needed for laying out the code sample, they are not part of the sample code. -->
  var pageTitle = 'Choosing Different Devices';
  var blogPostLocation = "http://thoughtstuff.co.uk";
  var githubLocation = "http://github.com";
 


   var client;
  $(function () {
    'use strict';

	Skype.initialize({
            apiKey: 'SWX-BUILD-SDK',
        }, function (api) {
            client = new api.application();           
			
		// whenever client.state changes, display its value
		client.signInManager.state.changed(function (state) {
		$('#loginStatus').text("Login State: " + state);
		});
	
        }, function (err) {
            alert('Error loading Skype Web SDK: ' + err);
        }); 


    $('#btnLogIn').click(function () {

        // start signing in
        client.signInManager.signIn({
          username: $('#username').val(),
          password: $('#password').val()
        }).then(function () {
            //log in worked!
            alert('Logged in!');
           SubscribeToDevices();
            
          }, function (error) {
            //Something went wrong.
            alert(error);
          });
      });

    $('#btnLogOut').click(function () {
        // start signing out
        client.signInManager.signOut()
        .then(function () {
               //log out worked!
               alert('Logged out!');
               $('#btnStartConversation').prop('disabled', true);
             }, function (error) {
                //Something went wrong.
                alert(error);
              });
      });

	  //listen for changes to the device drop downs
 	   $('#cameras').change(function() {
	
	   var chosenCameraId = $('#cameras').val();
			client.devicesManager.cameras.get().then(function (list) {
			for(var i=0; i < list.length; i++)
		{
		var camera = list&#91;i&#93;;
		if (camera.id() == chosenCameraId)
		{
		  client.devicesManager.selectedCamera.set(camera);
		}		
		}
		
		});
	   });
   
    	$('#mics').change(function() {
	
	   var chosenMicId = $('#mics').val();
			client.devicesManager.microphones.get().then(function (list) {
			for(var i=0; i < list.length; i++)
		{
		var microphone = list&#91;i&#93;;
		if (microphone.id() == chosenMicId)
		{
		  client.devicesManager.selectedMicrophone.set(microphone);
		}		
		}
		
		});
	   });
	   
	    $('#speakers').change(function() {
	
	   var chosenSpeakerId = $('#speakers').val();
			client.devicesManager.speakers.get().then(function (list) {
			for(var i=0; i < list.length; i++)
		{
		var speaker = list&#91;i&#93;;
		if (speaker.id() == chosenSpeakerId)
		{
		  client.devicesManager.selectedSpeaker.set(speaker);
		}		
		}
		
		});
	   });



  function SubscribeToDevices () {
ListAvailableDevices();
ShowCurrentDevices(); 
 SubscribeToEvents();
 

}



function SubscribeToEvents()
{
  client.devicesManager.cameras.subscribe();
  client.devicesManager.microphones.subscribe();
  client.devicesManager.speakers.subscribe();
}

function ShowCurrentDevices()
{
 client.devicesManager.selectedCamera.changed(function (theCamera) {
	$('#selectedCamera').text(theCamera.id());
  });

  
  client.devicesManager.selectedMicrophone.changed(function (theMicrophone) {
	$('#selectedMicrophone').text(theMicrophone.id());
  });
  
  
  client.devicesManager.selectedSpeaker.changed(function (theSpeaker) {
	$('#selectedSpeaker').text(theSpeaker.id());
  });
  
}

function ListAvailableDevices()
{
//cameras
client.devicesManager.cameras.added(function (newCamera) {
     $('#cameras')
         .append($("<option></option>")
         .attr("value",newCamera.id())
         .text(newCamera.id())); 

});

//microphones
client.devicesManager.microphones.added(function (newMicrophone) {
     $('#mics')
         .append($("<option></option>")
         .attr("value",newMicrophone.id())
         .text(newMicrophone.id())); 
		 });
		 
//speakers
client.devicesManager.speakers.added(function (newSpeaker) {
     $('#speakers')
         .append($("<option></option>")
         .attr("value",newSpeaker.id())
         .text(newSpeaker.id())); 

});

}



});

</script>

Demo Online

You can try this code out against your own Skype for Business environment by going to the demo page. From here you can also download the code from GitHub if you want to host it locally, or take it and use it in your next project.
[contemplate-2]

Written by Tom Morgan

Tom is a Microsoft Teams Platform developer and Microsoft MVP who has been blogging for over a decade. Find out more.
Buy the book: Building and Developing Apps & Bots for Microsoft Teams. Now available to purchase online with free updates.

1 Comment

  1. News – MSN

Post a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.