add a way to choose the audioouput/mute a webrtc call

pull/2039/head
Audric Ackermann 3 years ago
parent 53289298a9
commit a4daabfa75
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -1,6 +1,6 @@
import { SessionIconButton } from '../icon';
import { animation, contextMenu, Item, Menu } from 'react-contexify';
import { InputItem } from '../../../session/utils/CallManager';
import { InputItem } from '../../../session/utils/calling/CallManager';
import { setFullScreenCall } from '../../../state/ducks/call';
import { CallManager, ToastUtils } from '../../../session/utils';
import React from 'react';
@ -71,16 +71,16 @@ export const AudioInputButton = ({
export const AudioOutputButton = ({
currentConnectedAudioOutputs,
}: // isAudioOutputMuted,
// hideArrowIcon = false,
{
isAudioOutputMuted,
hideArrowIcon = false,
}: {
currentConnectedAudioOutputs: Array<InputItem>;
isAudioOutputMuted: boolean;
hideArrowIcon?: boolean;
}) => {
return (
<>
{/* <DropDownAndToggleButton
<DropDownAndToggleButton
iconType="volume"
isMuted={isAudioOutputMuted}
onMainButtonClick={() => {
@ -90,7 +90,7 @@ export const AudioOutputButton = ({
showAudioOutputMenu(currentConnectedAudioOutputs, e);
}}
hidePopoverArrow={hideArrowIcon}
/> */}
/>
<AudioOutputMenu
triggerId={audioOutputTriggerId}
@ -238,19 +238,19 @@ const showAudioInputMenu = (
});
};
// const showAudioOutputMenu = (
// currentConnectedAudioOutputs: Array<any>,
// e: React.MouseEvent<HTMLDivElement>
// ) => {
// if (currentConnectedAudioOutputs.length === 0) {
// ToastUtils.pushNoAudioOutputFound();
// return;
// }
// contextMenu.show({
// id: audioOutputTriggerId,
// event: e,
// });
// };
const showAudioOutputMenu = (
currentConnectedAudioOutputs: Array<any>,
e: React.MouseEvent<HTMLDivElement>
) => {
if (currentConnectedAudioOutputs.length === 0) {
ToastUtils.pushNoAudioOutputFound();
return;
}
contextMenu.show({
id: audioOutputTriggerId,
event: e,
});
};
const showVideoInputMenu = (
currentConnectedCameras: Array<InputItem>,
@ -300,22 +300,22 @@ const handleMicrophoneToggle = async (
}
};
// const handleSpeakerToggle = async (
// currentConnectedAudioOutputs: Array<InputItem>,
// isAudioOutputMuted: boolean
// ) => {
// if (!currentConnectedAudioOutputs.length) {
// ToastUtils.pushNoAudioInputFound();
const handleSpeakerToggle = async (
currentConnectedAudioOutputs: Array<InputItem>,
isAudioOutputMuted: boolean
) => {
if (!currentConnectedAudioOutputs.length) {
ToastUtils.pushNoAudioInputFound();
// return;
// }
// if (isAudioOutputMuted) {
// // selects the first one
// await CallManager.selectAudioOutputByDeviceId(currentConnectedAudioOutputs[0].deviceId);
// } else {
// await CallManager.selectAudioOutputByDeviceId(CallManager.DEVICE_DISABLED_DEVICE_ID);
// }
// };
return;
}
if (isAudioOutputMuted) {
// selects the first one
await CallManager.selectAudioOutputByDeviceId(currentConnectedAudioOutputs[0].deviceId);
} else {
await CallManager.selectAudioOutputByDeviceId(CallManager.DEVICE_DISABLED_DEVICE_ID);
}
};
const StyledCallWindowControls = styled.div`
position: absolute;

@ -23,7 +23,7 @@ import {
import { useModuloWithTripleDots } from '../../../hooks/useModuloWithTripleDots';
import { CallWindowControls } from './CallButtons';
import { SessionSpinner } from '../SessionSpinner';
import { DEVICE_DISABLED_DEVICE_ID } from '../../../session/utils/CallManager';
import { DEVICE_DISABLED_DEVICE_ID } from '../../../session/utils/calling/CallManager';
const VideoContainer = styled.div`
height: 100%;
@ -156,10 +156,10 @@ export const InConversationCallContainer = () => {
if (videoRefRemote.current) {
if (currentSelectedAudioOutput === DEVICE_DISABLED_DEVICE_ID) {
videoRefLocal.current.muted = true;
videoRefRemote.current.muted = true;
} else {
// void videoRefLocal.current.setSinkId(currentSelectedAudioOutput);
videoRefLocal.current.muted = false;
// void videoRefRemote.current.setSinkId(currentSelectedAudioOutput);
videoRefRemote.current.muted = false;
}
}
}

@ -2,12 +2,13 @@ import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
// tslint:disable-next-line: no-submodule-imports
import useMountedState from 'react-use/lib/useMountedState';
import { CallManager } from '../session/utils';
import {
addVideoEventsListener,
CallManagerOptionsType,
DEVICE_DISABLED_DEVICE_ID,
InputItem,
} from '../session/utils/CallManager';
removeVideoEventsListener,
} from '../session/utils/calling/CallManager';
import { getSelectedConversationKey } from '../state/selectors/conversations';
import { getCallIsInFullScreen, getHasOngoingCallWithPubkey } from '../state/selectors/call';
@ -40,7 +41,7 @@ export function useVideoCallEventsListener(uniqueId: string, onSame: boolean) {
(onSame && ongoingCallPubkey === selectedConversationKey) ||
(!onSame && ongoingCallPubkey !== selectedConversationKey)
) {
CallManager.addVideoEventsListener(uniqueId, (options: CallManagerOptionsType) => {
addVideoEventsListener(uniqueId, (options: CallManagerOptionsType) => {
const {
audioInputsList,
audioOutputsList,
@ -68,7 +69,7 @@ export function useVideoCallEventsListener(uniqueId: string, onSame: boolean) {
}
return () => {
CallManager.removeVideoEventsListener(uniqueId);
removeVideoEventsListener(uniqueId);
};
}, [ongoingCallPubkey, selectedConversationKey, isFullScreen]);

@ -1,10 +1,10 @@
import _ from 'lodash';
import { MessageUtils, ToastUtils, UserUtils } from '.';
import { getCallMediaPermissionsSettings } from '../../components/session/settings/SessionSettings';
import { getConversationById } from '../../data/data';
import { MessageModelType } from '../../models/messageType';
import { SignalService } from '../../protobuf';
import { openConversationWithMessages } from '../../state/ducks/conversations';
import { MessageUtils, ToastUtils, UserUtils } from '../';
import { getCallMediaPermissionsSettings } from '../../../components/session/settings/SessionSettings';
import { getConversationById } from '../../../data/data';
import { MessageModelType } from '../../../models/messageType';
import { SignalService } from '../../../protobuf';
import { openConversationWithMessages } from '../../../state/ducks/conversations';
import {
answerCall,
callConnected,
@ -13,22 +13,23 @@ import {
incomingCall,
setFullScreenCall,
startingCallWith,
} from '../../state/ducks/call';
import { getConversationController } from '../conversations';
import { CallMessage } from '../messages/outgoing/controlMessage/CallMessage';
import { ed25519Str } from '../onions/onionPath';
import { getMessageQueue, MessageSender } from '../sending';
import { PubKey } from '../types';
} from '../../../state/ducks/call';
import { getConversationController } from '../../conversations';
import { CallMessage } from '../../messages/outgoing/controlMessage/CallMessage';
import { ed25519Str } from '../../onions/onionPath';
import { PubKey } from '../../types';
import { v4 as uuidv4 } from 'uuid';
import { PnServer } from '../../pushnotification';
import { setIsRinging } from './RingingManager';
import { PnServer } from '../../../pushnotification';
import { setIsRinging } from '../RingingManager';
import { getBlackSilenceMediaStream } from './Silence';
import { getMessageQueue } from '../..';
import { MessageSender } from '../../sending';
export type InputItem = { deviceId: string; label: string };
// tslint:disable: function-name
const maxWidth = 1920;
const maxHeight = 1080;
export type InputItem = { deviceId: string; label: string };
/**
* This uuid is set only once we accepted a call or started one.
*/
@ -169,28 +170,6 @@ if (typeof navigator !== 'undefined') {
});
}
const silence = () => {
const ctx = new AudioContext();
const oscillator = ctx.createOscillator();
const dst = oscillator.connect(ctx.createMediaStreamDestination());
oscillator.start();
return Object.assign((dst as any).stream.getAudioTracks()[0], { enabled: false });
};
const black = () => {
const canvas = Object.assign(document.createElement('canvas'), {
width: maxWidth,
height: maxHeight,
});
canvas.getContext('2d')?.fillRect(0, 0, maxWidth, maxHeight);
const stream = (canvas as any).captureStream();
return Object.assign(stream.getVideoTracks()[0], { enabled: false });
};
const getBlackSilenceMediaStream = () => {
return new MediaStream([black(), silence()]);
};
async function updateConnectedDevices() {
// Get the set of cameras connected
const videoCameras = await getConnectedDevices('videoinput');
@ -339,12 +318,13 @@ export async function selectAudioInputByDeviceId(audioInputDeviceId: string) {
if (!peerConnection) {
throw new Error('cannot selectAudioInputByDeviceId without a peer connection');
}
const sender = peerConnection.getSenders().find(s => {
const audioSender = peerConnection.getSenders().find(s => {
return s.track?.kind === audioTrack.kind;
});
window.log.info('replacing audio track');
if (sender) {
await sender.replaceTrack(audioTrack);
if (audioSender) {
await audioSender.replaceTrack(audioTrack);
// we actually do not need to toggle the track here, as toggling it here unmuted here locally (so we start to hear ourselves)
} else {
throw new Error('Failed to get sender for selectAudioInputByDeviceId ');
@ -562,6 +542,11 @@ function handleConnectionStateChanged(pubkey: string) {
if (firstAudioInput) {
void selectAudioInputByDeviceId(firstAudioInput);
}
const firstAudioOutput = audioOutputsList?.[0].deviceId || undefined;
if (firstAudioOutput) {
void selectAudioOutputByDeviceId(firstAudioOutput);
}
window.inboxStore?.dispatch(callConnected({ pubkey }));
}
}

@ -0,0 +1,24 @@
const maxWidth = 1920;
const maxHeight = 1080;
const silence = () => {
const ctx = new AudioContext();
const oscillator = ctx.createOscillator();
const dst = oscillator.connect(ctx.createMediaStreamDestination());
oscillator.start();
return Object.assign((dst as any).stream.getAudioTracks()[0], { enabled: false });
};
const black = () => {
const canvas = Object.assign(document.createElement('canvas'), {
width: maxWidth,
height: maxHeight,
});
canvas.getContext('2d')?.fillRect(0, 0, maxWidth, maxHeight);
const stream = (canvas as any).captureStream();
return Object.assign(stream.getVideoTracks()[0], { enabled: false });
};
export const getBlackSilenceMediaStream = () => {
return new MediaStream([black(), silence()]);
};

@ -8,7 +8,7 @@ import * as UserUtils from './User';
import * as SyncUtils from './syncUtils';
import * as AttachmentsV2Utils from './AttachmentsV2';
import * as AttachmentDownloads from './AttachmentsDownload';
import * as CallManager from './CallManager';
import * as CallManager from './calling/CallManager';
export * from './Attachments';
export * from './TypedEmitter';

Loading…
Cancel
Save