Skip to content

Commit

Permalink
Merge pull request #6 from zoom/revert-5-revert-4-1.1.3
Browse files Browse the repository at this point in the history
Redo "update 1.1.3"
  • Loading branch information
mayk-zoom authored Jul 15, 2021
2 parents 31800d8 + f476e27 commit 30a9fcf
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 126 deletions.
4 changes: 2 additions & 2 deletions purejs-demo/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "http://json.schemastore.org/coffeelint",
"name": "videosdk-demo-purejs",
"version": "1.1.0",
"version": "1.1.3",
"description": "Zoom Web Video SDK Pure JS Demo",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -51,6 +51,6 @@
"webpack-dev-server": "3.11.2"
},
"dependencies": {
"@zoom/videosdk": "1.1.0"
"@zoom/videosdk": "1.1.3"
}
}
6 changes: 3 additions & 3 deletions react-demo/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "react-video-sdk-demo",
"version": "1.1.0",
"version": "1.1.3",
"private": true,
"dependencies": {
"@ant-design/icons": "^4.6.2",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.8.3",
"@zoom/videosdk": "^1.1.3",
"antd": "^4.14.1",
"classnames": "^2.2.6",
"crypto-js": "^4.0.0",
Expand All @@ -18,8 +19,7 @@
"react-dom": "17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.2",
"web-vitals": "1.1.1",
"@zoom/videosdk": "1.1.0"
"web-vitals": "1.1.1"
},
"scripts": {
"start": "react-app-rewired start",
Expand Down
3 changes: 2 additions & 1 deletion react-demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ function App(props: AppProps) {
const [mediaStream, setMediaStream] = useState<MediaStream | null>(null);
const [chatClient, setChatClient] = useState<ChatClient | null>(null);
const zmClient = useContext(ZoomContext);

useEffect(() => {
const init = async () => {
await zmClient.init("en-US", `${window.location.origin}/lib`);
await zmClient.init("en-US", `${window.location.origin}/lib`, 'zoom.us');
try {
setLoadingText("Joining the session...");
await zmClient.join(topic, signature, name, password);
Expand Down
2 changes: 1 addition & 1 deletion react-demo/src/feature/preview/preview.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
border: 1px solid rgba(0, 0, 0, 1);
}

.video-operations-preview button{
.video-operations-preview div {
background-color: black !important
}
.join-button {
Expand Down
249 changes: 161 additions & 88 deletions react-demo/src/feature/preview/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,55 @@
import React, { useCallback, useContext, useEffect, useState, useRef } from 'react';
import produce from 'immer';
import ZoomVideo from "@zoom/videosdk";
import classNames from 'classnames';
import { useMount } from '../../hooks';
import './preview.scss';
import MicrophoneButton from '../video/components/microphone';
import CameraButton from '../video/components/camera';
import { message } from 'antd';
import { MediaDevice } from '../video/video-types';

// label: string;
// deviceId: string;
let prevMicFeedbackStyle = '';
let micFeedBackInteval: any = '';
let micFeedBackInteval: any = '';

let localAudio = ZoomVideo.createLocalAudioTrack();
let localVideo = ZoomVideo.createLocalVideoTrack();
let allDevices;

const mountDevices: () => Promise<{
mics: MediaDevice[];
speakers: MediaDevice[];
cameras: MediaDevice[];
}> = async () => {
allDevices = await ZoomVideo.getDevices();
const cameraDevices: Array<MediaDeviceInfo> = allDevices.filter(function (device) {
return device.kind === 'videoinput';
});
const micDevices: Array<MediaDeviceInfo> = allDevices.filter(function (device) {
return device.kind === 'audioinput';
});
const speakerDevices: Array<MediaDeviceInfo> = allDevices.filter(function (
device,
) {
return device.kind === 'audiooutput';
});
return {
mics: micDevices.map((item) => {
return { label: item.label, deviceId: item.deviceId };
}),
speakers: speakerDevices.map((item) => {
return { label: item.label, deviceId: item.deviceId };
}),
cameras: cameraDevices.map((item) => {
return { label: item.label, deviceId: item.deviceId };
}),
};
};

const localAudio = ZoomVideo.createLocalAudioTrack();
const localVideo = ZoomVideo.createLocalVideoTrack();
const AUDIO_MASK = 1,
MIC_MASK = 2,
VIDEO_MASK = 4;
MIC_MASK = 2,
VIDEO_MASK = 4;

let PREVIEW_VIDEO: any;

Expand All @@ -24,132 +58,171 @@ const updateMicFeedbackStyle = () => {
let newMicFeedbackStyle = '';

if (newVolumeIntensity === 0) {
newMicFeedbackStyle = '';
newMicFeedbackStyle = '';
} else if (newVolumeIntensity <= 0.05) {
newMicFeedbackStyle = 'mic-feedback__very-low';
newMicFeedbackStyle = 'mic-feedback__very-low';
} else if (newVolumeIntensity <= 0.1) {
newMicFeedbackStyle = 'mic-feedback__low';
newMicFeedbackStyle = 'mic-feedback__low';
} else if (newVolumeIntensity <= 0.15) {
newMicFeedbackStyle = 'mic-feedback__medium';
newMicFeedbackStyle = 'mic-feedback__medium';
} else if (newVolumeIntensity <= 0.2) {
newMicFeedbackStyle = 'mic-feedback__high';
newMicFeedbackStyle = 'mic-feedback__high';
} else if (newVolumeIntensity <= 0.25) {
newMicFeedbackStyle = 'mic-feedback__very-high';
newMicFeedbackStyle = 'mic-feedback__very-high';
} else {
newMicFeedbackStyle = 'mic-feedback__max';
newMicFeedbackStyle = 'mic-feedback__max';
}
const micIcon: any = document.getElementById('auido-volume-feedback');
if (prevMicFeedbackStyle !== '' && micIcon) {
micIcon.classList.toggle(prevMicFeedbackStyle);
micIcon.classList.toggle(prevMicFeedbackStyle);
}

if (newMicFeedbackStyle !== '' && micIcon) {
micIcon.classList.toggle(newMicFeedbackStyle);
micIcon.classList.toggle(newMicFeedbackStyle);
}
console.log(newMicFeedbackStyle, newVolumeIntensity);
prevMicFeedbackStyle = newMicFeedbackStyle;
};

const encodePreviewOptions = (isJoinAudio: boolean, isMuteAudio: boolean, isStartVideo: boolean) => {
const encodePreviewOptions = (
isStartedAudio: boolean,
isMuted: boolean,
isStartedVideo: boolean,
) => {
let res = 0;
res = (res | +isStartVideo) << 1;
res = (res | +isMuteAudio) << 1;
res = (res | +isJoinAudio);
res = (res | +isStartedVideo) << 1;
res = (res | +isMuted) << 1;
res = res | +isStartedAudio;
return res;
}
};
const decodePreviewOptions = (val: number) => {
/*
LSB: audio,
MSB: video
*/
let isJoinAudio = !!((val & AUDIO_MASK) === AUDIO_MASK);
let isMuteAudio = !!((val & MIC_MASK) === MIC_MASK);
let isStartVideo = !!((val & VIDEO_MASK) === VIDEO_MASK);
return {isStartVideo, isMuteAudio, isJoinAudio};
}
const isStartedAudio = !!((val & AUDIO_MASK) === AUDIO_MASK);
const isMuted = !!((val & MIC_MASK) === MIC_MASK);
const isStartedVideo = !!((val & VIDEO_MASK) === VIDEO_MASK);
return { isStartedVideo, isMuted, isStartedAudio };
};

const PreviewContainer = () => {
const [isStartedAudio, setIsStartedAudio] = useState<boolean>(false);
const [isMuted, setIsMuted] = useState<boolean>(true);
const [isStartedVideo, setIsStartedVideo] = useState<boolean>(false);
const [micList, setMicList] = useState<MediaDevice[]>([]);
const [speakerList, setSpeakerList] = useState<MediaDevice[]>([]);
const [cameraList, setCameraList] = useState<MediaDevice[]>([]);
const [activeMicrophone, setActiveMicrophone] = useState('');
const [activeSpeaker, setActiveSpeaker] = useState('');
const [activeCamera, setActiveCamera] = useState('');

const [isJoinAudio, setIsJoinAudio] = useState<boolean>(false);
const [isMuteAudio, setIsMuteAudio] = useState<boolean>(false);
const [isStartVideo, setIsStartVideo] = useState<boolean>(false);
const onMicrophoneClick = () => {
if(isJoinAudio) {
if(isMuteAudio) {
localAudio.unmute().then(()=>{
micFeedBackInteval = setInterval(updateMicFeedbackStyle, 500);
setIsMuteAudio(!isMuteAudio);
});
const onCameraClick = useCallback(async () => {
if (isStartedVideo) {
await localVideo?.stop();
setIsStartedVideo(false);
} else {
await localVideo?.start(PREVIEW_VIDEO);
setIsStartedVideo(true);
}
}, [isStartedVideo]);
const onMicrophoneClick = useCallback(async () => {
if (isStartedAudio) {
if (isMuted) {
await localAudio?.unmute();
micFeedBackInteval = setInterval(updateMicFeedbackStyle, 500);
setIsMuted(false);
} else {
localAudio.mute().then(()=>{
if (micFeedBackInteval) {
clearInterval(micFeedBackInteval);
}
setIsMuteAudio(!isMuteAudio);
});
await localAudio?.mute();
if (micFeedBackInteval) {
clearInterval(micFeedBackInteval);
}
setIsMuted(true);
}
// localAudio.stop().then(()=>{
// if (micFeedBackInteval) {
// clearInterval(micFeedBackInteval);
// }
// setIsJoinAudio(!isJoinAudio);
// });
} else {
localAudio.start().then(()=>{
setIsJoinAudio(!isJoinAudio);
setIsMuteAudio(true);
});
await localAudio?.start();
setIsStartedAudio(true);
}

};

const toggleVideo = () => {
if(isStartVideo) {
localVideo.stop().then(()=>{
setIsStartVideo(!isStartVideo);
});
}, [isStartedAudio, isMuted]);
const onMicrophoneMenuClick = async (key: string) => {
const [type, deviceId] = key.split('|');
if (type === 'microphone') {
if (deviceId !== activeMicrophone) {
await localAudio.stop();
setIsMuted(true);
localAudio = ZoomVideo.createLocalAudioTrack(deviceId);
await localAudio.start();
setActiveMicrophone(deviceId);
}
} else if (type === 'leave audio') {
await localAudio.stop();
setIsStartedAudio(false);
}
else {
localVideo.start(PREVIEW_VIDEO).then(()=>{
setIsStartVideo(!isStartVideo);
});
};
const onSwitchCamera = async (key: string) => {
if (localVideo) {
if (activeCamera !== key) {
await localVideo.stop();
localVideo = ZoomVideo.createLocalVideoTrack(key);
localVideo.start(PREVIEW_VIDEO);
setActiveCamera(key);
}
}

}
};

useEffect(() => {
const encodeVal = encodePreviewOptions(isJoinAudio, isMuteAudio, isStartVideo);
console.log("preview encode val", encodeVal)
const decodeOption = decodePreviewOptions(encodeVal);
console.log("preview config", decodePreviewOptions(encodeVal));
message.info(JSON.stringify(decodeOption, null, 2));
}, [isJoinAudio, isMuteAudio, isStartVideo]);

const encodeVal = encodePreviewOptions(isStartedAudio, isMuted, isStartedVideo);
console.log('preview encode val', encodeVal);
const decodeOption = decodePreviewOptions(encodeVal);
console.log('preview config', decodePreviewOptions(encodeVal));
message.info(JSON.stringify(decodeOption, null, 2));
console.log(micList);
}, [isStartedAudio, isMuted, isStartedVideo]);

useMount(() => {
PREVIEW_VIDEO = document.getElementById('js-preview-video');
ZoomVideo.getDevices().then((res)=>{
console.log(res);
mountDevices().then((devices) => {
console.log('devicesdevicesdevicesdevices', devices);
setMicList(devices.mics);
setCameraList(devices.cameras);
// setSpeakerList(devices.speakers);
});
});

return (
<div className="js-preview-view">
<div id="js-preview-view" className="container preview__root">
<span>
<h1>Audio And Video Preview</h1>
</span>
<div className="container video-app">
<video id="js-preview-video" className="preview-video" muted={true} data-video="0"></video>
<div className="video-footer video-operations-preview">
<MicrophoneButton
isStartedAudio={isJoinAudio}
isMuted={isMuteAudio}
onMicrophoneClick={onMicrophoneClick}
/>
<CameraButton isStartedVideo={isStartVideo} onCameraClick={toggleVideo} />
</div>
</div>
<span>
<h1>Audio And Video Preview</h1>
</span>
<div className="container video-app">
<video
id="js-preview-video"
className="preview-video"
muted={true}
data-video="0"
></video>
<div className="video-footer video-operations video-operations-preview">
<MicrophoneButton
isStartedAudio={isStartedAudio}
isMuted={isMuted}
onMicrophoneClick={onMicrophoneClick}
onMicrophoneMenuClick={onMicrophoneMenuClick}
microphoneList={micList}
speakerList={speakerList}
activeMicrophone={activeMicrophone}
activeSpeaker={activeSpeaker}
/>
<CameraButton
isStartedVideo={isStartedVideo}
onCameraClick={onCameraClick}
onSwitchCamera={onSwitchCamera}
cameraList={cameraList}
activeCamera={activeCamera}
/>
</div>
</div>
</div>
</div>
);
};
Expand Down
7 changes: 4 additions & 3 deletions react-demo/src/feature/video/components/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import './avatar.scss';
import { Participant } from '../../../index-types';
interface AvatarProps {
participant: Participant;
style: { [key: string]: string };
style?: { [key: string]: string };
isActive: boolean;
className?: string;
}
const Avatar = (props: AvatarProps) => {
const { participant, style, isActive } = props;
const { participant, style, isActive, className } = props;
const { displayName, audio, muted, bVideoOn } = participant;
return (
<div
className={classNames('avatar', { 'avatar-active': isActive })}
className={classNames('avatar', { 'avatar-active': isActive }, className)}
style={{ ...style, background: bVideoOn ? 'transparent' : 'rgb(26,26,26)' }}
>
{(bVideoOn || (audio === 'computer' && muted)) && (
Expand Down
Loading

0 comments on commit 30a9fcf

Please sign in to comment.