working video calls accept with real streaming with android

pull/1939/head
Audric Ackermann 4 years ago
parent 8b611a2867
commit 94bc3da2c7
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -110,7 +110,8 @@ export const CallContainer = () => {
<CallWindow>
<CallWindowInner>
<CallWindowHeader>{ongoingCallProps.name}</CallWindowHeader>
<VideoContainer />
<VideoContainer autoPlay={true} id="video-remote" />
<VideoContainer autoPlay={true} id="video-local" />
<CallWindowControls>
<SessionButton text={'end call'} onClick={handleEndCall} />
</CallWindowControls>

@ -1,6 +1,12 @@
import _ from 'lodash';
import { SignalService } from '../../protobuf';
import { answerCall, callConnected, endCall, incomingCall } from '../../state/ducks/conversations';
import {
answerCall,
callConnected,
endCall,
incomingCall,
startingCallWith,
} from '../../state/ducks/conversations';
import { CallMessage } from '../messages/outgoing/controlMessage/CallMessage';
import { ed25519Str } from '../onions/onionPath';
import { getMessageQueue } from '../sending';
@ -13,7 +19,7 @@ const callCache = new Map<string, Array<SignalService.CallMessage>>();
let peerConnection: RTCPeerConnection | null;
const ENABLE_VIDEO = false;
const ENABLE_VIDEO = true;
const configuration = {
configuration: {
@ -32,7 +38,7 @@ const configuration = {
// tslint:disable-next-line: function-name
export async function USER_callRecipient(recipient: string) {
window?.log?.info(`starting call with ${ed25519Str(recipient)}..`);
window.inboxStore?.dispatch(startingCallWith({ pubkey: recipient }));
if (peerConnection) {
window.log.info('closing existing peerconnection');
peerConnection.close();
@ -50,7 +56,9 @@ export async function USER_callRecipient(recipient: string) {
window.inboxStore?.dispatch(callConnected({ pubkey: recipient }));
}
});
peerConnection.addEventListener('ontrack', event => {
console.warn('ontrack:', event);
});
peerConnection.addEventListener('icecandidate', event => {
// window.log.warn('event.candidate', event.candidate);
@ -60,6 +68,20 @@ export async function USER_callRecipient(recipient: string) {
}
});
const localVideo = document.querySelector('#video-local') as any;
if (localVideo) {
localVideo.srcObject = mediaDevices;
}
const remoteStream = new MediaStream();
peerConnection.addEventListener('track', event => {
const remoteVideo = document.querySelector('#video-remote') as any;
if (remoteVideo) {
remoteVideo.srcObject = remoteStream;
}
remoteStream.addTrack(event.track);
});
const offerDescription = await peerConnection.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: ENABLE_VIDEO,
@ -155,6 +177,7 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
);
return;
}
window.inboxStore?.dispatch(answerCall({ pubkey: fromSender }));
if (peerConnection) {
window.log.info('closing existing peerconnection');
@ -167,19 +190,20 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
// window.log.info('USER_acceptIncomingCallRequest adding track ', track);
peerConnection?.addTrack(track, mediaDevices);
});
peerConnection.addEventListener('icecandidateerror', event => {
console.warn('icecandidateerror:', event);
});
peerConnection.addEventListener('negotiationneeded', event => {
console.warn('negotiationneeded:', event);
});
peerConnection.addEventListener('signalingstatechange', _event => {
// console.warn('signalingstatechange:', event);
});
const localVideo = document.querySelector('#video-local') as any;
if (localVideo) {
localVideo.srcObject = mediaDevices;
}
peerConnection.addEventListener('ontrack', event => {
console.warn('ontrack:', event);
const remoteStream = new MediaStream();
peerConnection.addEventListener('track', event => {
const remoteVideo = document.querySelector('#video-remote') as any;
if (remoteVideo) {
remoteVideo.srcObject = remoteStream;
}
remoteStream.addTrack(event.track);
});
peerConnection.addEventListener('connectionstatechange', _event => {
window.log.info(
@ -238,8 +262,6 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
window.log.info('sending ANSWER MESSAGE');
await getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(fromSender), callAnswerMessage);
window.inboxStore?.dispatch(answerCall({ pubkey: fromSender }));
}
// tslint:disable-next-line: function-name
@ -258,6 +280,14 @@ export async function USER_rejectIncomingCallRequest(fromSender: string) {
export function handleEndCallMessage(sender: string) {
callCache.delete(sender);
const remoteVideo = document.querySelector('#video-remote') as any;
if (remoteVideo) {
remoteVideo.srcObject = null;
}
const localVideo = document.querySelector('#video-local') as any;
if (localVideo) {
localVideo.srcObject = null;
}
//
// FIXME audric trigger UI cleanup
window.inboxStore?.dispatch(endCall({ pubkey: sender }));

@ -824,6 +824,23 @@ const conversationsSlice = createSlice({
void foundConvo.commit();
return state;
},
startingCallWith(state: ConversationsStateType, action: PayloadAction<{ pubkey: string }>) {
const callerPubkey = action.payload.pubkey;
const existingCallState = state.conversationLookup[callerPubkey].callState;
if (existingCallState && existingCallState !== 'none') {
return state;
}
const foundConvo = getConversationController().get(callerPubkey);
if (!foundConvo) {
return state;
}
// we have to update the model itself.
// not the db (as we dont want to store that field in it)
// and not the redux store directly as it gets overriden by the commit() of the conversationModel
foundConvo.callState = 'offering';
void foundConvo.commit();
return state;
},
},
extraReducers: (builder: any) => {
// Add reducers for additional action types here, and handle loading state as needed
@ -888,6 +905,7 @@ export const {
endCall,
answerCall,
callConnected,
startingCallWith,
} = actions;
export async function openConversationWithMessages(args: {

Loading…
Cancel
Save