From e98d80ed57ec3e71f3789cd4ed3bfd0a109e4c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sat, 18 Apr 2020 23:20:58 +0200 Subject: [PATCH 01/17] Add a not yet complete audio out selection. --- app/src/RoomClient.js | 79 +++++++++++++++++++++++++ app/src/__tests__/Room.spec.js | 13 ++-- app/src/actions/meActions.js | 12 ++++ app/src/actions/settingsActions.js | 6 ++ app/src/components/Settings/Settings.js | 47 +++++++++++++++ app/src/reducers/me.js | 7 +++ app/src/reducers/settings.js | 5 ++ 7 files changed, 164 insertions(+), 5 deletions(-) diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 8d0e01f..219cb10 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -244,6 +244,8 @@ export default class RoomClient this._audioDevices = {}; + this._audioOutputDevices = {}; + // mediasoup Consumers. // @type {Map} this._consumers = new Map(); @@ -1107,6 +1109,50 @@ export default class RoomClient meActions.setAudioInProgress(false)); } + async changeAudioOutputDevice(deviceId) + { + logger.debug('changeAudioOutputDevice() [deviceId: %s]', deviceId); + + store.dispatch( + meActions.setAudioOutputInProgress(true)); + + try + { + const device = this._audioOutputDevices[deviceId]; + + if (!device) + throw new Error('Selected audio output device no longer avaibale'); + + logger.debug( + 'changeAudioOutputDevice() | new selected [audio output device:%o]', + device); + + + + const audioElements = document.getElementById("audio"); + for( let i=0; i me : { audioDevices : null, audioInProgress : false, + audioOutputDevices : null, + audioOutputInProgress : false, canSendMic : false, canSendWebcam : false, canShareFiles : false, @@ -72,11 +74,12 @@ beforeEach(() => windowConsumer : null }, settings : { - advancedMode : true, - displayName : 'Jest Tester', - resolution : 'ultra', - selectedAudioDevice : 'default', - selectedWebcam : 'soifjsiajosjfoi' + advancedMode : true, + displayName : 'Jest Tester', + resolution : 'ultra', + selectedAudioDevice : 'default', + selectedAudioOutputDevice : 'default', + selectedWebcam : 'soifjsiajosjfoi' }, toolarea : { currentToolTab : 'chat', diff --git a/app/src/actions/meActions.js b/app/src/actions/meActions.js index fc72592..9c350da 100644 --- a/app/src/actions/meActions.js +++ b/app/src/actions/meActions.js @@ -50,6 +50,12 @@ export const setAudioDevices = (devices) => payload : { devices } }); +export const setAudioOutputDevices = (devices) => +({ + type : 'SET_AUDIO_OUTPUT_DEVICES', + payload : { devices } +}); + export const setWebcamDevices = (devices) => ({ type : 'SET_WEBCAM_DEVICES', @@ -67,6 +73,12 @@ export const setAudioInProgress = (flag) => type : 'SET_AUDIO_IN_PROGRESS', payload : { flag } }); + +export const setAudioOutputInProgress = (flag) => +({ + type : 'SET_AUDIO_OUTPUT_IN_PROGRESS', + payload : { flag } +}); export const setWebcamInProgress = (flag) => ({ diff --git a/app/src/actions/settingsActions.js b/app/src/actions/settingsActions.js index 79b5ef2..e66d437 100644 --- a/app/src/actions/settingsActions.js +++ b/app/src/actions/settingsActions.js @@ -4,6 +4,12 @@ export const setSelectedAudioDevice = (deviceId) => payload : { deviceId } }); +export const setSelectedAudioOutputDevice = (deviceId) => +({ + type : 'CHANGE_AUDIO_OUTPUT_DEVICE', + payload : { deviceId } +}); + export const setSelectedWebcamDevice = (deviceId) => ({ type : 'CHANGE_WEBCAM', diff --git a/app/src/components/Settings/Settings.js b/app/src/components/Settings/Settings.js index 91ba0db..4ad8c0c 100644 --- a/app/src/components/Settings/Settings.js +++ b/app/src/components/Settings/Settings.js @@ -130,6 +130,13 @@ const Settings = ({ audioDevices = Object.values(me.audioDevices); else audioDevices = []; + + let audioOutputDevices; + + if (me.audioOutputDevices) + audioOutputDevices = Object.values(me.audioOutputDevices); + else + audioOutputDevices = []; return ( +
+ + + + { audioOutputDevices.length > 0 ? + intl.formatMessage({ + id : 'settings.selectAudio.output', + defaultMessage : 'Select audio output device' + }) + : + intl.formatMessage({ + id : 'settings.cantSelectAudio.output', + defaultMessage : 'Unable to select audio output device' + }) + } + + +
diff --git a/app/src/reducers/settings.js b/app/src/reducers/settings.js index 590ac8f..0be91a8 100644 --- a/app/src/reducers/settings.js +++ b/app/src/reducers/settings.js @@ -24,9 +24,9 @@ const settings = (state = initialState, action) => } case 'CHANGE_AUDIO_OUTPUT_DEVICE': - { - return { ...state, selectedAudioOutputDevice: action.payload.deviceId }; - } + { + return { ...state, selectedAudioOutputDevice: action.payload.deviceId }; + } case 'SET_DISPLAY_NAME': { From 37d5fdeefc547ccf10d29565e4c9a7d61357a200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 22 Apr 2020 10:30:29 +0200 Subject: [PATCH 07/17] Proper state handling --- app/src/components/PeerAudio/AudioPeers.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/components/PeerAudio/AudioPeers.js b/app/src/components/PeerAudio/AudioPeers.js index 8109ac4..2b0a951 100644 --- a/app/src/components/PeerAudio/AudioPeers.js +++ b/app/src/components/PeerAudio/AudioPeers.js @@ -3,7 +3,6 @@ import { connect } from 'react-redux'; import { micConsumerSelector } from '../Selectors'; import PropTypes from 'prop-types'; import PeerAudio from './PeerAudio'; -import settings from '../../reducers/settings'; const AudioPeers = (props) => { @@ -21,7 +20,7 @@ const AudioPeers = (props) => ); }) @@ -39,7 +38,7 @@ AudioPeers.propTypes = const mapStateToProps = (state) => ({ micConsumers : micConsumerSelector(state), - audioOutputDevice : settings.selectedAudioOutputDevice + audioOutputDevice : state.settings.selectedAudioOutputDevice }); const AudioPeersContainer = connect( @@ -50,7 +49,8 @@ const AudioPeersContainer = connect( areStatesEqual : (next, prev) => { return ( - prev.consumers === next.consumers + prev.consumers === next.consumers && + prev.settings === next.settings ); } } From cdf899a948358f7b31d6623fb4074564f2622400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 22 Apr 2020 10:41:12 +0200 Subject: [PATCH 08/17] We don't need to change sink manualy. State, and React handles that for us. --- app/src/RoomClient.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 3712009..bc075b0 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -1127,16 +1127,6 @@ export default class RoomClient 'changeAudioOutputDevice() | new selected [audio output device:%o]', device); - const audioElements = document.getElementsByTagName('audio'); - - if (typeof audioElements[0].setSinkId === 'function') - { - for (let i = 0; i < audioElements.length; i++) - await audioElements[i].setSinkId(deviceId); - } - else - logger.debug('changeAudioOutputDevice() | setSinkId not implemented'); - store.dispatch(settingsActions.setSelectedAudioOutputDevice(deviceId)); await this._updateAudioOutputDevices(); From 1ea330059ebe02c55555818c5e2293359d2b6ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 22 Apr 2020 12:26:35 +0200 Subject: [PATCH 09/17] Change browser name to lowercase --- app/src/deviceInfo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/deviceInfo.js b/app/src/deviceInfo.js index deef6f5..6acdedf 100644 --- a/app/src/deviceInfo.js +++ b/app/src/deviceInfo.js @@ -26,7 +26,7 @@ export default function() flag, os : browser.getOSName(true), // ios, android, linux... platform : browser.getPlatformType(true), // mobile, desktop, tablet - name : browser.getBrowserName(), + name : browser.getBrowserName(true), version : browser.getBrowserVersion(), bowser : browser }; From 58b4aaf6c1d31814b9970c76bf2b92d1cb6a1f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 22 Apr 2020 12:29:29 +0200 Subject: [PATCH 10/17] Compare audioOutputDevice states --- app/src/components/PeerAudio/AudioPeers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/components/PeerAudio/AudioPeers.js b/app/src/components/PeerAudio/AudioPeers.js index 2b0a951..386990f 100644 --- a/app/src/components/PeerAudio/AudioPeers.js +++ b/app/src/components/PeerAudio/AudioPeers.js @@ -50,6 +50,7 @@ const AudioPeersContainer = connect( { return ( prev.consumers === next.consumers && + prev.audioOutputDevice === next.audioOutputDevice && prev.settings === next.settings ); } From 3236a18a0bdc8c42deb60bd341433358c86f33b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 22 Apr 2020 12:33:37 +0200 Subject: [PATCH 11/17] Limit audio output selection to chrome - whitelist --- app/src/components/Settings/Settings.js | 98 +++++++++++++------------ 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/app/src/components/Settings/Settings.js b/app/src/components/Settings/Settings.js index c5fa353..ad1d245 100644 --- a/app/src/components/Settings/Settings.js +++ b/app/src/components/Settings/Settings.js @@ -58,6 +58,7 @@ const Settings = ({ room, me, settings, + browser, onToggleAdvancedMode, onTogglePermanentTopBar, handleCloseSettings, @@ -233,51 +234,53 @@ const Settings = ({
-
- - - - { audioOutputDevices.length > 0 ? - intl.formatMessage({ - id : 'settings.selectAudioOutput', - defaultMessage : 'Select audio output device' - }) - : - intl.formatMessage({ - id : 'settings.cantSelectAudioOutput', - defaultMessage : 'Unable to select audio output device' - }) - } - - -
+ { browser.name === 'chrome' && +
+ + + + { audioOutputDevices.length > 0 ? + intl.formatMessage({ + id : 'settings.selectAudioOutput', + defaultMessage : 'Select audio output device' + }) + : + intl.formatMessage({ + id : 'settings.cantSelectAudioOutput', + defaultMessage : 'Unable to select audio output device' + }) + } + + +
+ }
me : state.me, room : state.room, settings : state.settings, - browser : state.me.browser, + browser : state.me.browser }; }; From 3caa505d08b64e4cfb0f3692d7354611fd83d6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 23 Apr 2020 21:52:33 +0200 Subject: [PATCH 14/17] Fix state mistake --- app/src/components/PeerAudio/AudioPeers.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/components/PeerAudio/AudioPeers.js b/app/src/components/PeerAudio/AudioPeers.js index 386990f..d02f26d 100644 --- a/app/src/components/PeerAudio/AudioPeers.js +++ b/app/src/components/PeerAudio/AudioPeers.js @@ -50,8 +50,7 @@ const AudioPeersContainer = connect( { return ( prev.consumers === next.consumers && - prev.audioOutputDevice === next.audioOutputDevice && - prev.settings === next.settings + prev.settings.selectedAudioOutputDevice === next.settings.selectedAudioOutputDevice ); } } From d06f44d1d48883354e8da7eefc2a316c75cff9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 23 Apr 2020 21:56:27 +0200 Subject: [PATCH 15/17] Remove redundant browser state, and tidy --- app/src/components/Settings/Settings.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/src/components/Settings/Settings.js b/app/src/components/Settings/Settings.js index 1945ef2..5a4a09a 100644 --- a/app/src/components/Settings/Settings.js +++ b/app/src/components/Settings/Settings.js @@ -58,7 +58,6 @@ const Settings = ({ room, me, settings, - browser, onToggleAdvancedMode, onTogglePermanentTopBar, handleCloseSettings, @@ -235,8 +234,8 @@ const Settings = ({
{ - window.config.audioOutputSupportedBrowsers && - window.config.audioOutputSupportedBrowsers.includes(browser.name) && + 'audioOutputSupportedBrowsers' in window.config && + window.config.audioOutputSupportedBrowsers.includes(me.browser.name) &&