podchat-browser
Version:
Javascript SDK to use POD's Chat Service - Browser Only
1,193 lines (1,064 loc) • 49.5 kB
JavaScript
import CallUsers from "./callUsers";
import Utility from "../../utility/utility";
import CallServerManager from "./callServerManager";
import {callMetaDataTypes} from "../constants";
import {errorList} from "../errorHandler";
import ScreenShareStateManager from "./screenShareStateManager"
function CallManager({app, callId, callConfig}) {
const config = {
callId,
callConfig,
users: new CallUsers({app, callId}),
callServerController: new CallServerManager(app),
screenShareInfo: new ScreenShareStateManager(app),
onChatReadyUniqueId: null,
failedPeersQueue: [],
inquiryCallCounter: 0,
isDestroyed: false
};
function reconnectFailedPeers() {
while(config.failedPeersQueue.length) {
const topic = config.failedPeersQueue.shift();
topic.shouldReconnectTopic();
}
}
function canReconnect() {
return config.failedPeersQueue.length && app.callsManager.currentCallId() == config.callId;
}
function socketConnectListener() {
if (!config.inquiryCallCounter) {
let dataChangeDetected = false;
config.inquiryCallCounter++;
setTimeout(() => {
config.inquiryCallCounter = 0;
if(!config.isDestroyed && canReconnect()) {
socketConnectListener();
}
}, 9000);
canReconnect() && app.call.inquiryCallParticipants.inquiryCallParticipants({}, async result => {
if (!result.hasError) {
if(result.result?.callParticipantVOs && result.result.callParticipantVOs.length) {
let serverUsers = result.result?.callParticipantVOs;
//Sync local users with server users
serverUsers.forEach(item => {
if(!config.users.userExists(item.userId)) {
config.users.addItem({
clientId: item.participantVO.ssoId,
topicSend: item.sendTopic,
mute: item.mute,
video: item.video,
userId: item.userId,
callId : config.callId,
cameraPaused : false,
brokerAddress : config.callConfig.brokerAddress
});
dataChangeDetected = true;
}
});
let serverUserIds = serverUsers.map(item => item.userId);
Object.keys(config.users.getAll()).forEach(key => {
if(!serverUserIds.includes(Number(key)) && key != 'screenShare') {
config.users.removeItem(key);
}
dataChangeDetected = true;
});
}
//TODO: IT gives screenShareUser client id instead of its chat user id,
// It might needs change in future
if(Number(result.result.screenShareUser)) {
let screenOwnerChatId = config.users.findUserIdByClientId(Number(result.result.screenShareUser));
callConfig.screenShareOwner = screenOwnerChatId;
config.screenShareInfo.setOwner(callConfig.screenShareOwner);
config.screenShareInfo.setIsStarted(true);
// if (config.screenShareInfo.isStarted()) {
config.callConfig.screenShareObject.clientId = Number(result.result.screenShareUser);
config.callConfig.screenShareObject.brokerAddress = config.callConfig.brokerAddress;
// config.screenShareInfo.setOwner(config.callConfig.screenShareOwner);
// }
if(config.users.userExists('screenShare')) {
await config.users.removeItem('screenShare');
dataChangeDetected = true;
}
config.users.addItem(config.callConfig.screenShareObject, "screenShare");
} else if(config.users.userExists('screenShare')) {
await config.users.removeItem('screenShare');
dataChangeDetected = true;
}
if (Number(result.result.recordingUser)) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_RECORDING_STARTED',
callId: config.callId,
result: {
id: result.result.recordingUser
}
});
} else if(config.callConfig.recordingOwner) {
app.chatEvents.fireEvent('callEvents', {
type: 'STOP_RECORDING_CALL',
callId: config.callId,
result: {
id: config.callConfig.recordingOwner
}
});
}
setTimeout(()=>{
config.isReconnecting = true;
reconnectFailedPeers();
}, 500);
} else {
if (result.errorCode == 171) {
let callId = config.callId;
app.call.endCall({callId: config.callId}, null);
app.callsManager.removeItem(config.callId);
app.chatEvents.fireEvent('callEvents', {
type: 'YOU_DROPPED_FROM_CALL',
callId: callId,
result: {
callId: callId,
userId: app.store.user.get().id,
}
});
} else if (result.errorCode == 163) {
app.call.endCall({callId: config.callId}, null);
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ENDED',
callId: config.callId
});
app.callsManager.removeItem(config.callId);
} else if (result.errorCode == 160) {
app.call.endCall({callId: config.callId}, null);
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ENDED',
callId: config.callId
});
app.callsManager.removeItem(config.callId);
}
}
});
}
}
function startCallWebRTCFunctions(callConfig) {
config.onChatReadyUniqueId = app.chatEvents.on('chatReady', socketConnectListener);
config.callServerController.setServers(callConfig.kurentoAddress);
// if (app.call.sharedVariables.callDivId) {
new Promise(resolve => {
let callVideo = (typeof callConfig.video === 'boolean') ? callConfig.video : true,
callMute = (typeof callConfig.mute === 'boolean') ? callConfig.mute : false;
if (callConfig.selfData) {
callConfig.selfData.callId = config.callId;
callConfig.selfData.cameraPaused = callConfig.cameraPaused;
config.users.addItem(callConfig.selfData);
// callStateController.setupCallParticipant(params.selfData);
}
config.screenShareInfo.setOwner(callConfig.screenShareOwner);
config.screenShareInfo.setIsStarted(!!callConfig.screenShareOwner);
if (callConfig.recordingOwner) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_RECORDING_STARTED',
callId: config.callId,
result: {
id: callConfig.recordingOwner
}
});
if (config.users.get(app.store.user.get().id).user().video) {
config.users.get(app.store.user.get().id).videoTopicManager().restartMediaOnKeyFrame(app.store.user.get().id, [4000, 12000, 16000, 24000]);
}
}
if (callConfig.clientsList && callConfig.clientsList.length) {
for (let i in callConfig.clientsList) {
if (callConfig.clientsList[i].userId !== app.store.user.get().id) {
callConfig.clientsList[i].callId = config.callId;
callConfig.clientsList[i].cameraPaused = false;
config.users.addItem(callConfig.clientsList[i]);
}
}
}
config.callConfig.screenShareObject = {
callId: config.callId,
cameraPaused: false,
userId: "screenShare",
topicSend: callConfig.screenShare
}
config.screenShareInfo.setIsStarted(!!config.callConfig.screenShareOwner);
if (config.screenShareInfo.isStarted()) {
config.screenShareInfo.setOwner(config.callConfig.screenShareOwner);
config.users.addItem(config.callConfig.screenShareObject, "screenShare");
}
config.callConfig.callVideo = callVideo;
config.callConfig.callAudio = callMute;
createSessionInChat();
resolve();
}).then(() => {
app.call.currentCall().sendCallDivs();
})
//
// } else {
// app.sdkParams.consoleLogging && console.log('No Call DIV has been declared!');
// }
}
function createSessionInChat() {
app.call.callStopQueue.callStarted = true;
let message = {
id: 'CREATE_SESSION',
brokerAddress: config.callConfig.brokerAddress,
turnAddress: config.callConfig.turnAddress.split(',')[0]
},
onResultCallback = function (res) {
if (res.done === 'TRUE') {
app.call.callStopQueue.callStarted = true;
// callController.startCall(params);
} else {
app.callsManager.removeItem(config.callId);
// endCall({callId: config.callId});
// callStop(true, true);
}
}
sendCallMessage(message, onResultCallback, {
timeoutTime: 4000,
timeoutRetriesCount: 5
}
)
}
async function callStop(resetCurrentCallId = true, resetCameraPaused = true) {
await config.users.destroy();
if (app.call.callStopQueue.callStarted) {
sendCallMessage({
id: 'CLOSE'
}, null, {});
app.call.callStopQueue.callStarted = false;
}
if (resetCameraPaused)
app.call.joinCallParams.cameraPaused = false;
clearTimeout(config.callRequestTimeout);
config.callConfig = {};
if (resetCurrentCallId)
config.callId = null;
}
function sendCallMessage(message, callback, {
timeoutTime = 0,
timeoutRetriesCount = 0
}) {
message.token = app.sdkParams.token;
// let uniqueId;
if (!message.uniqueId) {
message.uniqueId = Utility.generateUUID();
}
// message.uniqueId = uniqueId;
message.chatId = config.callId;
let data = {
type: 3,
content: {
peerName: config.callServerController.getCurrentServer(),// callServerName,
priority: 1,
content: JSON.stringify(message),
ttl: app.sdkParams.messageTtl
},
uniqueId: message.uniqueId
};
if (typeof callback == 'function') {
app.store.messagesCallbacks[message.uniqueId] = callback;
}
app.call.sharedVariables.asyncClient.send(data, function (res) {});
if (timeoutTime || app.call.sharedVariables.globalCallRequestTimeout > 0) {
app.store.asyncRequestTimeouts[message.uniqueId] && clearTimeout(app.store.asyncRequestTimeouts[message.uniqueId]);
app.store.asyncRequestTimeouts[message.uniqueId] = setTimeout(function () {
if (app.store.messagesCallbacks[message.uniqueId]) {
delete app.store.messagesCallbacks[message.uniqueId];
}
if (timeoutRetriesCount) {
app.logger.warn(app.logger.tags.CALL_SERVER_MESSAGE.id,
`[sendCallMessage] `,
{msg: " Retrying call request. uniqueId: " + message.uniqueId, message}
);
// app.sdkParams.consoleLogging && console.log("[SDK][sendCallMessage] Retrying call request. uniqueId :" + message.uniqueId, {message})
sendCallMessage(message, callback, {timeoutTime, timeoutRetriesCount: timeoutRetriesCount - 1})
} else if (typeof callback == 'function') {
/**
* Request failed
*/
callback({
done: 'SKIP'
});
}
}, timeoutTime || app.call.sharedVariables.globalCallRequestTimeout);
}
}
function subscribeToReceiveOffers(jsonMessage) {
if (jsonMessage.upOrDown === true) { //TRUE if participant is sending data on this topic
sendCallMessage({
id: 'SUBSCRIBE',
useComedia: true,
useSrtp: false,
topic: jsonMessage.topic,
mediaType: (jsonMessage.topic.indexOf('screen-Share') !== -1 || jsonMessage.topic.indexOf('Vi-') !== -1 ? 2 : 1)
//brokerAddress:brkrAddr
}, null, {
timeoutTime: 4000,
timeoutRetriesCount: 5
});
}
}
function handleProcessSdpOffer(jsonMessage) {
let userId = config.users.findUserIdByTopic(jsonMessage.topic),
topicManager,
peer; //callUsers[userId].peers[jsonMessage.topic];
if (!userId) {
console.warn("[SDK] Skipping PROCESS_SDP_OFFER, topic not exists.", {jsonMessage})
return;
}
let userObj = config.users.get(userId);
if (jsonMessage.topic.indexOf('Vi-') !== -1 || jsonMessage.topic.indexOf('screen-Share') !== -1) {
topicManager = config.users.get(userId).videoTopicManager()
peer = topicManager.videoTopicManager().getPeer();
} else if (jsonMessage.topic.indexOf('Vo-') !== -1) {
topicManager = config.users.get(userId).audioTopicManager();
peer = topicManager.audioTopicManager().getPeer();
}
if (peer == null) {
console.warn("[handleProcessSdpAnswer] Skip, no WebRTC Peer");
return;
}
peer.processOffer(jsonMessage.sdpOffer, function (err, sdpAnswer) {
if (err) {
console.error("[SDK][handleProcessSdpOffer] Error: " + err);
stop();
return;
}
sendCallMessage({
id: 'RECIVE_SDP_ANSWER',
sdpAnswer: sdpAnswer,
useComedia: true,
useSrtp: false,
topic: jsonMessage.topic,
mediaType: (jsonMessage.topic.indexOf('screen-Share') !== -1 || jsonMessage.topic.indexOf('Vi-') !== -1 ? 2 : 1)
}, null, {
timeoutTime: 4000,
timeoutRetriesCount: 5
});
topicManager.topicMetaData().sdpAnswerReceived = true;
// topicManager.startMedia()
// if (userObj.isScreenShare() || userObj.isMe()) {
// topicManager.restartMediaOnKeyFrame(userId, [2000, 4000, 8000, 12000]);
// }
});
}
function handleProcessSdpAnswer(jsonMessage) {
let userId = config.users.findUserIdByTopic(jsonMessage.topic),
topicManager,
peer; // = callUsers[userId].peers[jsonMessage.topic];
if (!userId) {
console.warn("[SDK] Skipping PROCESS_SDP_ANSWER, topic not exists. ", {jsonMessage})
return;
}
let userObj = config.users.get(userId);
if (jsonMessage.topic.indexOf('Vi-') !== -1 || jsonMessage.topic.indexOf('screen-Share') !== -1) {
topicManager = userObj.videoTopicManager();
} else if (jsonMessage.topic.indexOf('Vo-') !== -1) {
topicManager = userObj.audioTopicManager();
}
if (!topicManager)
return;
peer = topicManager.getPeer();
if (peer == null) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "[handleProcessSdpAnswer] Skip, no WebRTC Peer",
error: peer,
environmentDetails: getCallDetails()
});
return;
}
peer.processAnswer(jsonMessage.sdpAnswer, (err) => {
if (err) {
sendCallSocketError("[handleProcessSdpAnswer] Error: " + err);
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "[handleProcessSdpAnswer] Error: " + err,
environmentDetails: getCallDetails()
});
return;
}
app.sdkParams.consoleLogging && console.log("[SDK][handleProcessSdpAnswer]", jsonMessage, jsonMessage.topic, topicManager.metadata().isIceCandidateIntervalSet().toString());
if (topicManager.metadata().isIceCandidateIntervalSet()) {
topicManager.topicMetaData().sdpAnswerReceived = true;
// topicManager.startMedia()
// if (userId == 'screenShare' || userId == app.store.user.get().id) {
// topicManager.restartMediaOnKeyFrame(userId, [2000, 4000, 8000, 12000, 20000]);
// }
}
});
}
function handleAddIceCandidate(jsonMessage) {
let userId = config.users.findUserIdByTopic(jsonMessage.topic);
if (!userId) {
console.warn("[SDK] Skipping ADD_ICE_CANDIDATE, topic not exists.", {jsonMessage})
return;
}
let peer; //= callUsers[userId].peers[jsonMessage.topic];
if (jsonMessage.topic.indexOf('Vi-') > -1 || jsonMessage.topic.indexOf('screen-Share') !== -1) {
peer = config.users.get(userId).videoTopicManager();
} else if (jsonMessage.topic.indexOf('Vo-') > -1) {
peer = config.users.get(userId).audioTopicManager();
}
if (!peer)
return;
peer = peer.getPeer();
if (peer == null) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "[handleAddIceCandidate] Skip, no WebRTC Peer",
error: JSON.stringify(peer),
environmentDetails: getCallDetails()
});
return;
}
peer.addIceCandidate(jsonMessage.candidate, (err) => {
if (err) {
console.error("[handleAddIceCandidate] " + err);
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "[handleAddIceCandidate] " + err,
error: JSON.stringify(jsonMessage.candidate),
environmentDetails: getCallDetails()
});
return;
}
});
}
function getCallDetails(customData) {
return {
currentUser: app.store.user.get(),
// currentServers: {
// callTurnIp: app.call.sharedVariables.callTurnIp,
// },
isJanus: config.callId && config.callServerController.isJanus(),
screenShareInfo: {
isStarted: config.screenShareInfo.isStarted(),
iAmOwner: config.screenShareInfo.iAmOwner(),
},
callId: config.callId,
startCallInfo: config.callConfig,
...customData,
}
}
function sendCallSocketError(message) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: message,
environmentDetails: getCallDetails()
});
sendCallMessage({
id: 'ERROR',
message: message,
}, null, {});
}
function handlePartnerFreeze(jsonMessage) {
if (!!jsonMessage && !!jsonMessage.topic && jsonMessage.topic.substring(0, 2) === 'Vi') {
let userId = config.users.findUserIdByTopic();
if (userId) {
config.users.get(userId).videoTopicManager().restartMedia()
setTimeout(function () {
config.users.get(userId).videoTopicManager().restartMedia()
}, 4000);
setTimeout(function () {
config.users.get(userId).videoTopicManager().restartMedia()
}, 8000);
}
}
}
function handleReceivedMetaData(jsonMessage, uniqueId) {
let jMessage = JSON.parse(jsonMessage.message);
let id = jMessage.id;
if (!id || typeof id === "undefined" || jsonMessage.userid == app.store.user.get().id) {
return;
}
switch (id) {
case callMetaDataTypes.POORCONNECTION:
publicized.sendQualityCheckEvent({
userId: jMessage.userid,
topic: jMessage.content.description,//jMessage.topic,
mediaType: (jMessage.content.description.indexOf('Vi') !== -1 ? 'video' : 'audio'),//jMessage.mediaType,
canSendCallMetaData: false
});
break;
case callMetaDataTypes.POORCONNECTIONRESOLVED:
publicized.sendQualityCheckEvent({
userId: jMessage.userid,
topic: jMessage.content.description,
mediaType: (jMessage.content.description.indexOf('Vi') !== -1 ? 'video' : 'audio'),
isResolved: true,
canSendCallMetaData: false
});
break;
case callMetaDataTypes.CUSTOMUSERMETADATA:
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](jsonMessage);
}
app.chatEvents.fireEvent('callEvents', {
type: 'CUSTOM_USER_METADATA',
callId: config.callId,
userId: jMessage.userid,
content: jMessage.content
});
break;
case callMetaDataTypes.SCREENSHAREMETADATA:
if (config.screenShareInfo.isStarted()) {
config.screenShareInfo.setWidth(jMessage.content.dimension.width);
config.screenShareInfo.setHeight(jMessage.content.dimension.height);
// applyScreenShareSizeToElement();
if (config.screenShareInfo.iAmOwner()) {
setTimeout(() => {
if (config.users.get('screenShare') && config.users.get('screenShare').videoTopicManager())
config.users.get('screenShare').videoTopicManager().restartMediaOnKeyFrame('screenShare', [2000]);
}, 2500)
}
app.chatEvents.fireEvent("callEvents", {
type: 'SCREENSHARE_METADATA',
callId: config.callId,
userId: jMessage.userid,
content: jMessage.content
});
}
break;
}
}
function sendCallMetaData(params) {
let message = {
id: params.id,
userid: params.userid,
content: params.content || undefined
};
sendCallMessage({
id: 'SENDMETADATA',
message: JSON.stringify(message),
chatId: config.callId
}, null, {});
}
function handleError(jsonMessage, sendingTopic, receiveTopic) {
const errMessage = jsonMessage.message;
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "Kurento error: " + errMessage,
environmentDetails: getCallDetails()
});
}
const publicized = {
queueMeForReconnect(topic) {
config.failedPeersQueue.push(topic);
},
callServerController() {
return config.callServerController
},
callConfig() {
return config.callConfig;
},
callStop,
endCall: app.call.endCall,
users() {
return config.users;
},
sendCallDivs() {
if(app.sdkParams.enableCallDivs) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_DIVS',
callId: config.callId,
result: config.users.generateCallUIList()
});
} else {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_STREAMS',
callId: config.callId,
result: config.users.generateCallStreamsList()
});
}
},
screenShareInfo: config.screenShareInfo,
raiseCallError: function (errorObject, callBack, fireEvent) {
app.errorHandler.raiseError(errorObject, callBack, fireEvent, {
eventName: 'callEvents',
eventType: 'CALL_ERROR',
environmentDetails: getCallDetails()
});
},
getCallDetails,
sendCallMessage,
getTurnServer: function (params) {
// if (!!params.turnAddress && params.turnAddress.length > 0
// || (app.call.sharedVariables.useInternalTurnAddress && !!params.internalTurnAddress && params.turnAddress.length > 0)) {
let serversTemp = app.call.sharedVariables.useInternalTurnAddress ? params.internalTurnAddress.split(',') : params.turnAddress.split(','),
turnsList = [];
if(app.call.sharedVariables.useCustomTurnAddress) {
return [
{
"urls": "turn:" + app.call.sharedVariables.callTurnIp + ":3478",
"username": "mkhorrami",
"credential": "mkh_123456"
}
];
} else {
for (let i in serversTemp) {
turnsList.push({
"urls": "turn:" + serversTemp[i],
"username": "mkhorrami",
"credential": "mkh_123456"
})
}
return turnsList;
}
// } else {
// return [
// {
// "urls": "turn:" + app.call.sharedVariables.callTurnIp + ":3478",
// "username": "mkhorrami",
// "credential": "mkh_123456"
// }
// ];
// }
},
sendQualityCheckEvent: function ({
userId,
topic,
mediaType,
isLongTime = false,
isResolved = false,
canSendCallMetaData = true
}) {
if (mediaType === 'video') { //TODO: Deprecated!
app.chatEvents.fireEvent('callEvents', {
type: isResolved ? 'POOR_VIDEO_CONNECTION_RESOLVED' : 'POOR_VIDEO_CONNECTION',
callId: config.callId,
subType: (isResolved ? undefined : (isLongTime ? 'LONG_TIME' : 'SHORT_TIME')),
message: 'Poor connection resolved',
metadata: {
elementId: "uiRemoteVideo-" + topic,
topic: topic,
userId: userId
}
});
}
app.chatEvents.fireEvent('callEvents', {
type: isResolved ? 'POOR_CONNECTION_RESOLVED' : 'POOR_CONNECTION',
callId: config.callId,
subType: (isResolved ? undefined : (isLongTime ? 'LONG_TIME' : 'SHORT_TIME')),
message: `Poor connection ${(isResolved ? 'resolved' : '')}`,
metadata: {
media: mediaType,
elementId: "uiRemoteVideo-" + topic,
topic: topic,
userId: userId
}
});
if (canSendCallMetaData) {
sendCallMetaData({
id: (isResolved ? callMetaDataTypes.POORCONNECTIONRESOLVED : callMetaDataTypes.POORCONNECTION),
userid: userId,
content: {
title: `Poor Connection ${(isResolved ? 'Resolved' : '')}`,
description: topic,
}
});
}
},
processCallMessage: function (message) {
let uniqueId = message.uniqueId;
if (message.done !== 'FALSE' || (message.done === 'FALSE' && message.desc === 'duplicated')) {
app.store.asyncRequestTimeouts[uniqueId] && clearTimeout(app.store.asyncRequestTimeouts[uniqueId]);
} else if (message.done === 'FALSE') {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ERROR',
callId: config.callId,
code: 7000,
message: "Kurento error: " + (message.desc ? message.desc : message.message),
environmentDetails: getCallDetails()
});
}
switch (message.id) {
case 'PROCESS_SDP_ANSWER':
handleProcessSdpAnswer(message);
break;
case 'RECEIVING_MEDIA': // Only for receiving topics from janus, first we subscribe
subscribeToReceiveOffers(message);
break;
case 'PROCESS_SDP_OFFER': //Then janus sends offers
handleProcessSdpOffer(message);
break;
case 'ADD_ICE_CANDIDATE':
handleAddIceCandidate(message);
break;
case 'GET_KEY_FRAME':
let user = config.users.get(app.store.user.get().id);
if (user && user.user().video) {
user.videoTopicManager().restartMediaOnKeyFrame(app.store.user.get().id, [2000, 4000, 8000, 12000]);
}
let screenShareuser = config.users.get('screenShare');
if (screenShareuser
&& screenShareuser.user().video
&& config.screenShareInfo.isStarted()
&& config.screenShareInfo.iAmOwner()
) {
screenShareuser.videoTopicManager().restartMediaOnKeyFrame('screenShare', [2000, 4000, 8000, 12000]);
}
break;
case 'FREEZED':
handlePartnerFreeze(message);
break;
/*case 'STOPALL':
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](jsonMessage);
}
break;*/
case 'STOP':
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](message);
}
break;
case 'CLOSE':
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](message);
}
break;
case 'SESSION_NEW_CREATED':
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](message);
}
break;
case 'SESSION_REFRESH':
if (app.store.messagesCallbacks[uniqueId]) {
app.store.messagesCallbacks[uniqueId](message);
}
break;
case 'RECEIVEMETADATA':
handleReceivedMetaData(message, uniqueId);
break;
case 'ERROR':
publicized.raiseCallError(app.errorHandler.getFilledErrorObject({
...errorList.CALL_SERVER_ERROR,
replacements: [JSON.stringify(message)]
}), null, true);
break;
case 'SEND_SDP_OFFER':
case 'RECIVE_SDP_OFFER':
case 'SDP_ANSWER_RECEIVED':
break;
default:
console.warn("[SDK][onmessage] Invalid message, id: " + message.id, message);
// if (jsonMessage.match(/NOT CREATE SESSION/g)) {
// if (currentCallParams && Object.keys(currentCallParams)) {
// //handleCallSocketOpen(currentCallParams);
// callStateController.createSessionInChat(currentCallParams);
// }
// }
break;
}
app.store.messagesCallbacks[uniqueId] && delete app.store.messagesCallbacks[uniqueId];
},
handleParticipantJoin(messageContent, threadId) {
if (Array.isArray(messageContent)) {
for (let i in messageContent) {
let correctedData = {
video: messageContent[i].video,
mute: messageContent[i].mute,
userId: messageContent[i].userId,
topicSend: messageContent[i].sendTopic,
autoStartStreams: true,
callId: config.callId,
cameraPaused: false
};
if (!config.users.get(correctedData.userId)) {
new Promise(resolve => {
config.users.addItem(correctedData);
resolve();
}).then(() => {
app.call.currentCall().sendCallDivs()
})
} else {
config.users.removeItem(correctedData.userId);
new Promise(resolve => {
config.users.addItem(correctedData);
resolve();
}).then(() => {
app.call.currentCall().sendCallDivs()
})
}
}
}
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_PARTICIPANT_JOINED',
callId: config.callId,
result: messageContent
});
if (config.users.get(app.store.user.get().id).video) {
config.users.get(app.store.user.get().id).videoTopicManager().restartMediaOnKeyFrame(app.store.user().id, [2000, 4000, 8000, 12000, 16000, 24000]);
}
if (config.screenShareInfo.isStarted()
&& config.screenShareInfo.iAmOwner()
) {
sendCallMetaData({
id: callMetaDataTypes.SCREENSHAREMETADATA,
userid: app.store.user.get().id,
content: {
dimension: {
width: config.screenShareInfo.getWidth(),
height: config.screenShareInfo.getHeight()
}
}
});
// config.users.get('screenShare').videoTopicManager().restartMediaOnKeyFrame('screenShare', [2000, 4000, 8000, 12000, 16000, 24000]);
}
},
async handleParticipantLeft(messageContent, threadId) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_PARTICIPANT_LEFT',
callId: config.callId,
result: messageContent
});
//If I'm the only call participant, stop the call
if (Object.values(config.users.getAll()).length < 2) {
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_ENDED',
callId: config.callId
});
app.callsManager.removeItem(config.callId);
return;
}
if (!!messageContent[0].userId) {
//console.log("chatMessageVOTypes.LEAVE_CALL: ", messageContent[0].userId, store.user().id)
if (messageContent[0].userId == app.store.user.get().id) {
// await callStop();
app.callsManager.removeItem(config.callId);
} else {
await config.users.removeItem(messageContent[0].userId);
if (config.screenShareInfo.isStarted() && config.screenShareInfo.getOwner() === messageContent[0].userId) {
config.users.removeItem("screenShare")
}
//callStateController.removeScreenShareFromCall()
}
}
},
handleParticipantMute(messageContent, threadId) {
if (Array.isArray(messageContent)) {
for (let i in messageContent) {
let user = config.users.get(messageContent[i].userId);
if (user) {
user.stopAudio();
}
}
}
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_PARTICIPANT_MUTE',
callId: config.callId,
result: messageContent
});
},
async handleParticipantUnMute(messageContent, threadId) {
if (Array.isArray(messageContent)) {
for (let i in messageContent) {
let user = config.users.get(messageContent[i].userId);
if (user) {
if (user.audioTopicManager()) {
await user.destroyAudio();
}
setTimeout(() => {
user.startAudio(messageContent[i].sendTopic);
}, 50);
}
}
}
app.chatEvents.fireEvent('callEvents', {
type: 'CALL_PARTICIPANT_UNMUTE',
callId: config.callId,
result: messageContent
});
},
async handleParticipantVideoOn(messageContent, threadId) {
if (Array.isArray(messageContent)) {
for (let i in messageContent) {
let user = config.users.get(messageContent[i].userId);
if (user) {
if (user.videoTopicManager()) {
await user.destroyVideo();
}
setTimeout(() => {
user.startVideo(messageContent[i].sendTopic);
}, 50);
}
}
}
setTimeout(function () {
app.call.currentCall().sendCallDivs()
})
app.chatEvents.fireEvent('callEvents', {
type: 'TURN_ON_VIDEO_CALL',
callId: config.callId,
result: messageContent
});
},
handleParticipantVideoOff(messageContent, threadId) {
if (Array.isArray(messageContent)) {
for (let i in messageContent) {
let user = config.users.get(messageContent[i].userId);
if (user)
user.stopVideo();
}
}
setTimeout(function () {
app.call.currentCall().sendCallDivs()
})
app.chatEvents.fireEvent('callEvents', {
type: 'TURN_OFF_VIDEO_CALL',
callId: config.callId,
result: messageContent
});
},
handleStartScreenShare(typeCode, onwerId, messageContent, threadId) {
app.sdkParams.consoleLogging && console.log("[sdk][startScreenShare][onResult]: ", messageContent);
let result = Utility.createReturnData(typeCode, onwerId, false, '', 0, messageContent, null)
if (result.hasError) {
// endScreenShare({}, null);
config.users.removeItem("screenShare");
return;
}
let direction = 'send', shareScreen = true;
config.screenShareInfo.setIsStarted(true);
config.screenShareInfo.setOwner(messageContent.screenOwner.id);
if (config.screenShareInfo.isStarted() && !config.screenShareInfo.iAmOwner()) {
direction = 'receive';
shareScreen = false;
}
if (config.screenShareInfo.isStarted() && config.screenShareInfo.iAmOwner()) {
let qualityObject = app.call.calculateScreenSize({quality: app.call.sharedVariables.startScreenShareParams.quality});
config.screenShareInfo.setWidth(qualityObject.width);
config.screenShareInfo.setHeight(qualityObject.height);
sendCallMetaData({
id: callMetaDataTypes.SCREENSHAREMETADATA,
userid: app.store.user.get().id,
content: {
dimension: {
width: config.screenShareInfo.getWidth(),
height: config.screenShareInfo.getHeight()
}
}
});
}
// callStateController.addScreenShareToCall(direction, shareScreen);
if (config.screenShareInfo.iAmOwner()) {
setTimeout(() => {
doThings();
}, 1000)
} else {
doThings();
}
function doThings() {
callConfig.screenShareObject.callId = config.callId;
callConfig.screenShareObject.cameraPaused = false;
callConfig.screenShareObject.userId = "screenShare";
config.users.addItem(callConfig.screenShareObject, "screenShare");
app.chatEvents.fireEvent('callEvents', {
type: 'START_SCREEN_SHARE',
callId: config.callId,
result: messageContent
});
}
},
async handleEndScreenShare(messageContent, threadId) {
config.screenShareInfo.setIsStarted(false);
config.screenShareInfo.setOwner(messageContent.screenOwner.id);
await config.users.removeItem('screenShare');
await app.call.deviceManager.mediaStreams.stopScreenShareInput();
app.chatEvents.fireEvent('callEvents', {
type: 'END_SCREEN_SHARE',
callId: config.callId,
result: messageContent
});
app.call.currentCall().sendCallDivs()
},
pauseCamera() {
let me = config.users.get(app.store.user.get().id);
if (!me || !me.user().video || !me.videoTopicManager().getPeer())
return;
me.videoTopicManager().pauseSendStream();
},
resumeCamera() {
let me = config.users.get(app.store.user.get().id);
if (!me || !me.user().videoTopicName || !me.videoTopicManager().getPeer())//!me.peers[me.videoTopicName]
return;
me.videoTopicManager().resumeSendStream();
},
pauseMice() {
let me = config.users.get(app.store.user.get().id);
if (!me || !me.user().audioTopicName || !me.audioTopicManager().getPeer())//!me.peers[me.videoTopicName]
return;
me.audioTopicManager().pauseSendStream();
},
resumeMice() {
let me = config.users.get(app.store.user.get().id);
if (!me || !me.user().audioTopicName || !me.audioTopicManager().getPeer())//!me.peers[me.videoTopicName]
return;
me.audioTopicManager().resumeSendStream();
},
onChatConnectionReconnect() {
return;
//First count all failed topics
let ftCount = 0, totalTopics = 0;
Object.values(config.users.getAll()).forEach(item => {
if (item.user().video) {
totalTopics++;
if (item.videoTopicManager().isPeerFailed()) {
ftCount++;
}
}
if (!item.user().mute) {
totalTopics++;
if (item.audioTopicManager().isPeerFailed()) {
ftCount++;
}
}
});
//If only some topics are failed
if (ftCount < totalTopics) {
Object.values(config.users.getAll()).forEach(item => {
if (item.user().video) {
totalTopics++;
if (item.videoTopicManager().isPeerFailed()) {
item.reconnectTopic("video");
}
}
if (!item.user().mute) {
totalTopics++;
if (item.audioTopicManager().isPeerFailed()) {
item.reconnectTopic("audio");
}
}
})
} else {
//Inquiry the call
}
},
async destroy() {
config.isDestroyed = true;
app.chatEvents.off('chatReady', config.onChatReadyUniqueId);
await app.call.deviceManager.onCallEnd();
return callStop()
},
isDestroyed() {
return config.isDestroyed;
}
}
setTimeout(() => {
startCallWebRTCFunctions(config.callConfig);
}, 50)
return publicized;
}
export default CallManager