Tạo ứng dụng video chat Full Custom JavaScript với VideoSDK

We have seen a major increase in the usage of virtual meetings in the past year and the existing platforms cannot cater to everyone’s custom needs. Also, building a custom feature-rich solution for your need from scratch is not a great option as you need to manage a lot of tasks, this is where VideoSDK.live comes to the rescue.

With video SDK you can build a customized Video Chat App with all features your need. We will see in this guide, how you can build a video chat app using Javascript.

Prerequisites

  1. Node.js v12+
  2. NPM v6+ (comes pre-installed with newer Node versions)
  3. You should have a video SDK account to generate tokens. Visit the video SDK dashboard to generate a token.

Project Structure

root 
├── index.html
├── assets
│    ├── css
│    │    ├── index.css
│    ├── js
│         ├── index.js

Step 1: Adding VideoSDK

Update the index.html file with the <script ... /> as shown to add the VideoSDK Javascript SDK to your project.

<html>
	  <head>
	    ....
	  </head>
	  <body>
	    .....
	    <script src="https://sdk.videosdk.live/js-sdk/0.0.20/videosdk.js"></script>
	  </body>
	</html>

If you don’t want to use <script ... /> you can use `npm` to install VideoSDK in your project.

npm install @videosdk.live/js-sdk

//or you can use yarn
yarn add @videosdk.live/js-sdk

Step 2: Creating the UI

For the interface, we will have simple Join and Create Meeting meeting buttons which will join and create a new meeting room respectively.

The meeting room will show the local participant view, remote participant view and show buttons to toggle mic, webcam, and leave the meeting.

<html>
	  <head>
	    <!--favicon-->
	    <link
	      rel="shortcut icon"
	      href="https://videosdk.live/favicon/favicon.ico"
	    />
	    <meta charset="UTF-8" />
	    <link rel="stylesheet" href="./assets/css/index.css" />
	    <!--add necessary bootstrap links here -->
	    ...
	  </head>
	  <body class="bg-secondary">
	    <!--join-screen-->
	    <div
	      id="join-screen"
	      class="flex flex-row align-items-center justify-content-center h-100" >
	      <button
	        class="btn btn-primary"
	        id="btnCreateMeeting"
	        onclick="meetingHandler(true)" >
	        New Meeting
	      </button>
	      <input
	        type="text"
	        id="txtMeetingCode"
	        placeholder="Enter Meeting Code .." />
	      <button
	        id="btnJoinMeeting"
	        onclick="meetingHandler(false)"
	        class="btn btn-primary" >
	        Join
	      </button>
	    </div>
	      
	    <!--grid-screen-->
	    <div id="grid-screen">
	      <div>
	        <input
	          type="text"
	          class="form-control navbar-brand"
	          id="lblMeetingId"
	          readonly
	        />
	        <button class="btn btn-dark" id="btnToggleMic">Unmute Mic</button>
	        <button class="btn btn-dark" id="btnToggleWebCam">Disable Webcam</button>
	        <button class="btn btn-dark" id="btnLeaveMeeting">Leave Meeting</button>
	      </div>
	      <br />
	      <div id="videoContainer"></div>
	      <div
	        style="position: absolute;
	              top: 10px;
	              right: 0px;
	              height: 50%;
	              overflow-y: scroll;" >
	        <h3>Participants List</h3>
	        <div id="participantsList"></div>
	      </div>
	    </div>
	      
	    <!--scripts-->
	    <script src="./assets/js/config.js"></script>
	    <script src="./assets/js/index.js"></script>
	    <script src="https://sdk.videosdk.live/js-sdk/0.0.20/videosdk.js"></script>
	  </body>
	</html>

You can get the complete custom CSS style from here.

We will declare all the DOM variables we will need in the index.js file.

//DOM elements
let btnCreateMeeting = document.getElementById("btnCreateMeeting");
let btnJoinMeeting = document.getElementById("btnJoinMeeting");
let videoContainer = document.getElementById("videoContainer");
let btnLeaveMeeting = document.getElementById("btnLeaveMeeting");
let btnToggleMic = document.getElementById("btnToggleMic");
let btnToggleWebCam = document.getElementById("btnToggleWebCam");

Step 3: Meeting Implementation

To start the meeting implementation, we will need the token so if you don't have one, you can generate it from here.

  1. Now update your token in the index.js file as shown to add the token in the script and add a validator.
//variables
let token = "YOUR_TOKEN_HERE";
	
//handlers
async function tokenGeneration() {
    //Update this function with a server-side token generation for Production version
    if (token != "") {
        console.log("token : ", token);
    } else {
        alert("Please Provide Your Token First");
    }
}

2. We have got the token. Now we will add the meetingHandler which will create or join to a meeting room.

//variables
	let meetingId = "";
	

	async function meetingHandler(newMeeting) {
	  let joinMeetingName = "JS-SDK";
	  
	  tokenGeneration();
	  if (newMeeting) {
	    const url = `${API_BASE_URL}/api/meetings`;
	    const options = {
	      method: "POST",
	      headers: { Authorization: token, "Content-Type": "application/json" },
	    };
	

	    const { meetingId } = await fetch(url, options)
	      .then((response) => response.json())
	      .catch((error) => alert("error", error));
	    document.getElementById("lblMeetingId").value = meetingId;
	    document.getElementById("home-screen").style.display = "none";
	    document.getElementById("grid-screen").style.display = "inline-block";
	    startMeeting(token, meetingId, joinMeetingName);
	  } else {
	    document.getElementById("lblMeetingId").value = meetingId;
	    document.getElementById("home-screen").style.display = "none";
	    document.getElementById("grid-screen").style.display = "inline-block";
	    startMeeting(token, meetingId, joinMeetingName);
	  }
}

