UNPKG

video-auth-js-sdk

Version:

A SDK to authenticate users with camera through a realtime stream

252 lines (235 loc) 9.73 kB
import {errorList} from "../errorHandler"; import {WebrtcPeerConnection} from "./webrtcPeer"; import Utility from "../utility/utility"; function CallTopicManager( { app, callId, topic, mediaType, direction, deviceManager, isScreenShare, onHTMLElement, onPeerConnect }) { const config = { callId, state: 0, //0: disconnected, 1: connecting, 2: failed, 3: connected, 4: disconnected peer: null, topic, mediaType, direction, isScreenShare, sdpOfferRequestSent: false, htmlElement: null, isDestroyed: false, dataStream: null, statusEventsInterval: null, audioObject: null, alreadyAddedStreamTrackToElement: false }; const peerStates = { DISCONNECTED: 0, CONNECTING: 1, FAILED: 3, CONNECTED: 4 }; const publicized = { setPeerState(state) { config.state = state; }, setIsScreenShare() { config.isScreenShare = true; }, setDirection(direction) { config.direction = direction; }, getPeer() { return config.peer; }, isPeerConnecting() { return config.state === peerStates.CONNECTING; }, isPeerFailed() { return config.state === peerStates.FAILED; }, isPeerConnected() { return config.state === peerStates.CONNECTED; }, isPeerDisconnected() { return config.state === peerStates.DISCONNECTED; }, createTopic() { let manager = this; if (config.peer) { return; } this.generateSdpOfferOptions().then(options => { console.debug("[SDK][generateSdpOfferOptions] Options for this request have been resolved: ", {options}, "topic: ", config.topic, "direction: ", config.direction); manager.establishPeerConnection(options); }).catch(error => { console.error(error) }); }, generateSdpOfferOptions() { return new Promise((resolve, reject) => { let options = { configuration: { iceServers: app.authSessionInfo.turnsList } }; options.stream = app.store.localCameraStream; resolve(options); console.log("[SDK][getSdpOfferOptions] ", "topic: ", config.topic, "mediaType: ", config.mediaType, "direction: ", config.direction, "options: ", options); }); }, establishPeerConnection(options) { let manager = this; config.state = peerStates.CONNECTING; config.peer = new WebrtcPeerConnection({ callId: config.callId, direction: config.direction, mediaType: config.mediaType, stream: options.stream, rtcPeerConfig: options.configuration, connectionStateChange: publicized.onConnectionStateChange, iceConnectionStateChange: publicized.onIceConnectionStateChange, }, function (err) { if (err) { let errorString = "[SDK][start/webRtc Peer] Error: " + err; console.error(errorString); app.publicCallbacks.onError({ code: errorList.FAILED_TO_OPEN_PEER.code, message: errorString }); return; } config.peer.generateOffer((err, sdpOffer) => { // app.sdkParams.consoleLogging && console.debug("[SDK][establishPeerConnection][generateOffer] GenerateOffer:: ", " sdpOffer: ", sdpOffer, " err: ", err); if (err) { let errorString = "[SDK][start/WebRtc Peer/generateOffer] " + err; console.error(errorString); app.publicCallbacks.onError({ code: errorList.FAILED_TO_OPEN_PEER.code, message: errorString }); return; } if (!config.sdpOfferRequestSent) { config.sdpOfferRequestSent = true; manager.sendSDPOfferRequestMessage(sdpOffer, 1); } }); }); }, onConnectionStateChange() { if (!config.peer || publicized.isDestroyed()) { return; //avoid log errors } console.log("[SDK][peerConnection.onconnectionstatechange] ", "peer: ", config.topic, " peerConnection.connectionState: ", config.peer.peerConnection.connectionState); if (config.peer.peerConnection.connectionState === "failed") { if (publicized.isPeerFailed() || publicized.isDestroyed()) return; config.state = peerStates.FAILED; app.publicCallbacks.onDebug({ type: 'CALL_STATUS', message: `Stream Peer (${config.topic}) has failed!`, }); app.publicCallbacks.onError(errorList.PEER_FAILED); } if (config.peer.peerConnection.connectionState === 'connected') { config.state = peerStates.CONNECTED; onPeerConnect && onPeerConnect() onPeerConnect = null; } }, onIceConnectionStateChange() { if (!config.peer || publicized.isDestroyed()) { return; //avoid log errors } console.log("[SDK][oniceconnectionstatechange] ", "peer: ", config.topic, " peerConnection.connectionState: ", config.peer.peerConnection.iceConnectionState); if (config.peer.peerConnection.iceConnectionState === 'disconnected') { config.state = peerStates.DISCONNECTED; app.publicCallbacks.onDebug({ type: 'CALL_STATUS', message: `Stream Peer (${config.topic}) is disconnected!`, errorInfo: config.peer }); } if (config.peer.peerConnection.iceConnectionState === "failed") { if (publicized.isPeerFailed() || publicized.isDestroyed()) return; config.state = peerStates.FAILED; app.publicCallbacks.onDebug({ type: 'CALL_STATUS', message: `Stream Peer (${config.topic}) ice has failed!` }); app.publicCallbacks.onError(errorList.PEER_FAILED); } if (config.peer.peerConnection.iceConnectionState === "connected") { config.state = peerStates.CONNECTED; onPeerConnect && onPeerConnect() onPeerConnect = null; app.publicCallbacks.onDebug({ type: 'CALL_STATUS', message: `Stream Peer (${config.topic}) ice has connected!`, }); } }, sendSDPOfferRequestMessage(sdpOffer, retries) { app.messenger.sendCallMessage({ id: 'SEND_SDP_OFFER', sdpOffer: sdpOffer, useComedia: true, useSrtp: false, topic: config.topic, mediaType: 2, chatId: app.authSessionInfo.callId }, null, 4000, function (result) { if (result.done === 'FALSE' && retries > 0) { retries -= 1; publicized.sendSDPOfferRequestMessage(sdpOffer); } }); }, stopTopicOnServer() { return new Promise(resolve => { app.messenger.sendCallMessage({ id: 'STOP', topic: config.topic, chatId: app.authSessionInfo.callId }, function (result) { if (result.done === 'TRUE' || result.done === 'SKIP') { // manager.reconnectTopic(); resolve() } else { console.warn("[SDK] SDK tried to stop the topic but failed.", config.topic) } }, {}); }) }, async removeTopic() { let manager = this; app.messenger.sendCallMessage({ id: 'CLOSE', }, null, {}); if (config.peer) { config.peer.dispose(); config.peer = null; config.state = peerStates.DISCONNECTED; } }, updateStream(stream) { config.dataStream = stream; config.peer.updateStream(stream); }, stopStatusPrint() { config.statusEventsInterval && clearInterval(config.statusEventsInterval); }, isDestroyed() { return config.isDestroyed; }, async destroy() { config.isDestroyed = true; // publicized.removeStreamHTML(); await publicized.removeTopic(); } } return publicized } export {CallTopicManager}