Allow selecting audio output for WebRTC Audio/Video calls
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
bbdc27019a
commit
6636fa32f6
3 changed files with 50 additions and 8 deletions
src
|
@ -22,34 +22,44 @@ export default {
|
||||||
// Only needed for Electron atm, though should work in modern browsers
|
// Only needed for Electron atm, though should work in modern browsers
|
||||||
// once permission has been granted to the webapp
|
// once permission has been granted to the webapp
|
||||||
return navigator.mediaDevices.enumerateDevices().then(function(devices) {
|
return navigator.mediaDevices.enumerateDevices().then(function(devices) {
|
||||||
const audioIn = [];
|
const audiooutput = [];
|
||||||
const videoIn = [];
|
const audioinput = [];
|
||||||
|
const videoinput = [];
|
||||||
|
|
||||||
if (devices.some((device) => !device.label)) return false;
|
if (devices.some((device) => !device.label)) return false;
|
||||||
|
|
||||||
devices.forEach((device) => {
|
devices.forEach((device) => {
|
||||||
switch (device.kind) {
|
switch (device.kind) {
|
||||||
case 'audioinput': audioIn.push(device); break;
|
case 'audiooutput': audiooutput.push(device); break;
|
||||||
case 'videoinput': videoIn.push(device); break;
|
case 'audioinput': audioinput.push(device); break;
|
||||||
|
case 'videoinput': videoinput.push(device); break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log("Loaded WebRTC Devices", mediaDevices);
|
// console.log("Loaded WebRTC Devices", mediaDevices);
|
||||||
return {
|
return {
|
||||||
audioinput: audioIn,
|
audiooutput,
|
||||||
videoinput: videoIn,
|
audioinput,
|
||||||
|
videoinput,
|
||||||
};
|
};
|
||||||
}, (error) => { console.log('Unable to refresh WebRTC Devices: ', error); });
|
}, (error) => { console.log('Unable to refresh WebRTC Devices: ', error); });
|
||||||
},
|
},
|
||||||
|
|
||||||
loadDevices: function() {
|
loadDevices: function() {
|
||||||
|
const audioOutDeviceId = SettingsStore.getValue("webrtc_audiooutput");
|
||||||
const audioDeviceId = SettingsStore.getValue("webrtc_audioinput");
|
const audioDeviceId = SettingsStore.getValue("webrtc_audioinput");
|
||||||
const videoDeviceId = SettingsStore.getValue("webrtc_videoinput");
|
const videoDeviceId = SettingsStore.getValue("webrtc_videoinput");
|
||||||
|
|
||||||
|
Matrix.setMatrixCallAudioOutput(audioOutDeviceId);
|
||||||
Matrix.setMatrixCallAudioInput(audioDeviceId);
|
Matrix.setMatrixCallAudioInput(audioDeviceId);
|
||||||
Matrix.setMatrixCallVideoInput(videoDeviceId);
|
Matrix.setMatrixCallVideoInput(videoDeviceId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setAudioOutput: function(deviceId) {
|
||||||
|
SettingsStore.setValue("webrtc_audiooutput", null, SettingLevel.DEVICE, deviceId);
|
||||||
|
Matrix.setMatrixCallAudioOutput(deviceId);
|
||||||
|
},
|
||||||
|
|
||||||
setAudioInput: function(deviceId) {
|
setAudioInput: function(deviceId) {
|
||||||
SettingsStore.setValue("webrtc_audioinput", null, SettingLevel.DEVICE, deviceId);
|
SettingsStore.setValue("webrtc_audioinput", null, SettingLevel.DEVICE, deviceId);
|
||||||
Matrix.setMatrixCallAudioInput(deviceId);
|
Matrix.setMatrixCallAudioInput(deviceId);
|
||||||
|
|
|
@ -292,6 +292,7 @@ module.exports = React.createClass({
|
||||||
if (this._unmounted) return;
|
if (this._unmounted) return;
|
||||||
this.setState({
|
this.setState({
|
||||||
mediaDevices,
|
mediaDevices,
|
||||||
|
activeAudioOutput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_audiooutput'),
|
||||||
activeAudioInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_audioinput'),
|
activeAudioInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_audioinput'),
|
||||||
activeVideoInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_videoinput'),
|
activeVideoInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_videoinput'),
|
||||||
});
|
});
|
||||||
|
@ -970,6 +971,11 @@ module.exports = React.createClass({
|
||||||
return devices.map((device) => <span key={device.deviceId}>{ device.label }</span>);
|
return devices.map((device) => <span key={device.deviceId}>{ device.label }</span>);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setAudioOutput: function(deviceId) {
|
||||||
|
this.setState({activeAudioOutput: deviceId});
|
||||||
|
CallMediaHandler.setAudioOutput(deviceId);
|
||||||
|
},
|
||||||
|
|
||||||
_setAudioInput: function(deviceId) {
|
_setAudioInput: function(deviceId) {
|
||||||
this.setState({activeAudioInput: deviceId});
|
this.setState({activeAudioInput: deviceId});
|
||||||
CallMediaHandler.setAudioInput(deviceId);
|
CallMediaHandler.setAudioInput(deviceId);
|
||||||
|
@ -1010,6 +1016,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||||
|
|
||||||
|
let speakerDropdown = <p>{ _t('No Audio Outputs detected') }</p>;
|
||||||
let microphoneDropdown = <p>{ _t('No Microphones detected') }</p>;
|
let microphoneDropdown = <p>{ _t('No Microphones detected') }</p>;
|
||||||
let webcamDropdown = <p>{ _t('No Webcams detected') }</p>;
|
let webcamDropdown = <p>{ _t('No Webcams detected') }</p>;
|
||||||
|
|
||||||
|
@ -1018,6 +1025,26 @@ module.exports = React.createClass({
|
||||||
label: _t('Default Device'),
|
label: _t('Default Device'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const audioOutputs = this.state.mediaDevices.audiooutput.slice(0);
|
||||||
|
if (audioOutputs.length > 0) {
|
||||||
|
let defaultOutput = '';
|
||||||
|
if (!audioOutputs.some((input) => input.deviceId === 'default')) {
|
||||||
|
audioOutputs.unshift(defaultOption);
|
||||||
|
} else {
|
||||||
|
defaultOutput = 'default';
|
||||||
|
}
|
||||||
|
|
||||||
|
speakerDropdown = <div>
|
||||||
|
<h4>{ _t('Audio Output') }</h4>
|
||||||
|
<Dropdown
|
||||||
|
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||||
|
value={this.state.activeAudioOutput || defaultOutput}
|
||||||
|
onOptionChange={this._setAudioOutput}>
|
||||||
|
{ this._mapWebRtcDevicesToSpans(audioOutputs) }
|
||||||
|
</Dropdown>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
const audioInputs = this.state.mediaDevices.audioinput.slice(0);
|
const audioInputs = this.state.mediaDevices.audioinput.slice(0);
|
||||||
if (audioInputs.length > 0) {
|
if (audioInputs.length > 0) {
|
||||||
let defaultInput = '';
|
let defaultInput = '';
|
||||||
|
@ -1059,6 +1086,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
|
{ speakerDropdown }
|
||||||
{ microphoneDropdown }
|
{ microphoneDropdown }
|
||||||
{ webcamDropdown }
|
{ webcamDropdown }
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -201,6 +201,10 @@ export const SETTINGS = {
|
||||||
displayName: _td('Disable Peer-to-Peer for 1:1 calls'),
|
displayName: _td('Disable Peer-to-Peer for 1:1 calls'),
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"webrtc_audiooutput": {
|
||||||
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
"webrtc_audioinput": {
|
"webrtc_audioinput": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
default: null,
|
default: null,
|
||||||
|
|
Loading…
Reference in a new issue