diff --git a/public/main.js b/public/main.js index 3b15b32..f2986a4 100644 --- a/public/main.js +++ b/public/main.js @@ -51,8 +51,8 @@ peer.on('connection', (conn) => { // Handle incoming voice/video connection peer.on('call', (call) => { console.log('INCOMING CALL', call); - call.answer(stream); // Answer the call with an A/V stream. - renderVideo(stream, '#localVideo'); + call.answer(window.stream); // Answer the call with an A/V stream. + renderVideo(window.stream, '#localVideo'); call.on('stream', renderVideo); // navigator.mediaDevices.getUserMedia({video: true, audio: true}) // .then((stream) => { @@ -78,7 +78,7 @@ let connectToPeer = () => { conn.send('hi!'); }); - let call = peer.call(peerId, stream); + let call = peer.call(peerId, window.stream); call.on('stream', renderVideo); // navigator.mediaDevices.getUserMedia({video: true, audio: true}) // .then((stream) => { @@ -90,24 +90,136 @@ let connectToPeer = () => { // }); }; -let stream; let startLocalStream = () => { navigator.mediaDevices.getUserMedia({video: true, audio: true}) .then((localStream) => { console.log('LOCAL STREAM', localStream); renderVideo(localStream, '#localVideo'); - stream = localStream; + window.stream = localStream; }) .catch((err) => { console.log('Failed to get local stream', err); logMessage('Failed to get local stream', err); }); } -startLocalStream(); +// startLocalStream(); let disconnectFromPeer = () => { } window.disconnectFromPeer = disconnectFromPeer; -window.connectToPeer = connectToPeer; \ No newline at end of file +window.connectToPeer = connectToPeer; + + + +/* +* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. +* +* Use of this source code is governed by a BSD-style license +* that can be found in the LICENSE file in the root of the source +* tree. +*/ + +// 'use strict'; + +const videoElement = document.querySelector('#localVideo'); +const audioInputSelect = document.querySelector('select#audioSource'); +const audioOutputSelect = document.querySelector('select#audioOutput'); +const videoSelect = document.querySelector('select#videoSource'); +const selectors = [audioInputSelect, audioOutputSelect, videoSelect]; + +audioOutputSelect.disabled = !('sinkId' in HTMLMediaElement.prototype); + +function gotDevices(deviceInfos) { + // Handles being called several times to update labels. Preserve values. + const values = selectors.map(select => select.value); + selectors.forEach(select => { + while (select.firstChild) { + select.removeChild(select.firstChild); + } + }); + for (let i = 0; i !== deviceInfos.length; ++i) { + const deviceInfo = deviceInfos[i]; + const option = document.createElement('option'); + option.value = deviceInfo.deviceId; + if (deviceInfo.kind === 'audioinput') { + option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`; + audioInputSelect.appendChild(option); + } else if (deviceInfo.kind === 'audiooutput') { + option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`; + audioOutputSelect.appendChild(option); + } else if (deviceInfo.kind === 'videoinput') { + option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`; + videoSelect.appendChild(option); + } else { + console.log('Some other kind of source/device: ', deviceInfo); + } + } + selectors.forEach((select, selectorIndex) => { + if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) { + select.value = values[selectorIndex]; + } + }); +} + +navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError); + +// Attach audio output device to video element using device/sink ID. +function attachSinkId(element, sinkId) { + if (typeof element.sinkId !== 'undefined') { + element.setSinkId(sinkId) + .then(() => { + console.log(`Success, audio output device attached: ${sinkId}`); + }) + .catch(error => { + let errorMessage = error; + if (error.name === 'SecurityError') { + errorMessage = `You need to use HTTPS for selecting audio output device: ${error}`; + } + console.error(errorMessage); + // Jump back to first output device in the list as it's the default. + audioOutputSelect.selectedIndex = 0; + }); + } else { + console.warn('Browser does not support output device selection.'); + } +} + +function changeAudioDestination() { + const audioDestination = audioOutputSelect.value; + attachSinkId(videoElement, audioDestination); +} + +function gotStream(stream) { + window.stream = stream; // make stream available to console + videoElement.srcObject = stream; + // Refresh button list in case labels have become available + return navigator.mediaDevices.enumerateDevices(); +} + +function handleError(error) { + console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name); +} + +function start() { + if (window.stream) { + window.stream.getTracks().forEach(track => { + track.stop(); + }); + } + const audioSource = audioInputSelect.value; + const videoSource = videoSelect.value; + const constraints = { + audio: {deviceId: audioSource ? {exact: audioSource} : undefined}, + video: {deviceId: videoSource ? {exact: videoSource} : undefined} + }; + navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError); +} + +audioInputSelect.onchange = start; +audioOutputSelect.onchange = changeAudioDestination; + +videoSelect.onchange = start; + +start(); \ No newline at end of file diff --git a/views/index.html b/views/index.html index cd3413e..6c669d3 100644 --- a/views/index.html +++ b/views/index.html @@ -36,7 +36,22 @@ - +
Get available audio, video sources and audio output devices from mediaDevices.enumerateDevices()
+ then set the source for getUserMedia() using a deviceId constraint.