Last active
May 21, 2024 20:52
-
-
Save tavoohoh/77c8f4382f3f48d8c1163391dd7df257 to your computer and use it in GitHub Desktop.
Zoom video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public SessionController = { | |
join: async () => { | |
const instance = Store.instance; | |
instance.loaders = { | |
...instance.loaders, | |
join: true, | |
}; | |
const client = Client.get(); | |
await client.init('en-US', 'Global', { | |
patchJsMedia: true, | |
enforceMultipleVideos: true, | |
enforceVirtualBackground: false, | |
}); | |
await client.join( | |
instance.session.topic, | |
instance.session.token, | |
instance.session.username, | |
instance.session.password, | |
); | |
Stream.create(); | |
Participants.create(); | |
instance.sessionJoined = true; | |
instance.clientUserId = client.getCurrentUserInfo().userId; | |
await instance.AudioController.startAudio(); | |
await instance.VideoController.startVideo(); | |
instance.loaders = { | |
...instance.loaders, | |
join: false, | |
}; | |
instance.SessionController.listeners(); | |
}, | |
leave: async () => { | |
const instance = Store.instance; | |
await instance.AudioController.disableAudio(); | |
await instance.VideoController.stopVideo(); | |
instance.VideoController.destroyVideoWithCanvas(); | |
await Client.destroy(); | |
instance.sessionJoined = false; | |
instance.showControls = false; | |
}, | |
listeners: () => { | |
const instance = Store.instance; | |
const client = Client.get(); | |
client.on('video-active-change', (payload) => { | |
console.log('video-active-change', payload); | |
}); | |
client.on('passively-stop-share', () => { | |
instance.toggleScreen(); | |
}); | |
client.on('user-added', (payload) => | |
instance.SessionController.updateParticipants('user-added', payload), | |
); | |
client.on('user-removed', (payload) => | |
instance.SessionController.updateParticipants('user-removed', payload), | |
); | |
client.on('peer-video-state-change', (payload) => { | |
instance.SessionController.updateParticipants('peer-video-state-change', payload); | |
instance.emit('set-video-layout'); | |
}); | |
client.on('connection-change', (payload) => { | |
console.debug('Connection change', payload); | |
if (payload.state === 'Closed') { | |
console.info( | |
'Session ended by the host or the SDK kicked the user', | |
payload.reason, | |
); | |
} else if (payload.state === 'Reconnecting') { | |
console.info( | |
'The client side has lost connection with the server. Reconnecting...', | |
); | |
} else if (payload.state === 'Connected') { | |
console.info( | |
'The client side has reconnected with the server. Reconnected!', | |
); | |
} else if (payload.state === 'Fail') { | |
console.info( | |
'The client side has failed to reconnect with the server. Failed to reconnect!', | |
); | |
} | |
}); | |
} | |
} | |
public VideoController = { | |
startVideo: async () => { | |
const instance = Store.instance; | |
const stream = Stream.get(); | |
if (instance.media.camera) { | |
await stream.startVideo({ mirrored: true }); | |
} | |
instance.emit('set-video-layout'); | |
}, | |
stopVideo: async () => { | |
const instance = Store.instance; | |
const stream = Stream.get(); | |
await stream.stopVideo(); | |
instance.emit('set-video-layout'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
connectedCallback() { | |
super.connectedCallback(); | |
this.store.events('set-video-layout', async () => { | |
setTimeout(async() => { | |
await this.renderLayout(); | |
}, 10); | |
window.addEventListener('resize', this.renderLayout.bind(this)); | |
}); | |
this.store.events('toggle-screen', async () => { | |
await this.handleToggleScreen(); | |
}); | |
} | |
async renderLayout() { | |
const client = Client.get(); | |
const stream = Stream.get(); | |
const usersWithVideo = client.getAllUser(); | |
const mockVideos = localStorage.getItem('mockVideosCount'); | |
if (mockVideos) { | |
for (let i = 0; i < parseInt(mockVideos); i++) { | |
usersWithVideo[0]['isMock'] = true; | |
usersWithVideo.push(usersWithVideo[0]); | |
} | |
} | |
this.videoPlayerContainer.value.innerHTML = ''; | |
this.videoPlayerContainer.value.className = this.getVideoLayoutClassName(usersWithVideo.length); | |
const videoHeight = this.getVideoHeight(usersWithVideo.length); | |
const videoWidth = this.getVideoWidth(usersWithVideo.length); | |
for (const user of usersWithVideo) { | |
if (user.bVideoOn) { | |
const video = await stream.attachVideo( | |
user.userId, | |
2 | |
) as VideoPlayer; | |
video.className = 'video-player'; | |
video.style['height'] = videoHeight; | |
video.style['width'] = videoWidth; | |
video.style['overflow'] = 'hidden'; | |
video.style['background'] = 'black'; | |
video.style['aspect-ratio'] = '1'; | |
const mask = document.createElement('div'); | |
mask.className = 'video-player-mask'; | |
mask.innerHTML = ` | |
<div class="video-player-name">${user.displayName}</div> | |
`; | |
mask.appendChild(video as VideoPlayer); | |
this.videoPlayerContainer.value.appendChild(mask); | |
} else { | |
const placeholder = document.createElement('div'); | |
placeholder.className = 'video-player video-placeholder'; | |
const digit = user.userId.toString()[user.userId.toString().length - 1]; | |
const color = COLORS[digit]; | |
placeholder.innerHTML = ` | |
<div class="video-placeholder-name" style="background-color: ${color}"> | |
${user.displayName[0].toUpperCase()} | |
</div> | |
`; | |
this.videoPlayerContainer.value.appendChild(placeholder); | |
} | |
} | |
} | |
private getVideoLayoutClassName(count: number): string { | |
return `layout layout-${count}` | |
} | |
private getVideoHeight(layout: number): string { | |
switch (layout) { | |
case 1: | |
case 2: | |
return `${this.meetLayoutContent.value.clientHeight}px`; | |
default: | |
return `${(this.meetLayoutContent.value.clientHeight / 2) - GAP}px`; | |
} | |
} | |
private getVideoWidth(layout: number): string { | |
switch (layout) { | |
case 1: | |
return `${this.videoPlayerContainer.value.clientWidth}px`; | |
case 2: | |
case 3: | |
case 4: | |
return `${(this.videoPlayerContainer.value.clientWidth / 2) - GAP}px`; | |
case 5: | |
case 6: | |
return `${(this.videoPlayerContainer.value.clientWidth / 3) - GAP}px`; | |
case 7: | |
case 8: | |
default: | |
return `${(this.videoPlayerContainer.value.clientWidth / 4) - GAP}px`; | |
} | |
} | |
private async stopScreenShare() { | |
const stream = Stream.get(); | |
try { | |
await stream.stopShareScreen(); | |
this.screenContainer.value.innerHTML = ''; | |
this.videoPlayerContainer.value.style['grid-column'] = '1 / 3'; | |
this.store.loaders = { | |
...this.store.loaders, | |
screen: false, | |
} | |
this.store.control = { | |
...this.store.control, | |
screen: false, | |
} | |
} catch (error) { | |
console.error('Unable to stop screen share', error); | |
} | |
await this.renderLayout(); | |
} | |
private async handleToggleScreen() { | |
if (this.store.loaders.screen) { | |
return; | |
} | |
this.store.loaders = { | |
...this.store.loaders, | |
screen: true, | |
} | |
const stream = Stream.get(); | |
if (this.store.control.screen) { | |
return await this.stopScreenShare(); | |
} | |
this.videoPlayerContainer.value.style['grid-column'] = '2'; | |
await this.renderLayout(); | |
const startShare = async (tag: 'video' | 'canvas') => { | |
const element = document.createElement(tag); | |
element.id = 'screen-share'; | |
element.style.width = '100%'; | |
element.style.height = 'auto'; | |
this.screenContainer.value.appendChild(element); | |
console.debug('element was appended'); | |
await stream.startShareScreen(element).catch((error) => { | |
console.error('Error while starting screen share', error); | |
this.stopScreenShare(); | |
}); | |
}; | |
const tag = stream.isStartShareScreenWithVideoElement() ? 'video' : 'canvas'; | |
console.debug('start will be called'); | |
await startShare(tag); | |
this.store.control = { | |
...this.store.control, | |
screen: true, | |
} | |
this.store.loaders = { | |
...this.store.loaders, | |
screen: false, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment