Add a not yet complete audio out selection.
parent
bb9c07de3b
commit
e98d80ed57
|
|
@ -244,6 +244,8 @@ export default class RoomClient
|
||||||
|
|
||||||
this._audioDevices = {};
|
this._audioDevices = {};
|
||||||
|
|
||||||
|
this._audioOutputDevices = {};
|
||||||
|
|
||||||
// mediasoup Consumers.
|
// mediasoup Consumers.
|
||||||
// @type {Map<String, mediasoupClient.Consumer>}
|
// @type {Map<String, mediasoupClient.Consumer>}
|
||||||
this._consumers = new Map();
|
this._consumers = new Map();
|
||||||
|
|
@ -1107,6 +1109,50 @@ export default class RoomClient
|
||||||
meActions.setAudioInProgress(false));
|
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<audioElements; i++){
|
||||||
|
if (typeof audioElements[0].setSinkId === 'function'){
|
||||||
|
if (i === 0) logger.debug('changeAudioOutputDevice()');
|
||||||
|
await audioElements[i].setSinkId(deviceId);
|
||||||
|
} else {
|
||||||
|
logger.debug('changeAudioOutputDevice() | setSinkId not implemented');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
store.dispatch(settingsActions.setSelectedAudioOutputDevice(deviceId));
|
||||||
|
|
||||||
|
await this._updateAudioOutputDevices();
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
logger.error('changeAudioOutputDevice() failed: %o', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
meActions.setAudioOutputInProgress(false));
|
||||||
|
}
|
||||||
|
|
||||||
async changeVideoResolution(resolution)
|
async changeVideoResolution(resolution)
|
||||||
{
|
{
|
||||||
logger.debug('changeVideoResolution() [resolution: %s]', resolution);
|
logger.debug('changeVideoResolution() [resolution: %s]', resolution);
|
||||||
|
|
@ -2642,6 +2688,8 @@ export default class RoomClient
|
||||||
if (joinVideo && this._mediasoupDevice.canProduce('video'))
|
if (joinVideo && this._mediasoupDevice.canProduce('video'))
|
||||||
this.enableWebcam();
|
this.enableWebcam();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._updateAudioOutputDevices();
|
||||||
|
|
||||||
store.dispatch(roomActions.setRoomState('connected'));
|
store.dispatch(roomActions.setRoomState('connected'));
|
||||||
|
|
||||||
|
|
@ -3441,4 +3489,35 @@ export default class RoomClient
|
||||||
logger.error('_getWebcamDeviceId() failed:%o', error);
|
logger.error('_getWebcamDeviceId() failed:%o', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _updateAudioOutputDevices()
|
||||||
|
{
|
||||||
|
logger.debug('_updateAudioOutputDevices()');
|
||||||
|
|
||||||
|
// Reset the list.
|
||||||
|
this._audioOutputDevices = {};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.debug('_updateAudioOutputDevices() | calling enumerateDevices()');
|
||||||
|
|
||||||
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
|
||||||
|
for (const device of devices)
|
||||||
|
{
|
||||||
|
if (device.kind !== 'audiooutput')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this._audioOutputDevices[device.deviceId] = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
meActions.setAudioOutputDevices(this._audioOutputDevices));
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
logger.error('_updateAudioOutputDevices() failed:%o', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ beforeEach(() =>
|
||||||
me : {
|
me : {
|
||||||
audioDevices : null,
|
audioDevices : null,
|
||||||
audioInProgress : false,
|
audioInProgress : false,
|
||||||
|
audioOutputDevices : null,
|
||||||
|
audioOutputInProgress : false,
|
||||||
canSendMic : false,
|
canSendMic : false,
|
||||||
canSendWebcam : false,
|
canSendWebcam : false,
|
||||||
canShareFiles : false,
|
canShareFiles : false,
|
||||||
|
|
@ -72,11 +74,12 @@ beforeEach(() =>
|
||||||
windowConsumer : null
|
windowConsumer : null
|
||||||
},
|
},
|
||||||
settings : {
|
settings : {
|
||||||
advancedMode : true,
|
advancedMode : true,
|
||||||
displayName : 'Jest Tester',
|
displayName : 'Jest Tester',
|
||||||
resolution : 'ultra',
|
resolution : 'ultra',
|
||||||
selectedAudioDevice : 'default',
|
selectedAudioDevice : 'default',
|
||||||
selectedWebcam : 'soifjsiajosjfoi'
|
selectedAudioOutputDevice : 'default',
|
||||||
|
selectedWebcam : 'soifjsiajosjfoi'
|
||||||
},
|
},
|
||||||
toolarea : {
|
toolarea : {
|
||||||
currentToolTab : 'chat',
|
currentToolTab : 'chat',
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ export const setAudioDevices = (devices) =>
|
||||||
payload : { devices }
|
payload : { devices }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setAudioOutputDevices = (devices) =>
|
||||||
|
({
|
||||||
|
type : 'SET_AUDIO_OUTPUT_DEVICES',
|
||||||
|
payload : { devices }
|
||||||
|
});
|
||||||
|
|
||||||
export const setWebcamDevices = (devices) =>
|
export const setWebcamDevices = (devices) =>
|
||||||
({
|
({
|
||||||
type : 'SET_WEBCAM_DEVICES',
|
type : 'SET_WEBCAM_DEVICES',
|
||||||
|
|
@ -67,6 +73,12 @@ export const setAudioInProgress = (flag) =>
|
||||||
type : 'SET_AUDIO_IN_PROGRESS',
|
type : 'SET_AUDIO_IN_PROGRESS',
|
||||||
payload : { flag }
|
payload : { flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setAudioOutputInProgress = (flag) =>
|
||||||
|
({
|
||||||
|
type : 'SET_AUDIO_OUTPUT_IN_PROGRESS',
|
||||||
|
payload : { flag }
|
||||||
|
});
|
||||||
|
|
||||||
export const setWebcamInProgress = (flag) =>
|
export const setWebcamInProgress = (flag) =>
|
||||||
({
|
({
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@ export const setSelectedAudioDevice = (deviceId) =>
|
||||||
payload : { deviceId }
|
payload : { deviceId }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setSelectedAudioOutputDevice = (deviceId) =>
|
||||||
|
({
|
||||||
|
type : 'CHANGE_AUDIO_OUTPUT_DEVICE',
|
||||||
|
payload : { deviceId }
|
||||||
|
});
|
||||||
|
|
||||||
export const setSelectedWebcamDevice = (deviceId) =>
|
export const setSelectedWebcamDevice = (deviceId) =>
|
||||||
({
|
({
|
||||||
type : 'CHANGE_WEBCAM',
|
type : 'CHANGE_WEBCAM',
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,13 @@ const Settings = ({
|
||||||
audioDevices = Object.values(me.audioDevices);
|
audioDevices = Object.values(me.audioDevices);
|
||||||
else
|
else
|
||||||
audioDevices = [];
|
audioDevices = [];
|
||||||
|
|
||||||
|
let audioOutputDevices;
|
||||||
|
|
||||||
|
if (me.audioOutputDevices)
|
||||||
|
audioOutputDevices = Object.values(me.audioOutputDevices);
|
||||||
|
else
|
||||||
|
audioOutputDevices = [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|
@ -226,6 +233,46 @@ const Settings = ({
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
|
<form className={classes.setting} autoComplete='off'>
|
||||||
|
<FormControl className={classes.formControl}>
|
||||||
|
<Select
|
||||||
|
value={settings.selectedAudioOutputDevice || ''}
|
||||||
|
onChange={(event) =>
|
||||||
|
{
|
||||||
|
if (event.target.value)
|
||||||
|
roomClient.changeAudioOutputDevice(event.target.value);
|
||||||
|
}}
|
||||||
|
displayEmpty
|
||||||
|
name={intl.formatMessage({
|
||||||
|
id : 'settings.audio.output',
|
||||||
|
defaultMessage : 'Audio output device'
|
||||||
|
})}
|
||||||
|
autoWidth
|
||||||
|
className={classes.selectEmpty}
|
||||||
|
disabled={audioOutputDevices.length === 0 || me.audioOutputInProgress}
|
||||||
|
>
|
||||||
|
{ audioOutputDevices.map((audioOutput, index) =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<MenuItem key={index} value={audioOutput.deviceId}>{audioOutput.label}</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
{ 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'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</form>
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<form className={classes.setting} autoComplete='off'>
|
||||||
<FormControl className={classes.formControl}>
|
<FormControl className={classes.formControl}>
|
||||||
<Select
|
<Select
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,13 @@ const me = (state = initialState, action) =>
|
||||||
return { ...state, audioDevices: devices };
|
return { ...state, audioDevices: devices };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_AUDIO_OUTPUT_DEVICES':
|
||||||
|
{
|
||||||
|
const { devices } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, audioOutputDevices: devices };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_WEBCAM_DEVICES':
|
case 'SET_WEBCAM_DEVICES':
|
||||||
{
|
{
|
||||||
const { devices } = action.payload;
|
const { devices } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ const settings = (state = initialState, action) =>
|
||||||
return { ...state, selectedAudioDevice: action.payload.deviceId };
|
return { ...state, selectedAudioDevice: action.payload.deviceId };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'CHANGE_AUDIO_OUTPUT_DEVICE':
|
||||||
|
{
|
||||||
|
return { ...state, selectedAudioOutputDevice: action.payload.deviceId };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_DISPLAY_NAME':
|
case 'SET_DISPLAY_NAME':
|
||||||
{
|
{
|
||||||
const { displayName } = action.payload;
|
const { displayName } = action.payload;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue