webrtc config electron
init on LoggedInView mounting configurable via UserSettings new class: CallMediaHandler Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
0e880f7971
commit
c6262d62a6
3 changed files with 145 additions and 1 deletions
63
src/CallMediaHandler.js
Normal file
63
src/CallMediaHandler.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UserSettingsStore from './UserSettingsStore';
|
||||
import * as Matrix from 'matrix-js-sdk';
|
||||
import q from 'q';
|
||||
|
||||
export default {
|
||||
getDevices: function() {
|
||||
// Only needed for Electron atm, though should work in modern browsers
|
||||
// once permission has been granted to the webapp
|
||||
return navigator.mediaDevices.enumerateDevices().then(function(devices) {
|
||||
const audioIn = {};
|
||||
const videoIn = {};
|
||||
|
||||
devices.forEach((device) => {
|
||||
switch (device.kind) {
|
||||
case 'audioinput': audioIn[device.deviceId] = device.label; break;
|
||||
case 'videoinput': videoIn[device.deviceId] = device.label; break;
|
||||
}
|
||||
});
|
||||
|
||||
// console.log("Loaded WebRTC Devices", mediaDevices);
|
||||
return {
|
||||
audioinput: audioIn,
|
||||
videoinput: videoIn,
|
||||
};
|
||||
}, (error) => { console.log('Unable to refresh WebRTC Devices: ', error); });
|
||||
},
|
||||
|
||||
loadDevices: function() {
|
||||
// this.getDevices().then((devices) => {
|
||||
const localSettings = UserSettingsStore.getLocalSettings();
|
||||
// // if deviceId is not found, automatic fallback is in spec
|
||||
// // recall previously stored inputs if any
|
||||
Matrix.setMatrixCallAudioInput(localSettings['webrtc_audioinput']);
|
||||
Matrix.setMatrixCallVideoInput(localSettings['webrtc_videoinput']);
|
||||
// });
|
||||
},
|
||||
|
||||
setAudioInput: function(deviceId) {
|
||||
UserSettingsStore.setLocalSetting('webrtc_audioinput', deviceId);
|
||||
Matrix.setMatrixCallAudioInput(deviceId);
|
||||
},
|
||||
|
||||
setVideoInput: function(deviceId) {
|
||||
UserSettingsStore.setLocalSetting('webrtc_videoinput', deviceId);
|
||||
Matrix.setMatrixCallVideoInput(deviceId);
|
||||
},
|
||||
};
|
|
@ -21,6 +21,7 @@ import React from 'react';
|
|||
import KeyCode from '../../KeyCode';
|
||||
import Notifier from '../../Notifier';
|
||||
import PageTypes from '../../PageTypes';
|
||||
import CallMediaHandler from '../../CallMediaHandler';
|
||||
import sdk from '../../index';
|
||||
import dis from '../../dispatcher';
|
||||
|
||||
|
@ -71,6 +72,10 @@ export default React.createClass({
|
|||
// RoomView.getScrollState()
|
||||
this._scrollStateMap = {};
|
||||
|
||||
// Only run these in electron, at least until a better mechanism for perms exists
|
||||
// https://w3c.github.io/permissions/#dom-permissionname-device-info
|
||||
if (window && window.process && window.process.type) CallMediaHandler.loadDevices();
|
||||
|
||||
document.addEventListener('keydown', this._onKeyDown);
|
||||
},
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ var dis = require("../../dispatcher");
|
|||
var q = require('q');
|
||||
var package_json = require('../../../package.json');
|
||||
var UserSettingsStore = require('../../UserSettingsStore');
|
||||
var CallMediaHandler = require('../../CallMediaHandler');
|
||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
var Email = require('../../email');
|
||||
var AddThreepid = require('../../AddThreepid');
|
||||
|
@ -109,7 +110,6 @@ const THEMES = [
|
|||
}
|
||||
];
|
||||
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'UserSettings',
|
||||
|
||||
|
@ -147,6 +147,7 @@ module.exports = React.createClass({
|
|||
email_add_pending: false,
|
||||
vectorVersion: null,
|
||||
rejectingInvites: false,
|
||||
mediaDevices: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -167,6 +168,18 @@ module.exports = React.createClass({
|
|||
});
|
||||
}
|
||||
|
||||
q().then(() => {
|
||||
return CallMediaHandler.getDevices();
|
||||
}).then((mediaDevices) => {
|
||||
console.log("got mediaDevices", mediaDevices, this._unmounted);
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
mediaDevices,
|
||||
activeAudioInput: this._localSettings['webrtc_audioinput'] || 'default',
|
||||
activeVideoInput: this._localSettings['webrtc_videoinput'] || 'default',
|
||||
});
|
||||
});
|
||||
|
||||
// Bulk rejecting invites:
|
||||
// /sync won't have had time to return when UserSettings re-renders from state changes, so getRooms()
|
||||
// will still return rooms with invites. To get around this, add a listener for
|
||||
|
@ -187,6 +200,8 @@ module.exports = React.createClass({
|
|||
this._syncedSettings = syncedSettings;
|
||||
|
||||
this._localSettings = UserSettingsStore.getLocalSettings();
|
||||
this._setAudioInput = this._setAudioInput.bind(this);
|
||||
this._setVideoInput = this._setVideoInput.bind(this);
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
|
@ -775,6 +790,66 @@ module.exports = React.createClass({
|
|||
</div>;
|
||||
},
|
||||
|
||||
_mapWebRtcDevicesToSpans: function(devices) {
|
||||
return Object.keys(devices).map(
|
||||
(deviceId) => <span key={deviceId}>{devices[deviceId]}</span>
|
||||
);
|
||||
},
|
||||
|
||||
_setAudioInput: function(deviceId) {
|
||||
this.setState({activeAudioInput: deviceId});
|
||||
CallMediaHandler.setAudioInput(deviceId);
|
||||
},
|
||||
|
||||
_setVideoInput: function(deviceId) {
|
||||
this.setState({activeVideoInput: deviceId});
|
||||
CallMediaHandler.setVideoInput(deviceId);
|
||||
},
|
||||
|
||||
_renderWebRtcSettings: function() {
|
||||
if (!(window && window.process && window.process.type)
|
||||
|| !this.state.mediaDevices) return;
|
||||
|
||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||
|
||||
let microphoneDropdown = <h5>No Microphones detected</h5>;
|
||||
let webcamDropdown = <h5>No Webcams detected</h5>;
|
||||
|
||||
const audioInputs = this.state.mediaDevices.audioinput;
|
||||
if ('default' in audioInputs) {
|
||||
microphoneDropdown = <div>
|
||||
<h4>Microphone</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeAudioInput}
|
||||
onOptionChange={this._setAudioInput}>
|
||||
{this._mapWebRtcDevicesToSpans(audioInputs)}
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
||||
const videoInputs = this.state.mediaDevices.videoinput;
|
||||
if ('default' in videoInputs) {
|
||||
webcamDropdown = <div>
|
||||
<h4>Cameras</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeVideoInput}
|
||||
onOptionChange={this._setVideoInput}>
|
||||
{this._mapWebRtcDevicesToSpans(videoInputs)}
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <div>
|
||||
<h3>WebRTC</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
{microphoneDropdown}
|
||||
{webcamDropdown}
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
||||
_showSpoiler: function(event) {
|
||||
const target = event.target;
|
||||
const hidden = target.getAttribute('data-spoiler');
|
||||
|
@ -973,6 +1048,7 @@ module.exports = React.createClass({
|
|||
|
||||
{this._renderUserInterfaceSettings()}
|
||||
{this._renderLabs()}
|
||||
{this._renderWebRtcSettings()}
|
||||
{this._renderDevicesPanel()}
|
||||
{this._renderCryptoInfo()}
|
||||
{this._renderBulkOptions()}
|
||||
|
|
Loading…
Reference in a new issue