How to Integrate Jitsi meet in React 2021 (External API, IFrame API)
Jitsi is a free and open-source multiplatform voice (VoIP), video conferencing for the web platform.
In this tutorial, I am gonna tell you how to integrate Jitsi Meet Iframe API in React. Also, how you can use your custom buttons for controlling Jitsi events.
Demo:- https://ultimateakash.github.io/JitsiReact
Documentation:- https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-iframe
#Step 1
To enable the Jitsi Meet API in our react application we need to add Jitsi Meet Javascript library in index.html file.
For Self Hosted Jitsi:
<script src='https://<your-domain>/external_api.js'></script>
For meet.jit.si:
<script src='https://meet.jit.si/external_api.js'></script>
How to Install Jitsi Meet on Ubuntu - Self-Hosted
#Step 2
We need a component for creating the Jitsi Meet API object.
Inside the component, we also need to implement componentDidMount life cycle hook for iframe reference.
jitsi.component.jsx
import React, { Component } from 'react';
class JitsiComponent extends Component {
constructor(props) {
super(props);
this.state = {}; // State Data
}
startMeet = () => {
// Intialize Jitsi Object
}
componentDidMount() {
if (window.JitsiMeetExternalAPI) {
this.startMeet();
} else {
alert('JitsiMeetExternalAPI not loaded');
}
}
}
export default JitsiComponent;
#Step 3
Initialize jitsi object.
import React, { Component } from 'react';
class JitsiComponent extends Component {
domain = 'meet.jit.si';
api = {};
constructor(props) {
super(props);
this.state = {
room: 'bwb-bfqi-vmg',
user: {
name: 'Akash Verma'
},
isAudioMuted: false,
isVideoMuted: false
}
}
startMeet = () => {
const options = {
roomName: this.state.room,
width: '100%',
height: 500,
configOverwrite: { prejoinPageEnabled: false },
interfaceConfigOverwrite: {
// overwrite interface properties
},
parentNode: document.querySelector('#jitsi-iframe'),
userInfo: {
displayName: this.state.user.name
}
}
this.api = new window.JitsiMeetExternalAPI(this.domain, options);
this.api.addEventListeners({
readyToClose: this.handleClose,
participantLeft: this.handleParticipantLeft,
participantJoined: this.handleParticipantJoined,
videoConferenceJoined: this.handleVideoConferenceJoined,
videoConferenceLeft: this.handleVideoConferenceLeft,
audioMuteStatusChanged: this.handleMuteStatus,
videoMuteStatusChanged: this.handleVideoStatus
});
}
handleClose = () => {
console.log("handleClose");
}
handleParticipantLeft = async (participant) => {
console.log("handleParticipantLeft", participant); // { id: "2baa184e" }
const data = await this.getParticipants();
}
handleParticipantJoined = async (participant) => {
console.log("handleParticipantJoined", participant); // { id: "2baa184e", displayName: "Shanu Verma", formattedDisplayName: "Shanu Verma" }
const data = await this.getParticipants();
}
handleVideoConferenceJoined = async (participant) => {
console.log("handleVideoConferenceJoined", participant); // { roomName: "bwb-bfqi-vmh", id: "8c35a951", displayName: "Akash Verma", formattedDisplayName: "Akash Verma (me)"}
const data = await this.getParticipants();
}
handleVideoConferenceLeft = () => {
console.log("handleVideoConferenceLeft");
return this.props.history.push('/thank-you');
}
handleMuteStatus = (audio) => {
console.log("handleMuteStatus", audio); // { muted: true }
}
handleVideoStatus = (video) => {
console.log("handleVideoStatus", video); // { muted: true }
}
getParticipants() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(this.api.getParticipantsInfo()); // get all participants
}, 500)
});
}
// custom events
executeCommand(command) {
this.api.executeCommand(command);;
if(command == 'hangup') {
return this.props.history.push('/thank-you');
}
if(command == 'toggleAudio') {
this.setState({ isAudioMuted: !this.state.isAudioMuted });
}
if(command == 'toggleVideo') {
this.setState({ isVideoMuted: !this.state.isVideoMuted });
}
}
componentDidMount() {
if (window.JitsiMeetExternalAPI) {
this.startMeet();
} else {
alert('JitsiMeetExternalAPI not loaded');
}
}
render() {
const { isAudioMuted, isVideoMuted } = this.state;
return (
<>
<header className="nav-bar">
<p className="item-left heading">Jitsi React</p>
</header>
<div id="jitsi-iframe"></div>
<div class="item-center">
<span>Custom Controls</span>
</div>
<div class="item-center">
<span> </span>
<i onClick={ () => this.executeCommand('toggleAudio') } className={`fas fa-2x grey-color ${isAudioMuted ? 'fa-microphone-slash' : 'fa-microphone'}`} aria-hidden="true" title="Mute / Unmute"></i>
<i onClick={ () => this.executeCommand('hangup') } className="fas fa-phone-slash fa-2x red-color" aria-hidden="true" title="Leave"></i>
<i onClick={ () => this.executeCommand('toggleVideo') } className={`fas fa-2x grey-color ${isVideoMuted ? 'fa-video-slash' : 'fa-video'}`} aria-hidden="true" title="Start / Stop camera"></i>
<i onClick={ () => this.executeCommand('toggleShareScreen') } className="fas fa-film fa-2x grey-color" aria-hidden="true" title="Share your screen"></i>
</div>
</>
);
}
}
export default JitsiComponent;
#Step 4
Finally, we need to start react development server.
npm start
then open http://localhost:3000
Leave Your Comment