From 9bfcb90de299ae460eff4fd769feba1b27b4dd64 Mon Sep 17 00:00:00 2001 From: Ryan Rowland Date: Wed, 19 Oct 2016 15:19:46 -0700 Subject: [PATCH] Add examples for 1.4 Audio Selection and Volume Indicator features --- index.html | 17 ++++++++-- quickstart.js | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++- site.css | 42 +++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 4706abc..6c0703a 100644 --- a/index.html +++ b/index.html @@ -9,18 +9,31 @@

Twilio Client

+
+ + + +
+ Seeing unknown devices? +

Make a Call:

+
+ +


+ +
+
- + - \ No newline at end of file + diff --git a/quickstart.js b/quickstart.js index 056cd79..828b92a 100644 --- a/quickstart.js +++ b/quickstart.js @@ -1,4 +1,10 @@ $(function () { + var speakerDevices = document.getElementById('speaker-devices'); + var ringtoneDevices = document.getElementById('ringtone-devices'); + var outputVolumeBar = document.getElementById('output-volume'); + var inputVolumeBar = document.getElementById('input-volume'); + var volumeIndicators = document.getElementById('volume-indicators'); + log('Requesting Capability Token...'); $.getJSON('/token.php') .done(function (data) { @@ -21,12 +27,15 @@ log('Successfully established call!'); document.getElementById('button-call').style.display = 'none'; document.getElementById('button-hangup').style.display = 'inline'; + volumeIndicators.style.display = 'block'; + bindVolumeIndicators(conn); }); Twilio.Device.disconnect(function (conn) { log('Call ended.'); document.getElementById('button-call').style.display = 'inline'; document.getElementById('button-hangup').style.display = 'none'; + volumeIndicators.style.display = 'none'; }); Twilio.Device.incoming(function (conn) { @@ -43,6 +52,13 @@ }); setClientNameUI(data.identity); + + Twilio.Device.audio.on('deviceChange', updateAllDevices); + + // Show audio selection UI if it is supported by the browser. + if (Twilio.Device.audio.isSelectionSupported) { + document.getElementById('output-selection').style.display = 'block'; + } }) .fail(function () { log('Could not get a token from server!'); @@ -65,8 +81,76 @@ Twilio.Device.disconnectAll(); }; + document.getElementById('get-devices').onclick = function() { + navigator.mediaDevices.getUserMedia({ audio: true }) + .then(updateAllDevices); + }; + + speakerDevices.addEventListener('change', function() { + var selectedDevices = [].slice.call(speakerDevices.children) + .filter(function(node) { return node.selected; }) + .map(function(node) { return node.getAttribute('data-id'); }); + + Twilio.Device.audio.speakerDevices.set(selectedDevices); + }); + + ringtoneDevices.addEventListener('change', function() { + var selectedDevices = [].slice.call(ringtoneDevices.children) + .filter(function(node) { return node.selected; }) + .map(function(node) { return node.getAttribute('data-id'); }); + + Twilio.Device.audio.ringtoneDevices.set(selectedDevices); + }); + + function bindVolumeIndicators(connection) { + connection.volume(function(inputVolume, outputVolume) { + var inputColor = 'red'; + if (inputVolume < .50) { + inputColor = 'green'; + } else if (inputVolume < .75) { + inputColor = 'yellow'; + } + + inputVolumeBar.style.width = Math.floor(inputVolume * 300) + 'px'; + inputVolumeBar.style.background = inputColor; + + var outputColor = 'red'; + if (outputVolume < .50) { + outputColor = 'green'; + } else if (outputVolume < .75) { + outputColor = 'yellow'; + } + + outputVolumeBar.style.width = Math.floor(outputVolume * 300) + 'px'; + outputVolumeBar.style.background = outputColor; + }); + } + + function updateAllDevices() { + updateDevices(speakerDevices, Twilio.Device.audio.speakerDevices.get()); + updateDevices(ringtoneDevices, Twilio.Device.audio.ringtoneDevices.get()); + } }); +// Update the available ringtone and speaker devices +function updateDevices(selectEl, selectedDevices) { + selectEl.innerHTML = ''; + Twilio.Device.audio.availableOutputDevices.forEach(function(device, id) { + var isActive = (selectedDevices.size === 0 && id === 'default'); + selectedDevices.forEach(function(device) { + if (device.deviceId === id) { isActive = true; } + }); + + var option = document.createElement('option'); + option.label = device.label; + option.setAttribute('data-id', id); + if (isActive) { + option.setAttribute('selected', 'selected'); + } + selectEl.appendChild(option); + }); +} + // Activity log function log(message) { var logDiv = document.getElementById('log'); @@ -79,4 +163,4 @@ function setClientNameUI(clientName) { var div = document.getElementById('client-name'); div.innerHTML = 'Your client name: ' + clientName + ''; -} \ No newline at end of file +} diff --git a/site.css b/site.css index 77eb8b0..66c6f31 100644 --- a/site.css +++ b/site.css @@ -10,6 +10,14 @@ body { background: #272726; } +label { + text-align: left; + font-family: Helvetica, sans-serif; + font-size: 1.25em; + color: #777776; + display: block; +} + div#controls { padding: 3em; max-width: 1200px; @@ -26,6 +34,40 @@ div#controls { margin: 0 1.5em; text-align: center; } + div#controls div#info div#output-selection { + display: none; + } + + div#controls div#info a { + font-size: 1.1em; + color: khaki; + text-decoration: underline; + cursor: pointer; + } + + div#controls div#info select { + width: 300px; + height: 60px; + margin-bottom: 2em; + } + + div#controls div#info label { + width: 300px; + } + + div#controls div#call-controls div#volume-indicators { + display: none; + padding: 10px; + margin-top: 20px; + width: 500px; + text-align: left; + } + + div#controls div#call-controls div#volume-indicators > div { + display: block; + height: 20px; + width: 0; + } div#controls p.instructions { text-align: left;