feat(audio-only): be able to lock a browser into capturing audio only (#2125)

* feat(audio-only): be able to lock a browser into capturing audio only

* squash: try to make string more clear about audio only support

* squash: final strings
This commit is contained in:
virtuacoplenny 2017-11-09 13:59:16 -08:00 committed by bbaldino
parent 81e36b2a26
commit 5c464a7bda
6 changed files with 87 additions and 18 deletions

View File

@ -29,8 +29,7 @@ import {
EMAIL_COMMAND,
lockStateChanged,
p2pStatusChanged,
sendLocalParticipant,
toggleAudioOnly
sendLocalParticipant
} from './react/features/base/conference';
import { updateDeviceList } from './react/features/base/devices';
import {
@ -554,11 +553,6 @@ export default {
let tryCreateLocalTracks;
// Enable audio only mode
if (config.startAudioOnly) {
APP.store.dispatch(toggleAudioOnly());
}
// FIXME is there any simpler way to rewrite this spaghetti below ?
if (options.startScreenSharing) {
tryCreateLocalTracks = this._createDesktopTrack()

View File

@ -1,5 +1,4 @@
.video-quality-dialog {
.hide-warning {
height: 0;
visibility: hidden;
@ -27,7 +26,7 @@
@mixin sliderTrackStyles() {
height: 15px;
border-radius: 10px;
background: #0E1624;
background: rgb(14, 22, 36);
}
&::-ms-track {
@ -110,6 +109,30 @@
word-spacing: unset;
}
}
&.video-not-supported {
.video-quality-dialog-labels {
color: gray;
}
.video-quality-dialog-slider {
@mixin sliderTrackDisabledStyles() {
background: rgba(14, 22, 36, 0.1);
}
&::-ms-track {
@include sliderTrackDisabledStyles();
}
&::-moz-range-track {
@include sliderTrackDisabledStyles();
}
&::-webkit-slider-runnable-track {
@include sliderTrackDisabledStyles();
}
}
}
}
.video-state-indicator {

View File

@ -470,6 +470,8 @@
"labelTooltipAudioOnly": "Audio-only mode enabled",
"ld": "LD",
"lowDefinition": "Low definition",
"onlyAudioAvailable": "Only audio is available",
"onlyAudioSupported": "We only support audio in this browser.",
"p2pEnabled": "Peer to Peer Enabled",
"p2pVideoQualityDescription": "In peer to peer mode, received call quality can only be toggled between high and audio only. Other settings will not be honored until peer to peer is exited.",
"recHighDefinitionOnly": "Will prefer high definition.",

View File

@ -3,6 +3,7 @@
import { sendAnalyticsEvent } from '../../analytics';
import { SET_ROOM, setAudioOnly } from '../conference';
import { parseURLParams } from '../config';
import JitsiMeetJS from '../lib-jitsi-meet';
import { MiddlewareRegistry } from '../redux';
import { setTrackMuted, TRACK_ADDED } from '../tracks';
@ -108,10 +109,19 @@ function _setRoom({ dispatch, getState }, next, action) {
// because it looks like config.startWithAudioMuted and
// config.startWithVideoMuted.
if (room) {
let audioOnly = urlParams && urlParams['config.startAudioOnly'];
let audioOnly;
if (JitsiMeetJS.mediaDevices.supportsVideo()) {
audioOnly = urlParams && urlParams['config.startAudioOnly'];
typeof audioOnly === 'undefined'
&& (audioOnly = config.startAudioOnly);
audioOnly = Boolean(audioOnly);
} else {
// Always default to being audio only if the current environment
// does not support sending or receiving video.
audioOnly = true;
}
typeof audioOnly === 'undefined' && (audioOnly = config.startAudioOnly);
audioOnly = Boolean(audioOnly);
sendAnalyticsEvent(
`startaudioonly.${audioOnly ? 'enabled' : 'disabled'}`);
logger.log(`Start audio only set to ${audioOnly.toString()}`);

View File

@ -513,6 +513,10 @@ class DeviceSelectionDialogBase extends Component {
this._disposeVideoPreview()
.then(() => createLocalTrack('video', deviceId))
.then(jitsiLocalTrack => {
if (!jitsiLocalTrack) {
return Promise.reject();
}
this.setState({
previewVideoTrack: jitsiLocalTrack,
previewVideoTrackError: null

View File

@ -10,6 +10,7 @@ import {
VIDEO_QUALITY_LEVELS
} from '../../base/conference';
import { translate } from '../../base/i18n';
import JitsiMeetJS from '../../base/lib-jitsi-meet';
const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -48,6 +49,12 @@ class VideoQualityDialog extends Component {
*/
_receiveVideoQuality: PropTypes.number,
/**
* Whether or not displaying video is supported in the current
* environment. If false, the slider will be disabled.
*/
_videoSupported: PropTypes.bool,
/**
* Invoked to request toggling of audio only mode.
*/
@ -116,17 +123,26 @@ class VideoQualityDialog extends Component {
* @returns {ReactElement}
*/
render() {
const { _audioOnly, _p2p, t } = this.props;
const { _audioOnly, _p2p, _videoSupported, t } = this.props;
const activeSliderOption = this._mapCurrentQualityToSliderValue();
const showP2PWarning = _p2p && !_audioOnly;
let classNames = 'video-quality-dialog';
let warning = null;
if (!_videoSupported) {
classNames += ' video-not-supported';
warning = this._renderAudioOnlyLockedMessage();
} else if (_p2p && !_audioOnly) {
warning = this._renderP2PMessage();
}
return (
<div className = 'video-quality-dialog'>
<div className = { classNames }>
<h3 className = 'video-quality-dialog-title'>
{ t('videoStatus.callQuality') }
</h3>
<div className = { showP2PWarning ? '' : 'hide-warning' }>
{ this._renderP2PMessage() }
<div className = { warning ? '' : 'hide-warning' }>
{ warning }
</div>
<div className = 'video-quality-dialog-contents'>
<div className = 'video-quality-dialog-slider-container'>
@ -136,6 +152,7 @@ class VideoQualityDialog extends Component {
*/ }
<input
className = 'video-quality-dialog-slider'
disabled = { !_videoSupported }
max = { this._sliderOptions.length - 1 }
min = '0'
onChange = { this._onSliderChange }
@ -154,6 +171,24 @@ class VideoQualityDialog extends Component {
);
}
/**
* Creates a React Element for notifying that the browser is in audio only
* and cannot be changed.
*
* @private
* @returns {ReactElement}
*/
_renderAudioOnlyLockedMessage() {
const { t } = this.props;
return (
<InlineMessage
title = { t('videoStatus.onlyAudioAvailable') }>
{ t('videoStatus.onlyAudioSupported') }
</InlineMessage>
);
}
/**
* Creates React Elements for notifying that peer to peer is enabled.
*
@ -330,7 +365,8 @@ function _mapStateToProps(state) {
return {
_audioOnly: audioOnly,
_p2p: p2p,
_receiveVideoQuality: receiveVideoQuality
_receiveVideoQuality: receiveVideoQuality,
_videoSupported: JitsiMeetJS.mediaDevices.supportsVideo()
};
}