podchat-browser
Version:
Javascript SDK to use POD's Chat Service - Browser Only
467 lines (431 loc) • 18.5 kB
JavaScript
import {CallTopicManager} from "./callTopicManager";
import {errorList} from "../errorHandler";
function CallUser(app, user) {
const config = {
callId: user.callId,
userId: user.userId,
user,
isMe: user.userId == app.store.user.get().id,
containerTag: null,
htmlElements: {},
videoTopicManager: null,
audioTopicManager: null,
};
const publicized = {
getAudioStream() {
return config.audioTopicManager.getStream();
},
getVideoStream() {
return config.videoTopicManager.getStream();
},
async switchSpeaker(deviceId) {
const audioObject = config.audioTopicManager;
if (audioObject) {
audioObject.changeAudioObject(deviceId)
}
},
isMe() {
return config.userId == app.store.user.get().id;
},
isScreenShare() {
return false;
},
user() {
return config.user;
},
getHTMLElements() {
return config.htmlElements;
},
appendAudioToCallDiv() {
if (!app.call.sharedVariables.callDivId) {
app.sdkParams.consoleLogging && console.log('No Call DIV has been declared!');
return;
}
let user = config.user,
callParentDiv = document.getElementById(app.call.sharedVariables.callDivId),
userContainer = document.getElementById("callParticipantWrapper-" + config.userId);
if (!userContainer) {
callParentDiv.appendChild(config.htmlElements.container);
userContainer = document.getElementById("callParticipantWrapper-" + config.userId)
}
if (typeof user.mute !== "undefined" && !user.mute && config.audioTopicManager) {
if (!document.getElementById("callUserAudio-" + config.user.audioTopicName)) {
userContainer.appendChild(config.htmlElements[config.user.audioTopicName]);
config.audioTopicManager.startMedia();
config.audioTopicManager.watchAudioLevel();
}
}
},
appendVideoToCallDiv() {
if (!app.call.sharedVariables.callDivId) {
app.sdkParams.consoleLogging && console.log('No Call DIV has been declared!');
return;
}
let user = config.user,
callParentDiv = document.getElementById(app.call.sharedVariables.callDivId),
userContainer = document.getElementById("callParticipantWrapper-" + config.userId);
if (!userContainer) {
callParentDiv.appendChild(config.htmlElements.container);
userContainer = document.getElementById("callParticipantWrapper-" + config.userId)
}
if (user.video && config.videoTopicManager) {
if (!document.getElementById("callUserVideo-" + config.user.videoTopicName)) {
userContainer.appendChild(config.htmlElements[config.user.videoTopicName]);
config.videoTopicManager.startMedia();
}
}
app.call.currentCall().sendCallDivs()
},
videoTopicManager() {
return config.videoTopicManager;
},
audioTopicManager() {
return config.audioTopicManager;
},
async startAudio(sendTopic) {
if (config.audioTopicManager)
return;
config.user.audioTopicName = 'Vo-' + sendTopic;
config.user.mute = false;
config.audioTopicManager = new CallTopicManager({
app,
callId: config.user.callId,
userId: config.user.userId,
topic: 'Vo-' + config.user.topicSend,
mediaType: 'audio',
direction: (config.user.userId === app.store.user.get().id ? 'send' : 'receive'),
user: config.user,
onHTMLElement(el) {
config.htmlElements[config.user.audioTopicName] = el;
publicized.appendAudioToCallDiv();
}
});
config.audioTopicManager.createTopic();
},
async startVideo(sendTopic) {
if (config.videoTopicManager)
return;
config.user.videoTopicName = 'Vi-' + sendTopic;
config.user.video = true;
config.videoTopicManager = new CallTopicManager({
app,
callId: config.user.callId,
userId: config.user.userId,
topic: 'Vi-' + config.user.topicSend,
mediaType: 'video',
direction: (config.user.userId === app.store.user.get().id ? 'send' : 'receive'),
user: config.user,
onHTMLElement(el) {
config.htmlElements[config.user.videoTopicName] = el;
publicized.appendVideoToCallDiv();
}
});
config.videoTopicManager.createTopic();
},
async reconnectTopic(media) {
if (media == 'audio') {
await config.audioTopicManager.stopTopicOnServer();
await publicized.destroyAudio()
await publicized.startAudio(config.user.topicSend);
} else {
await config.videoTopicManager.stopTopicOnServer();
await publicized.destroyVideo()
await publicized.startVideo(config.user.topicSend)
}
},
async destroy() {
if (config.videoTopicManager && config.videoTopicManager.getPeer()) {
await publicized.destroyVideo();
}
if (config.audioTopicManager && config.audioTopicManager.getPeer()) {
await publicized.destroyAudio();
}
// user.topicMetaData = {};
config.htmlElements = {};
user = null;
},
async stopAudio() {
config.user.mute = true;
await publicized.destroyAudio();
},
async destroyAudio() {
if (!config.audioTopicManager)
return;
if(config.isMe) {
await app.call.deviceManager.mediaStreams.stopAudioInput();
}
await config.audioTopicManager.destroy();
delete config.htmlElements[config.user.audioTopicName];
config.audioTopicManager = null;
},
changeAudioStream(deviceId, callback) {
const conf = {deviceId: {exact: deviceId}},
deviceManager = app.call.deviceManager;
if(deviceManager.mediaStreams.getAudioInput()) {
deviceManager.mediaStreams.stopAudioInput();
// setTimeout(()=> {
deviceManager.grantUserMediaDevicesPermissions({
audio: conf,
}, (result) => {
if (!result.hasError) {
try {
config.audioTopicManager.updateStream(deviceManager.mediaStreams.getAudioInput())
callback && callback();
} catch(error) {
app.call.currentCall().raiseCallError({code: errorList.CHANGE_MEDIA_DEVICE_FAILED.code, message: error.message}, null, true)
publicized.stopAudio();
}
} else {
app.call.currentCall().raiseCallError({code: result.errorCode, message: result.errorMessage}, null, true)
publicized.stopAudio();
}
});
} else {
throw new Error('[SDK] Microphone is not active')
}
},
changeVideoStream(deviceId, callback) {
const conf = {deviceId: {exact: deviceId}},
deviceManager = app.call.deviceManager;
if(deviceManager.mediaStreams.getVideoInput()) {
deviceManager.mediaStreams.stopVideoInput();
// setTimeout(()=> {
const video = Object.assign(conf, {width: 320, framerate: 10})
app.call.deviceManager.grantUserMediaDevicesPermissions({
video: video,
}, (result) => {
if (!result.hasError) {
let user = app.call.currentCall().users().get(app.store.user.get().id);
try {
config.videoTopicManager.updateStream(app.call.deviceManager.mediaStreams.getVideoInput());
callback && callback();
} catch(error) {
app.call.currentCall().raiseCallError({code: errorList.CHANGE_MEDIA_DEVICE_FAILED.code, message: error.message}, null, true)
publicized.stopVideo();
setTimeout(function () {
app.call.currentCall().sendCallDivs()
})
}
} else {
app.call.currentCall().raiseCallError({code: result.errorCode, message: result.errorMessage}, null, true)
app.call.currentCall().users().get(app.store.user.get().id).stopVideo();
setTimeout(function () {
app.call.currentCall().sendCallDivs();
})
}
});
} else {
throw new Error('[SDK] Webcam is not active')
}
},
async stopVideo() {
config.user.video = false;
await publicized.destroyVideo();
},
async destroyVideo() {
if (!config.videoTopicManager)
return;
if(config.isMe)
app.call.deviceManager.mediaStreams.stopVideoInput();
await config.videoTopicManager.destroy();
delete config.htmlElements[config.user.videoTopicName];
config.videoTopicManager = null;
}
}
function setup(participant) {
config.user = participant;
if (config.isMe) {
config.user.direction = 'send';
} else {
config.user.direction = 'receive';
}
config.user.videoTopicName = 'Vi-' + config.user.topicSend;
config.user.audioTopicName = 'Vo-' + config.user.topicSend;
// config.user.audioStopManager = new DevicePauseStopManager({
// callId: config.callId,
// userId: config.user.userId,
// mediaType: 'audio',
// timeout: app.sdkParams.callOptions?.streamCloseTimeout || 10000
// });
// if (config.user.mute) {
// config.user.audioStopManager.pauseStream();
// config.user.audioStopManager.stopStream();
// }
// config.user.videoStopManager = new DevicePauseStopManager({
// callId: config.callId,
// userId: config.user.userId,
// mediaType: 'video',
// timeout: app.sdkParams.callOptions?.streamCloseTimeout || 10000
// });
// if (!config.user.video) {
// config.user.videoStopManager.pauseStream();
// config.user.videoStopManager.stopStream();
// }
// publicized.appendUserToCallDiv(generateContainerElement())
generateContainerElement();
if (config.user.video)
publicized.startVideo(config.user.topicSend);
if (!config.user.mute)
publicized.startAudio(config.user.topicSend);
}
function generateContainerElement() {
if (!config.htmlElements.container) {
config.htmlElements.container = document.createElement('div');
let el = config.htmlElements.container;
el.setAttribute('id', 'callParticipantWrapper-' + config.userId);
el.classList.add('participant');
el.classList.add('wrapper');
el.classList.add('user-' + config.userId);
el.classList.add((config.isMe ? 'local' : 'remote'));
}
return config.htmlElements;
}
setup(user);
return publicized;
}
function CallScreenShare(app, user) {
const config = {
callId: user.callId,
userId: user.userId,
isMe: user.userId == app.store.user.get().id,
user,
type: "screenShare",
containerTag: null,
htmlElements: {},
videoTopicManager: null,
};
const publicized = {
getVideoStream() {
return config.videoTopicManager.getStream();
},
isMe() {
return false;
},
isScreenShare() {
return true;
},
user() {
return config.user;
},
getHTMLElements() {
return config.htmlElements;
},
appendVideoToCallDiv() {
if (!app.call.sharedVariables.callDivId) {
app.sdkParams.consoleLogging && console.log('No Call DIV has been declared!');
return;
}
let user = config.user,
callParentDiv = document.getElementById(app.call.sharedVariables.callDivId),
userContainer = document.getElementById("callParticipantWrapper-" + config.userId);
if (!userContainer) {
callParentDiv.appendChild(config.htmlElements.container);
userContainer = document.getElementById("callParticipantWrapper-" + config.userId)
}
if (user.video && config.videoTopicManager) {
if (!document.getElementById("callUserVideo-" + config.user.videoTopicName)) {
userContainer.appendChild(config.htmlElements[config.user.videoTopicName]);
config.videoTopicManager.startMedia();
}
}
// if(currentCall().screenShareInfo.iAmOwner())
config.videoTopicManager?.restartMediaOnKeyFrame("screenShare", [1000, 4000]);
// else {
// config.videoTopicManager?.restartMediaOnKeyFrame("screenShare", [1000, 3000, 6000]);
// }
app.call.currentCall().sendCallDivs()
},
videoTopicManager() {
return config.videoTopicManager;
},
audioTopicManager() {
return config.audioTopicManager;
},
audioStopManager() {
return config.user.audioStopManager
},
startAudio(sendTopic) {
return;
},
startVideo(sendTopic) {
config.user.videoTopicName = sendTopic;
config.user.video = true;
config.videoTopicManager = new CallTopicManager({
app,
callId: config.user.callId,
userId: config.user.userId,
topic: config.user.videoTopicName,
mediaType: 'video',
direction: (app.callsManager.get(config.callId).screenShareInfo.iAmOwner() ? 'send' : 'receive'),
user: config.user,
isScreenShare: true,
onHTMLElement(el) {
config.htmlElements[config.user.videoTopicName] = el;
publicized.appendVideoToCallDiv();
}
});
// publicized.appendUserToCallDiv(generateVideoElement());
config.videoTopicManager.createTopic();
},
async reconnectTopic(media) {
await config.videoTopicManager.stopTopicOnServer();
await publicized.destroyVideo()
await publicized.startVideo(config.user.topic)
},
async destroy() {
if (config.videoTopicManager && config.videoTopicManager.getPeer()) {
await config.videoTopicManager.destroy();
}
// user.topicMetaData = {};
config.htmlElements = {};
user = null;
},
destroyAudio() {
return new Promise(resolve => {
resolve()
})
},
async destroyVideo() {
await config.videoTopicManager.destroy();
delete config.htmlElements[config.user.videoTopicName];
config.videoTopicManager = null;
},
}
function setup(user) {
let iAmOwner = app.callsManager.get(config.callId).screenShareInfo.iAmOwner();
let obj = {
video: true,
callId: user.callId,
userId: user.userId,
topic: user.topicSend
};
obj.direction = iAmOwner ? 'send' : 'receive';
obj.videoTopicName = config.topic;
config.user = obj;
// publicized.appendUserToCallDiv(generateContainerElement())
generateContainerElement();
if (config.user.video)
publicized.startVideo(obj.topic);
}
function generateContainerElement() {
if (!config.htmlElements.container) {
config.htmlElements.container = document.createElement('div');
let el = config.htmlElements.container;
el.setAttribute('id', 'callParticipantWrapper-' + config.userId);
el.classList.add('participant');
el.classList.add('wrapper');
el.classList.add('user-' + config.userId);
el.classList.add((config.isMe ? 'local' : 'remote'));
}
return config.htmlElements;
}
function generateVideoElement() {
if (config.user.video && !config.htmlElements[config.user.videoTopicName]) {
let el = config.videoTopicManager.getHtmlElement();
config.htmlElements[config.user.videoTopicName] = el;
}
}
setup(user);
return publicized;
}
export {CallUser, CallScreenShare}