Skip to content

Commit

Permalink
Select video cam for p2p calls
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeny-nadymov committed Apr 9, 2021
1 parent b7d1c74 commit fae054a
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 67 deletions.
7 changes: 7 additions & 0 deletions src/Components/Calls/CallSettingsVideoPreview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (c) 2018-present, Evgeny Nadymov
*
* This source code is licensed under the GPL v.3.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

52 changes: 52 additions & 0 deletions src/Components/Calls/CallSettingsVideoPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-present, Evgeny Nadymov
*
* This source code is licensed under the GPL v.3.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import PropTypes from 'prop-types';
import './CallSettingsVideoPreview.css';

class CallSettingsVideoPreview extends React.Component {

componentDidMount() {
const { stream } = this.props;
if (stream) {
const video = document.getElementById('call-settings-video');
if (video) {
video.srcObject = stream;
}
}
}

componentDidUpdate(prevProps, prevState, snapshot) {
const { stream } = this.props;
if (prevProps.stream !== stream) {
const video = document.getElementById('call-settings-video');
if (video) {
video.srcObject = stream;
}
}
}

componentWillUnmount() {
}

render() {

return (
<div>
<video id='call-settings-video' autoPlay={true} muted={true}/>
</div>
);
}

}

CallSettingsVideoPreview.propTypes = {
stream: PropTypes.object
};

export default CallSettingsVideoPreview;
9 changes: 9 additions & 0 deletions src/Components/Calls/GroupCallSettings.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/

#call-settings-video {
width: calc(100% - 44px);
max-height: 100px;
background: black;
transform: scaleX(-1);
margin: 10px 22px;
box-sizing: border-box;
}