3. Now the meetingId is either generated or updated with the value user entered. After this, startMeeting is triggered which is responsible to initialize the meeting with the required configuration and join the meeting.

function startMeeting(token, meetingId, name) {
	  // Meeting config
	  window.ZujoSDK.config(token);
	

	  // Meeting Init
	  meeting = window.ZujoSDK.initMeeting({
	    meetingId: meetingId, // required
	    name: name, // required
	    micEnabled: true, // optional, default: true
	    webcamEnabled: true, // optional, default: true
	    maxResolution: "hd", // optional, default: "hd"
	  });
	  //join meeting
	  meeting.join();
}

4. Now we will create the local participant view.

function startMeeting(token, meetingId, name) {
	  //...Meeting intializating and joining code is here
	

	  //create Local Participant
	  createParticipant(meeting.localParticipant.id);
	

	  //local participant stream-enabled event
	  meeting.localParticipant.on("stream-enabled", (stream) => {
	    setTrack(
	      stream,
	      localParticipant,
	      localParticipantAudio,
	      meeting.localParticipant.id
	    );
	  });
	

	}
	

	//createParticipant
	function createParticipant(participant) {
	

	  //create videoElem of participant
	  let participantVideo = createVideoElement(
	    participant.id,
	    participant.displayName
	  );
	

	  //create audioEle of participant
	  let participantAudio = createAudioElement(participant.id);
	

	  //append video and audio of participant to videoContainer div
	  videoContainer.appendChild(participantVideo);
	  videoContainer.appendChild(participantAudio);
	}
	

	// creating video element
	function createVideoElement(id, name) {
	  let videoFrame = document.createElement("div");
	  videoFrame.classList.add("video-frame");
	

	  //create video
	  let videoElement = document.createElement("video");
	  videoElement.classList.add("video");
	  videoElement.setAttribute("id", `v-${id}`);
	  videoElement.setAttribute("autoplay", true);
	  videoFrame.appendChild(videoElement);
	

	  //add overlay
	  let overlay = document.createElement("div");
	  overlay.classList.add("overlay");
	  overlay.innerHTML = `Name : ${name}`;
	

	  videoFrame.appendChild(overlay);
	  return videoFrame;
	}
	

	// creating audio element
	function createAudioElement(pId) {
	  let audioElement = document.createElement("audio");
	  audioElement.setAttribute("autoPlay", false);
	  audioElement.setAttribute("playsInline", "false");
	  audioElement.setAttribute("controls", "false");
	  audioElement.setAttribute("id", `a-${pId}`);
	  audioElement.style.display = "none";
	  return audioElement;
	}
	

	//set the video or audio stream in the video element
	function setTrack(stream, videoElem, audioElement, id) {
	  if (stream.kind == "video") {
	    // enablePermission(id);
	    const mediaStream = new MediaStream();
	    mediaStream.addTrack(stream.track);
	    videoElem.srcObject = mediaStream;
	    videoElem
	      .play()
	      .catch((error) =>
	        console.error("videoElem.current.play() failed", error)
	      );
	  }
	  if (stream.kind == "audio") {
	    if (id == meeting.localParticipant.id) return;
	    const mediaStream = new MediaStream();
	    mediaStream.addTrack(stream.track);
	    audioElement.srcObject = mediaStream;
	    audioElement
	      .play()
	      .catch((error) => console.error("audioElem.play() failed", error));
	  }
	}

6. At last, we will add the event listeners to the toggle buttons and leave button.

function startMeeting(token, meetingId, name) {
	  //... Meeting intialization and joining
	  //...creating local participants
	  //...remote participant listeners
	  addDomEvents();
	}
	

	function addDomEvents() {
	  btnToggleMic.addEventListener("click", () => {
	    if (btnToggleMic.innerText == "Unmute Mic") {
	      meeting.unmuteMic();
	      btnToggleMic.innerText = "Mute Mic";
	    } else {
	      meeting.muteMic();
	      btnToggleMic.innerText = "Unmute Mic";
	    }
	  });
	

	  btnToggleWebCam.addEventListener("click", () => {
	    if (btnToggleWebCam.innerText == "Disable Webcam") {
	      meeting.disableWebcam();
	      btnToggleWebCam.innerText = "Enable Webcam";
	    } else {
	      meeting.enableWebcam();
	      btnToggleWebCam.innerText = "Disable Webcam";
	    }
	  });
	

	  btnLeaveMeeting.addEventListener("click", async () => {
	    // leavemeeting
	    meeting.leave();
	    document.getElementById("join-screen").style.display = "inline-block";
	    document.getElementById("grid-screen").style.display = "none";
	  });
	}

Step4. Run and Test

To run the app you will need live-server. If you don't have it installed already you can do it using:

npm install -g live-server

Once you have the live-server installed, just run it using:

live-server

Conclusion

With this, we successfully built the video chat app using the video SDK in Javascript. If you wish to add functionalities like chat messaging, screen sharing, you can always check out our documentation. If you face any difficulty with the implementation you can check out the example on GitHub or connect with us on our discord community.

Nguồn: Here

Khôi Phạm
Khôi Phạm

Share is way to learn

SUNTECH VIỆT NAM   Đăng ký để nhận thông báo mới nhất