Learn Skype Web SDK Day 23 : Mute, Hold and DTMF Tones
[contemplate-1]
View Demo
So, last time we looked at how to receive incoming audio calls, meaning you can make and receive audio calls using Skype Web SDK in your browser. Whilst that pretty much is the definition of nirvana, there is in fact even more you can do with audio.
Looking to the standard Skype for Business client for a moment, you’ll notice some features that you probably use every day without even thinking about it. Muting your microphone, for example. Or putting the call on hold. Or sending DTMF tones to navigate through IVR systems.
The great news is that the Skype Web SDK supports all three of these scenarios, and that’s the focus of today’s lesson. Why three new features in one lesson? Because they’re super-easy to pick up!
DTMF (Dual-Tone Multi Frequency) is the noise you hear when you press a keypad on a phone whilst in a call, and is used to navigate IVR systems, vote in phone surveys, and even by Skype for Business when dialling in to join a meeting. According to Wikipedia, DTMF is “an in-band telecommunication signaling system using the voice-frequency band over telephone lines between telephone equipment and other communications devices and switching centers. DTMF was first developed in the Bell System in the United States, and became known under the trademark Touch-Tone for use in push-button telephones supplied to telephone customers, starting in 1963.” So, now you know.
Muting
To provide a mute button for your users so they can sound off about their customers in private, simply set the isMuted
property of the selfParticipant
‘s audio object:
conversation.selfParticipant.audio.isMuted.set(!conversation.selfParticipant.audio.isMuted());
On Hold
For longer breaks, or to make another call, you can place the current call on hold by setting the onHold
property of the selfParticipant
‘s audio:
conversation.selfParticipant.audio.isOnHold.set(!conversation.selfParticipant.audio.isOnHold());
DTMF
To send DTMF tones, there’s a special method, sendDTMF, which takes the number you want to send:
conversation.audioService.sendDtmf("1");
<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> </div> <hr/> <div class="form-horizontal"> <div class="form-group"> <label for="contact" class="col-sm-2 control-label">Start Audio Call with:</label> <div class="col-sm-10"> <input type="email" class="form-control" id="contact" placeholder="Contact SIP Address"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button class="btn btn-default" id="btnStartConversation" disabled="disabled">Start</button> <button class="btn btn-default" id="btnStopConversation" disabled="disabled">Stop</button> <button class="btn btn-default" id="btnMute" disabled="disabled">Mute / Unmute</button> <button class="btn btn-default" id="btnHold" disabled="disabled">Hold / Resume</button> <button class="btn btn-default" id="btnSendDTMF" disabled="disabled">SendDTMF</button> </div> </div> </div> <div> <span id="audioStatus"></span> </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 = 'Mute, Hold &amp; DTMF Tones'; 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!'); $('#btnStartConversation').prop('disabled', false); $('#btnStopConversation').prop('disabled', false); $('#btnMute').prop('disabled', false); $('#btnHold').prop('disabled', false); $('#btnSendDTMF').prop('disabled', false); }, 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); $('#btnStopConversation').prop('disabled', true); $('#btnMute').prop('disabled', true); $('#btnHold').prop('disabled', true); $('#btnSendDTMF').prop('disabled', true); }, function (error) { //Something went wrong. alert(error); }); }); $('#btnStartConversation').click(function () { StartConversation($('#contact').val()); }); $('#btnStopConversation').click(function() { conversation.leave(); }); $('#btnMute').click(function() { conversation.selfParticipant.audio.isMuted.set(!conversation.selfParticipant.audio.isMuted()); }); $('#btnHold').click(function() { conversation.selfParticipant.audio.isOnHold.set(!conversation.selfParticipant.audio.isOnHold()); }); $('#btnSendDTMF').click(function() { conversation.audioService.sendDtmf("1"); }); function StartConversation (contactSIP) { //first, get the person to start a conversation with. Assume one person. var person; GetContactFromName(contactSIP).then(function (results) { results.forEach(function (result) { person = result.result; }); //create the conversation object conversation = client.conversationsManager.createConversation(); //add the person to the conversation by creating a conversation participant object var convParticipant = conversation.createParticipant(person); conversation.participants.add(convParticipant); //add the newly created conversation to the ConversationManager list client.conversationsManager.conversations.add(conversation); conversation.audioService.start(); //watch the audio state of the self-participant to see what's happening conversation.selfParticipant.audio.state.changed(function(newState) { $('#audioStatus').text("Audio State: " + newState); }); }); } function GetContactFromName(contactSIP) { var query = client.personsAndGroupsManager.createPersonSearchQuery(); query.text(contactSIP); query.limit(1); return query.getMore(); } }); </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]