Cleaning up device handling. Now able to change devices properly when audio/video is disabled.

auto_join_3.3
Håvar Aambø Fosstveit 2020-05-20 23:57:41 +02:00
parent 425fd1a92b
commit 0654acded8
1 changed files with 116 additions and 124 deletions

View File

@ -1128,66 +1128,85 @@ export default class RoomClient
async changeAudioDevice(deviceId) async changeAudioDevice(deviceId)
{ {
logger.debug('changeAudioDevice() [deviceId: %s]', deviceId); logger.debug('changeAudioDevice() [deviceId:"%s"]', deviceId);
store.dispatch( store.dispatch(
meActions.setAudioInProgress(true)); meActions.setAudioInProgress(true));
store.dispatch(settingsActions.setSelectedAudioDevice(deviceId));
if (!this._micProducer)
{ // If mic disabled, enable it, device is correct from settings
this.enableMic();
return;
}
let track;
try try
{ {
const device = this._audioDevices[deviceId]; const device = await this._getAudioDeviceId();
if (!device) if (!device)
throw new Error('no audio devices'); throw new Error('no audio devices');
logger.debug(
'changeAudioDevice() | new selected webcam [device:%o]',
device);
this.disconnectLocalHark(); this.disconnectLocalHark();
if (this._micProducer && this._micProducer.track) const {
this._micProducer.track.stop(); sampleRate,
channelCount,
logger.debug('changeAudioDevice() | calling getUserMedia() %o', store.getState().settings); volume,
autoGainControl,
echoCancellation,
noiseSuppression,
sampleSize
} = store.getState().settings;
const stream = await navigator.mediaDevices.getUserMedia( const stream = await navigator.mediaDevices.getUserMedia(
{ {
audio : audio :
{ {
deviceId : { ideal: device.deviceId }, deviceId : { ideal: device },
sampleRate : store.getState().settings.sampleRate, sampleRate,
channelCount : store.getState().settings.channelCount, channelCount,
volume : store.getState().settings.volume, volume,
autoGainControl : store.getState().settings.autoGainControl, autoGainControl,
echoCancellation : store.getState().settings.echoCancellation, echoCancellation,
noiseSuppression : store.getState().settings.noiseSuppression, noiseSuppression,
sampleSize : store.getState().settings.sampleSize sampleSize
} }
} }
); );
logger.debug('Constraints: %o', stream.getAudioTracks()[0].getConstraints()); ([ track ] = stream.getAudioTracks());
const track = stream.getAudioTracks()[0];
if (this._micProducer) await this._micProducer.replaceTrack({ track });
await this._micProducer.replaceTrack({ track });
if (this._micProducer) store.dispatch(
this._micProducer.volume = 0; producerActions.setProducerTrack(this._micProducer.id, track));
this.connectLocalHark(track);
if (this._micProducer && this._micProducer.id)
store.dispatch(
producerActions.setProducerTrack(this._micProducer.id, track));
store.dispatch(settingsActions.setSelectedAudioDevice(deviceId));
await this._updateAudioDevices(); await this._updateAudioDevices();
this._micProducer.volume = 0;
this.connectLocalHark(track);
} }
catch (error) catch (error)
{ {
logger.error('changeAudioDevice() failed: %o', error); logger.error('changeAudioDevice() [error:"%o"]', error);
store.dispatch(requestActions.notify(
{
type : 'error',
text : intl.formatMessage({
id : 'devices.microphoneError',
defaultMessage : 'An error occurred while accessing your microphone'
})
}));
if (track)
track.stop();
} }
store.dispatch( store.dispatch(
@ -1196,7 +1215,7 @@ export default class RoomClient
async changeAudioOutputDevice(deviceId) async changeAudioOutputDevice(deviceId)
{ {
logger.debug('changeAudioOutputDevice() [deviceId: %s]', deviceId); logger.debug('changeAudioOutputDevice() [deviceId:"%s"]', deviceId);
store.dispatch( store.dispatch(
meActions.setAudioOutputInProgress(true)); meActions.setAudioOutputInProgress(true));
@ -1206,11 +1225,7 @@ export default class RoomClient
const device = this._audioOutputDevices[deviceId]; const device = this._audioOutputDevices[deviceId];
if (!device) if (!device)
throw new Error('Selected audio output device no longer avaibale'); throw new Error('Selected audio output device no longer available');
logger.debug(
'changeAudioOutputDevice() | new selected [audio output device:%o]',
device);
store.dispatch(settingsActions.setSelectedAudioOutputDevice(deviceId)); store.dispatch(settingsActions.setSelectedAudioOutputDevice(deviceId));
@ -1218,7 +1233,7 @@ export default class RoomClient
} }
catch (error) catch (error)
{ {
logger.error('changeAudioOutputDevice() failed: %o', error); logger.error('changeAudioOutputDevice() [error:"%o"]', error);
} }
store.dispatch( store.dispatch(
@ -1304,79 +1319,64 @@ export default class RoomClient
async changeWebcam(deviceId) async changeWebcam(deviceId)
{ {
logger.debug('changeWebcam() [deviceId: %s]', deviceId); logger.debug('changeWebcam() [deviceId:"%s"]', deviceId);
store.dispatch( store.dispatch(
meActions.setWebcamInProgress(true)); meActions.setWebcamInProgress(true));
store.dispatch(settingsActions.setSelectedWebcamDevice(deviceId));
if (!this._webcamProducer)
{ // If webcam disabled, enable it, device is correct
this.enableWebcam();
return;
}
let track;
try try
{ {
const device = this._webcams[deviceId]; const device = await this._getWebcamDeviceId();
const resolution = store.getState().settings.resolution; const resolution = store.getState().settings.resolution;
if (!device) if (!device)
throw new Error('no webcam devices'); throw new Error('no webcam devices');
logger.debug(
'changeWebcam() | new selected webcam [device:%o]',
device);
if (this._webcamProducer && this._webcamProducer.track)
this._webcamProducer.track.stop();
logger.debug('changeWebcam() | calling getUserMedia()');
const stream = await navigator.mediaDevices.getUserMedia( const stream = await navigator.mediaDevices.getUserMedia(
{ {
video : video :
{ {
deviceId : { exact: device.deviceId }, deviceId : { exact: device },
...VIDEO_CONSTRAINS[resolution] ...VIDEO_CONSTRAINS[resolution]
} }
}); });
if (stream) ([ track ] = stream.getVideoTracks());
{
const track = stream.getVideoTracks()[0];
if (track) if (this._webcamProducer)
{ await this._webcamProducer.replaceTrack({ track });
if (this._webcamProducer)
{
await this._webcamProducer.replaceTrack({ track });
}
else
{
this._webcamProducer = await this._sendTransport.produce({
track,
appData :
{
source : 'webcam'
}
});
}
store.dispatch( store.dispatch(
producerActions.setProducerTrack(this._webcamProducer.id, track)); producerActions.setProducerTrack(this._webcamProducer.id, track));
}
else
{
logger.warn('getVideoTracks Error: First Video Track is null');
}
}
else
{
logger.warn('getUserMedia Error: Stream is null!');
}
store.dispatch(settingsActions.setSelectedWebcamDevice(deviceId));
await this._updateWebcams(); await this._updateWebcams();
} }
catch (error) catch (error)
{ {
logger.error('changeWebcam() failed: %o', error); logger.error('changeWebcam() [error:"%o"]', error);
store.dispatch(requestActions.notify(
{
type : 'error',
text : intl.formatMessage({
id : 'devices.cameraError',
defaultMessage : 'An error occurred while accessing your camera'
})
}));
if (track)
track.stop();
} }
store.dispatch( store.dispatch(
@ -3309,12 +3309,6 @@ export default class RoomClient
if (!device) if (!device)
throw new Error('no webcam devices'); throw new Error('no webcam devices');
logger.debug(
'addExtraVideo() | new selected webcam [device:%o]',
device);
logger.debug('_setWebcamProducer() | calling getUserMedia()');
const stream = await navigator.mediaDevices.getUserMedia( const stream = await navigator.mediaDevices.getUserMedia(
{ {
video : video :
@ -3324,7 +3318,7 @@ export default class RoomClient
} }
}); });
track = stream.getVideoTracks()[0]; ([ track ] = stream.getVideoTracks());
let producer; let producer;
@ -3434,6 +3428,8 @@ export default class RoomClient
async enableMic() async enableMic()
{ {
logger.debug('enableMic()');
if (this._micProducer) if (this._micProducer)
return; return;
@ -3458,30 +3454,32 @@ export default class RoomClient
if (!device) if (!device)
throw new Error('no audio devices'); throw new Error('no audio devices');
logger.debug( const {
'enableMic() | new selected audio device [device:%o]', sampleRate,
device); channelCount,
volume,
logger.debug('enableMic() | calling getUserMedia()'); autoGainControl,
echoCancellation,
noiseSuppression,
sampleSize
} = store.getState().settings;
const stream = await navigator.mediaDevices.getUserMedia( const stream = await navigator.mediaDevices.getUserMedia(
{ {
audio : { audio : {
deviceId : { ideal: device.deviceId }, deviceId : { ideal: device.deviceId },
sampleRate : store.getState().settings.sampleRate, sampleRate,
channelCount : store.getState().settings.channelCount, channelCount,
volume : store.getState().settings.volume, volume,
autoGainControl : store.getState().settings.autoGainControl, autoGainControl,
echoCancellation : store.getState().settings.echoCancellation, echoCancellation,
noiseSuppression : store.getState().settings.noiseSuppression, noiseSuppression,
sampleSize : store.getState().settings.sampleSize sampleSize
} }
} }
); );
logger.debug('Constraints: %o', stream.getAudioTracks()[0].getConstraints()); ([ track ] = stream.getAudioTracks());
track = stream.getAudioTracks()[0];
this._micProducer = await this._sendTransport.produce( this._micProducer = await this._sendTransport.produce(
{ {
@ -3535,11 +3533,10 @@ export default class RoomClient
this._micProducer.volume = 0; this._micProducer.volume = 0;
this.connectLocalHark(track); this.connectLocalHark(track);
} }
catch (error) catch (error)
{ {
logger.error('enableMic() failed:%o', error); logger.error('enableMic() [error:"%o"]', error);
store.dispatch(requestActions.notify( store.dispatch(requestActions.notify(
{ {
@ -3590,6 +3587,8 @@ export default class RoomClient
async enableScreenSharing() async enableScreenSharing()
{ {
logger.debug('enableScreenSharing()');
if (this._screenSharingProducer) if (this._screenSharingProducer)
return; return;
@ -3611,15 +3610,13 @@ export default class RoomClient
if (!available) if (!available)
throw new Error('screen sharing not available'); throw new Error('screen sharing not available');
logger.debug('enableScreenSharing() | calling getUserMedia()');
const stream = await this._screenSharing.start({ const stream = await this._screenSharing.start({
width : 1920, width : 1920,
height : 1080, height : 1080,
frameRate : 5 frameRate : 5
}); });
track = stream.getVideoTracks()[0]; ([ track ] = stream.getVideoTracks());
if (this._useSharingSimulcast) if (this._useSharingSimulcast)
{ {
@ -3757,6 +3754,7 @@ export default class RoomClient
async enableWebcam() async enableWebcam()
{ {
logger.debug('enableWebcam()');
if (this._webcamProducer) if (this._webcamProducer)
return; return;
@ -3783,12 +3781,6 @@ export default class RoomClient
if (!device) if (!device)
throw new Error('no webcam devices'); throw new Error('no webcam devices');
logger.debug(
'_setWebcamProducer() | new selected webcam [device:%o]',
device);
logger.debug('_setWebcamProducer() | calling getUserMedia()');
const stream = await navigator.mediaDevices.getUserMedia( const stream = await navigator.mediaDevices.getUserMedia(
{ {
video : video :
@ -3798,7 +3790,7 @@ export default class RoomClient
} }
}); });
track = stream.getVideoTracks()[0]; ([ track ] = stream.getVideoTracks());
if (this._useSimulcast) if (this._useSimulcast)
{ {
@ -3876,8 +3868,6 @@ export default class RoomClient
this.disableWebcam() this.disableWebcam()
.catch(() => {}); .catch(() => {});
}); });
logger.debug('_setWebcamProducer() succeeded');
} }
catch (error) catch (error)
{ {
@ -3962,8 +3952,10 @@ export default class RoomClient
async _setNoiseThreshold(threshold) async _setNoiseThreshold(threshold)
{ {
logger.debug('_setNoiseThreshold:%s', threshold); logger.debug('_setNoiseThreshold() [threshold:"%s"]', threshold);
this._hark.setThreshold(threshold); this._hark.setThreshold(threshold);
store.dispatch( store.dispatch(
settingsActions.setNoiseThreshold(threshold)); settingsActions.setNoiseThreshold(threshold));
} }