no video track by default and will be turn ON if asked to

pull/2039/head
Audric Ackermann 4 years ago
parent 6f3625f99c
commit 1dff310820
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -20,7 +20,8 @@ export async function handleCallMessage(
// we just allow self send of ANSWER message to remove the incoming call dialog when we accepted it from another device // we just allow self send of ANSWER message to remove the incoming call dialog when we accepted it from another device
if ( if (
sender === UserUtils.getOurPubKeyStrFromCache() && sender === UserUtils.getOurPubKeyStrFromCache() &&
callMessage.type !== SignalService.CallMessage.Type.ANSWER callMessage.type !== SignalService.CallMessage.Type.ANSWER &&
callMessage.type !== SignalService.CallMessage.Type.END_CALL
) { ) {
window.log.info('Dropping incoming call from ourself'); window.log.info('Dropping incoming call from ourself');
await removeFromCache(envelope); await removeFromCache(envelope);

@ -6,6 +6,7 @@ import { OpenGroupVisibleMessage } from '../messages/outgoing/visibleMessage/Ope
import { EncryptionType, RawMessage } from '../types'; import { EncryptionType, RawMessage } from '../types';
import { UserUtils } from '../utils'; import { UserUtils } from '../utils';
// tslint:disable-next-line: no-unnecessary-class
export class MessageSentHandler { export class MessageSentHandler {
public static async handlePublicMessageSentSuccess( public static async handlePublicMessageSentSuccess(
sentMessage: OpenGroupVisibleMessage, sentMessage: OpenGroupVisibleMessage,

@ -52,7 +52,7 @@ function callVideoListeners() {
if (videoEventsListeners.length) { if (videoEventsListeners.length) {
videoEventsListeners.forEach(item => { videoEventsListeners.forEach(item => {
item.listener?.({ item.listener?.({
localStream: mediaDevices, localStream,
remoteStream, remoteStream,
camerasList, camerasList,
audioInputsList, audioInputsList,
@ -92,7 +92,7 @@ const callCache = new Map<string, Map<string, Array<SignalService.CallMessage>>>
let peerConnection: RTCPeerConnection | null; let peerConnection: RTCPeerConnection | null;
let dataChannel: RTCDataChannel | null; let dataChannel: RTCDataChannel | null;
let remoteStream: MediaStream | null; let remoteStream: MediaStream | null;
let mediaDevices: MediaStream | null; let localStream: MediaStream | null;
let remoteVideoStreamIsMuted = true; let remoteVideoStreamIsMuted = true;
export const DEVICE_DISABLED_DEVICE_ID = 'off'; export const DEVICE_DISABLED_DEVICE_ID = 'off';
@ -238,29 +238,32 @@ export async function selectCameraByDeviceId(cameraDeviceId: string) {
if (!peerConnection) { if (!peerConnection) {
throw new Error('cannot selectCameraByDeviceId without a peer connection'); throw new Error('cannot selectCameraByDeviceId without a peer connection');
} }
let sender = peerConnection.getSenders().find(s => {
return s.track?.kind === videoTrack.kind;
});
// video might be completely off // video might be completely off on start. adding a track like this triggers a negotationneeded event
if (!sender) { window.log.info('adding/replacing video track');
peerConnection.addTrack(videoTrack); const sender = peerConnection.getSenders().find(s => {
}
sender = peerConnection.getSenders().find(s => {
return s.track?.kind === videoTrack.kind; return s.track?.kind === videoTrack.kind;
}); });
videoTrack.enabled = true;
if (sender) { if (sender) {
// this should not trigger a negotationneeded event
// and it is needed for when the video cam was never turn on
await sender.replaceTrack(videoTrack); await sender.replaceTrack(videoTrack);
videoTrack.enabled = true; } else {
mediaDevices?.getVideoTracks().forEach(t => { // this will trigger a negotiationeeded event
t.stop(); peerConnection.addTrack(videoTrack, newVideoStream);
mediaDevices?.removeTrack(t);
});
mediaDevices?.addTrack(videoTrack);
sendVideoStatusViaDataChannel();
callVideoListeners();
} }
// do the same changes locally
localStream?.getVideoTracks().forEach(t => {
t.stop();
localStream?.removeTrack(t);
});
localStream?.addTrack(videoTrack);
sendVideoStatusViaDataChannel();
callVideoListeners();
} catch (e) { } catch (e) {
window.log.warn('selectCameraByDeviceId failed with', e.message); window.log.warn('selectCameraByDeviceId failed with', e.message);
callVideoListeners(); callVideoListeners();
@ -403,19 +406,16 @@ async function openMediaDevicesAndAddTracks() {
video: false, video: false,
}; };
mediaDevices = await navigator.mediaDevices.getUserMedia(devicesConfig); localStream = await navigator.mediaDevices.getUserMedia(devicesConfig);
mediaDevices.getTracks().map(track => { localStream.getTracks().map(track => {
// if (track.kind === 'video') { if (localStream) {
// track.enabled = false; peerConnection?.addTrack(track, localStream);
// }
if (mediaDevices) {
peerConnection?.addTrack(track, mediaDevices);
} }
}); });
} catch (err) { } catch (err) {
window.log.warn('openMediaDevices: ', err); window.log.warn('openMediaDevices: ', err);
ToastUtils.pushVideoCallPermissionNeeded(); ToastUtils.pushVideoCallPermissionNeeded();
await closeVideoCall(); closeVideoCall();
} }
callVideoListeners(); callVideoListeners();
} }
@ -520,7 +520,7 @@ const findLastMessageTypeFromSender = (sender: string, msgType: SignalService.Ca
function handleSignalingStateChangeEvent() { function handleSignalingStateChangeEvent() {
if (peerConnection?.signalingState === 'closed') { if (peerConnection?.signalingState === 'closed') {
void closeVideoCall(); closeVideoCall();
} }
} }
@ -528,14 +528,14 @@ function handleConnectionStateChanged(pubkey: string) {
window.log.info('handleConnectionStateChanged :', peerConnection?.connectionState); window.log.info('handleConnectionStateChanged :', peerConnection?.connectionState);
if (peerConnection?.signalingState === 'closed' || peerConnection?.connectionState === 'failed') { if (peerConnection?.signalingState === 'closed' || peerConnection?.connectionState === 'failed') {
void closeVideoCall(); closeVideoCall();
} else if (peerConnection?.connectionState === 'connected') { } else if (peerConnection?.connectionState === 'connected') {
setIsRinging(false); setIsRinging(false);
window.inboxStore?.dispatch(callConnected({ pubkey })); window.inboxStore?.dispatch(callConnected({ pubkey }));
} }
} }
async function closeVideoCall() { function closeVideoCall() {
window.log.info('closingVideoCall '); window.log.info('closingVideoCall ');
setIsRinging(false); setIsRinging(false);
if (peerConnection) { if (peerConnection) {
@ -551,14 +551,16 @@ async function closeVideoCall() {
dataChannel.close(); dataChannel.close();
dataChannel = null; dataChannel = null;
} }
if (mediaDevices) { if (localStream) {
mediaDevices.getTracks().forEach(track => { localStream.getTracks().forEach(track => {
track.stop(); track.stop();
localStream?.removeTrack(track);
}); });
} }
if (remoteStream) { if (remoteStream) {
remoteStream.getTracks().forEach(track => { remoteStream.getTracks().forEach(track => {
track.stop();
remoteStream?.removeTrack(track); remoteStream?.removeTrack(track);
}); });
} }
@ -567,7 +569,7 @@ async function closeVideoCall() {
peerConnection = null; peerConnection = null;
} }
mediaDevices = null; localStream = null;
remoteStream = null; remoteStream = null;
selectedCameraId = DEVICE_DISABLED_DEVICE_ID; selectedCameraId = DEVICE_DISABLED_DEVICE_ID;
selectedAudioInputId = DEVICE_DISABLED_DEVICE_ID; selectedAudioInputId = DEVICE_DISABLED_DEVICE_ID;
@ -577,6 +579,7 @@ async function closeVideoCall() {
window.inboxStore?.dispatch(endCall()); window.inboxStore?.dispatch(endCall());
remoteVideoStreamIsMuted = true; remoteVideoStreamIsMuted = true;
timestampAcceptedCall = undefined;
makingOffer = false; makingOffer = false;
ignoreOffer = false; ignoreOffer = false;
@ -638,11 +641,17 @@ function createOrGetPeerConnection(withPubkey: string, isAcceptingCall = false)
dataChannel.onmessage = onDataChannelReceivedMessage; dataChannel.onmessage = onDataChannelReceivedMessage;
dataChannel.onopen = onDataChannelOnOpen; dataChannel.onopen = onDataChannelOnOpen;
if (!isAcceptingCall) { peerConnection.onnegotiationneeded = async () => {
peerConnection.onnegotiationneeded = async () => { const shouldTriggerAnotherNeg =
isAcceptingCall && timestampAcceptedCall && Date.now() - timestampAcceptedCall > 1000;
if (!isAcceptingCall || shouldTriggerAnotherNeg) {
await handleNegotiationNeededEvent(withPubkey); await handleNegotiationNeededEvent(withPubkey);
}; } else {
} window.log.info(
'should negotaite again but we accepted the call recently, so swallowing this one'
);
}
};
peerConnection.onsignalingstatechange = handleSignalingStateChangeEvent; peerConnection.onsignalingstatechange = handleSignalingStateChangeEvent;
@ -685,6 +694,8 @@ function createOrGetPeerConnection(withPubkey: string, isAcceptingCall = false)
return peerConnection; return peerConnection;
} }
let timestampAcceptedCall: number | undefined;
// tslint:disable-next-line: function-name // tslint:disable-next-line: function-name
export async function USER_acceptIncomingCallRequest(fromSender: string) { export async function USER_acceptIncomingCallRequest(fromSender: string) {
window.log.info('USER_acceptIncomingCallRequest'); window.log.info('USER_acceptIncomingCallRequest');
@ -719,6 +730,7 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
} }
currentCallUUID = lastOfferMessage.uuid; currentCallUUID = lastOfferMessage.uuid;
timestampAcceptedCall = Date.now();
peerConnection = createOrGetPeerConnection(fromSender, true); peerConnection = createOrGetPeerConnection(fromSender, true);
await openMediaDevicesAndAddTracks(); await openMediaDevicesAndAddTracks();
@ -774,7 +786,8 @@ export async function rejectCallAlreadyAnotherCall(fromSender: string, forcedUUI
// tslint:disable-next-line: function-name // tslint:disable-next-line: function-name
export async function USER_rejectIncomingCallRequest(fromSender: string) { export async function USER_rejectIncomingCallRequest(fromSender: string) {
setIsRinging(false); setIsRinging(false);
// close the popup call
window.inboxStore?.dispatch(endCall());
const lastOfferMessage = findLastMessageTypeFromSender( const lastOfferMessage = findLastMessageTypeFromSender(
fromSender, fromSender,
SignalService.CallMessage.Type.OFFER SignalService.CallMessage.Type.OFFER
@ -798,16 +811,15 @@ export async function USER_rejectIncomingCallRequest(fromSender: string) {
// clear the ongoing call if needed // clear the ongoing call if needed
if (ongoingCallWith && ongoingCallStatus && ongoingCallWith === fromSender) { if (ongoingCallWith && ongoingCallStatus && ongoingCallWith === fromSender) {
await closeVideoCall(); closeVideoCall();
} }
// close the popup call
window.inboxStore?.dispatch(endCall());
} }
async function sendCallMessageAndSync(callmessage: CallMessage, user: string) { async function sendCallMessageAndSync(callmessage: CallMessage, user: string) {
await getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(user), callmessage); await Promise.all([
await getMessageQueue().sendToPubKeyNonDurably(UserUtils.getOurPubKeyFromCache(), callmessage); getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(user), callmessage),
getMessageQueue().sendToPubKeyNonDurably(UserUtils.getOurPubKeyFromCache(), callmessage),
]);
} }
// tslint:disable-next-line: function-name // tslint:disable-next-line: function-name
@ -834,7 +846,7 @@ export async function USER_hangup(fromSender: string) {
clearCallCacheFromPubkeyAndUUID(fromSender, currentCallUUID); clearCallCacheFromPubkeyAndUUID(fromSender, currentCallUUID);
await closeVideoCall(); closeVideoCall();
} }
/** /**
@ -858,14 +870,14 @@ export async function handleCallTypeEndCall(sender: string, aboutCallUUID?: stri
(ongoingCallStatus === 'incoming' || ongoingCallStatus === 'connecting') && (ongoingCallStatus === 'incoming' || ongoingCallStatus === 'connecting') &&
ongoingCallWith === ownerOfCall ongoingCallWith === ownerOfCall
) { ) {
await closeVideoCall(); closeVideoCall();
window.inboxStore?.dispatch(endCall()); window.inboxStore?.dispatch(endCall());
} }
return; return;
} }
if (aboutCallUUID === currentCallUUID) { if (aboutCallUUID === currentCallUUID) {
await closeVideoCall(); closeVideoCall();
window.inboxStore?.dispatch(endCall()); window.inboxStore?.dispatch(endCall());
} }
} }
@ -1069,7 +1081,7 @@ export async function handleCallTypeAnswer(sender: string, callMessage: SignalSe
rejectedCallUUIDS.add(callMessageUUID); rejectedCallUUIDS.add(callMessageUUID);
// if this call is about the one being currently displayed, force close it // if this call is about the one being currently displayed, force close it
if (ongoingCallStatus && ongoingCallWith === foundOwnerOfCallUUID) { if (ongoingCallStatus && ongoingCallWith === foundOwnerOfCallUUID) {
await closeVideoCall(); closeVideoCall();
} }
window.inboxStore?.dispatch(endCall()); window.inboxStore?.dispatch(endCall());

Loading…
Cancel
Save