.group-call-settings {
position: absolute;
left: 0;
Expand Down
101 changes: 70 additions & 31 deletions src/Components/Calls/GroupCallSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { withTranslation } from 'react-i18next';
import IconButton from '@material-ui/core/IconButton';
import Switch from '@material-ui/core/Switch';
import CloseIcon from '../../Assets/Icons/Close';
import CallSettingsVideoPreview from './CallSettingsVideoPreview';
import GroupCallMicAmplitude from './GroupCallMicAmplitude';
import KeyboardManager, { KeyboardHandler } from '../Additional/KeyboardManager';
import { modalManager } from '../../Utils/Modal';
Expand Down Expand Up @@ -130,6 +131,7 @@ class GroupCallSettings extends React.Component {

componentDidMount() {
this.handleSelectDevice('inputAudio', CallStore.getInputAudioDeviceId());
this.handleSelectDevice('inputVideo', CallStore.getInputVideoDeviceId());
navigator.mediaDevices.addEventListener('devicechange', this.onDeviceChange);
// navigator.permissions.addEventListener('onchange', this.onDeviceChange);
KeyboardManager.add(this.keyboardHandler);
Expand All @@ -146,11 +148,20 @@ class GroupCallSettings extends React.Component {
}

closeStreams() {
const { inputAudioStream, inputAudioDeviceId } = this.state;
if (inputAudioStream && (!CallStore.currentGroupCall || inputAudioDeviceId === CallStore.getInputAudioDeviceId())) {
inputAudioStream.getAudioTracks().forEach(x => {
x.stop();
});
const { inputAudioStream, inputAudioDeviceId, inputVideoStream, inputVideoDeviceId } = this.state;
if (inputAudioStream) {
if (!CallStore.currentGroupCall || !CallStore.currentCall || inputAudioDeviceId === CallStore.getInputAudioDeviceId()) {
inputAudioStream.getAudioTracks().forEach(x => {
x.stop();
});
}
}
if (inputVideoStream) {
if (!CallStore.currentGroupCall || !CallStore.currentCall || inputVideoDeviceId === CallStore.getInputVideoDeviceId()) {
inputVideoStream.getAudioTracks().forEach(x => {
x.stop();
});
}
}
}

Expand Down Expand Up @@ -268,41 +279,61 @@ class GroupCallSettings extends React.Component {
break;
}
case 'inputAudio': {
const { currentGroupCall } = CallStore;
if (!currentGroupCall) return;

const { streamManager } = currentGroupCall;
if (!streamManager) return;
const { currentGroupCall, currentCall } = CallStore;
if (currentGroupCall) {
const { streamManager } = currentGroupCall;
if (!streamManager) return;

const { inputAudioStream, inputAudioDeviceId } = this.state;
if (inputAudioDeviceId === deviceId && inputAudioStream) return;

if (inputAudioStream) {
inputAudioStream.getAudioTracks().forEach(t => {
t.stop()
});
}

const stream = await getStream({
audio: { deviceId: { exact: deviceId } },
video: false
});

const { inputAudioStream, inputAudioDeviceId } = this.state;
if (inputAudioDeviceId === deviceId && inputAudioStream) return;
this.setState({
inputAudioDeviceId: deviceId,
inputAudioStream: stream
});
} else if (currentCall) {
const { inputAudioStream, inputAudioDeviceId } = this.state;
if (inputAudioDeviceId === deviceId && inputAudioStream) return;

if (inputAudioStream) {
inputAudioStream.getAudioTracks().forEach(t => {
t.stop()
});
}

const stream = await getStream({
audio: { deviceId: { exact: deviceId } },
video: false
});

if (inputAudioStream) {
inputAudioStream.getAudioTracks().forEach(t => {
t.stop()
this.setState({
inputAudioDeviceId: deviceId,
inputAudioStream: stream
});
}

const stream = await getStream({
audio: { deviceId: { exact: deviceId } },
video: false
});

this.setState({
inputAudioDeviceId: deviceId,
inputAudioStream: stream
});
break;
}
case 'inputVideo': {
const { currentCall } = CallStore;
if (!currentCall) return;

const { inputVideoStream, inputVideoDeviceId } = this.state;

if (inputVideoDeviceId === deviceId && inputVideoStream) return;

if (inputVideoStream) {
inputVideoStream.getAudioTracks().forEach(t => {
inputVideoStream.getVideoTracks().forEach(t => {
t.stop()
});
}
Expand Down Expand Up @@ -369,6 +400,7 @@ class GroupCallSettings extends React.Component {
inputAudioStream,
inputAudio,
inputVideoDeviceId,
inputVideoStream,
inputVideo,
outputDeviceId,
output,
Expand Down Expand Up @@ -480,13 +512,20 @@ class GroupCallSettings extends React.Component {
<div className='group-call-settings-panel-item-subtitle'>{inputAudioString}</div>
</div>

<GroupCallMicAmplitude stream={inputAudioStream}/>

{ callId && (
<div className='group-call-settings-panel-item' onClick={() => this.handleOpenDeviceSelect('inputVideo')}>
<div className='group-call-settings-panel-item-title'>{t('Camera')}</div>
<div className='group-call-settings-panel-item-subtitle'>{inputVideoString}</div>
</div>
<>
<div className='group-call-settings-panel-item' onClick={() => this.handleOpenDeviceSelect('inputVideo')}>
<div className='group-call-settings-panel-item-title'>{t('Camera')}</div>
<div className='group-call-settings-panel-item-subtitle'>{inputVideoString}</div>
</div>
<CallSettingsVideoPreview stream={inputVideoStream}/>
{/*<div>*/}
{/* <video id='call-settings-video' autoPlay={true} muted={true}/>*/}
{/*</div>*/}
</>
)}
<GroupCallMicAmplitude stream={inputAudioStream}/>
{ username && (
<div className='group-call-settings-panel-item' onClick={this.handleCopyLink}>
{t('VoipGroupCopyInviteLink')}
Expand Down
66 changes: 30 additions & 36 deletions src/Stores/CallStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -1165,10 +1165,8 @@ class CallStore extends EventEmitter {

const p2pPlayer = document.getElementById('call-output-video');
if (p2pPlayer) {
for (let audio of p2pPlayer.getElementsByTagName('audio')) {
if (typeof audio.sinkId !== 'undefined') {
audio.setSinkId(deviceId);
}
if (typeof p2pPlayer.sinkId !== 'undefined') {
p2pPlayer.setSinkId(deviceId);
}
}
} else {
Expand All @@ -1195,8 +1193,8 @@ class CallStore extends EventEmitter {
}

getOutputDeviceId() {
const { currentGroupCall } = this;
if (!currentGroupCall) return null;
const { currentGroupCall, currentCall } = this;
if (!currentGroupCall && !currentCall) return null;

if (JOIN_TRACKS) {
const player = document.getElementById('group-call-player');
Expand All @@ -1210,10 +1208,8 @@ class CallStore extends EventEmitter {

const p2pPlayer = document.getElementById('call-output-video');
if (p2pPlayer) {
for (let audio of p2pPlayer.getElementsByTagName('audio')) {
if (typeof audio.sinkId !== 'undefined') {
return audio.sinkId;
}
if (typeof p2pPlayer.sinkId !== 'undefined') {
return p2pPlayer.sinkId;
}
}
} else {
Expand Down Expand Up @@ -1254,25 +1250,26 @@ class CallStore extends EventEmitter {
oldTrack.stop();
streamManager.replaceInputAudio(stream, oldTrack);
} else if (currentCall) {
// const { connection, streamManager } = currentGroupCall;
// if (!connection) return;
//
// const { inputStream } = streamManager;
//
const { connection, inputStream } = currentCall;
if (!connection) return;
if (!inputStream) return;

// // const videoTrack = stream.getVideoTracks()[0];
// // const sender = pc.getSenders().find(function(s) {
// // return s.track.kind == videoTrack.kind;
// // });
// // sender.replaceTrack(videoTrack);
//
// const audioTrack = stream.getAudioTracks()[0];
// const sender2 = connection.getSenders().find(x => {
// return x.track.kind === audioTrack.kind;
// });
// const oldTrack = sender2.track;
// await sender2.replaceTrack(audioTrack);
//
// oldTrack.stop();

const audioTrack = stream.getAudioTracks()[0];
const sender2 = connection.getSenders().find(x => {
return x.track.kind === audioTrack.kind;
});
const oldTrack = sender2.track;
await sender2.replaceTrack(audioTrack);

oldTrack.stop();
inputStream.removeTrack(oldTrack);
inputStream.addTrack(audioTrack);
// streamManager.replaceInputAudio(stream, oldTrack);
}
}
Expand Down Expand Up @@ -1301,28 +1298,25 @@ class CallStore extends EventEmitter {
// oldTrack.stop();
// streamManager.replaceInputAudio(stream, oldTrack);
} else if (currentCall) {
const { connection, inputStream } = currentCall;
const { callId, connection, inputStream } = currentCall;
if (!connection) return;
if (!inputStream) return;

const videoTrack = stream.getVideoTracks()[0];
const mediaState = this.p2pGetMediaState(callId, 'input');
if (mediaState && mediaState.videoState === 'inactive') {
videoTrack.enabled = false;
}

const sender = connection.getSenders().find(function(s) {
return s.track.kind == videoTrack.kind;
});
const oldTrack = sender.track;
sender.replaceTrack(videoTrack);

oldTrack.stop();
// inputStream.replaceTrack()

// const audioTrack = stream.getAudioTracks()[0];
// const sender2 = connection.getSenders().find(x => {
// return x.track.kind === audioTrack.kind;
// });
// const oldTrack = sender2.track;
// await sender2.replaceTrack(audioTrack);

// oldTrack.stop();
// streamManager.replaceInputAudio(stream, oldTrack);
inputStream.removeTrack(oldTrack);
inputStream.addTrack(videoTrack);
}
}

Expand Down

0 comments on commit fae054a

Please sign in to comment.