У меня есть требование интегрировать jitsi-meet с reactjs web в мой проект. Я просмотрел следующие документы
https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-iframe
https://dev.to/fifo/video-conferencing-app-using-react-and-jitsi-32oh
https://github.com/jitsi/lib-jitsi-meet/tree/master/doc/example
По третьей ссылке я смог воспроизвести его и работал нормально.
Но мне нужно сделать то же самое reactjs, для которого я установил два пакета из npm
- npm i lib-jitsi-react
- npm i strophe js -plugins
Тем не менее, это не сработало, было выдача ошибок, связанных с stophe js (Отсутствуют плагины strophe (требуются плагины disco и caps)!).
если кто-то реализовал jitsi, встречайтесь в reactjs, пожалуйста, расскажите мне, как я могу этого добиться.
И я использовал внешний API iframe, он также работает нормально, но мне нужно больше контроля над пользовательским интерфейсом.
Ниже мой компонент реакции:
/* global $, JitsiMeetJS */
import react from "react";
import { JitsiMeetJS } from "lib-jitsi-meet";
import $ from "jquery";
export const options = {
hosts: {
domain: "beta.meet.jit.si",
muc: "conference.beta.meet.jit.si", // FIXME: use XEP-0030
},
bosh: "https://beta.meet.jit.si/http-bind", // FIXME: use xep-0156 for that
// The name of client node advertised in XEP-0115 'c' stanza
clientNode: "http://jitsi.org/jitsimeet",
};
const confOptions = {
openBridgeChannel: true,
};
let connection = null;
let isJoined = false;
let room = null;
let localTracks = [];
const remoteTracks = {};
/**
* Handles local tracks.
* @param tracks Array with JitsiTrack objects
*/
function onLocalTracks(tracks) {
localTracks = tracks;
for (let i = 0; i < localTracks.length; i++) {
localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
(audioLevel) => console.log(`Audio Level local: ${audioLevel}`)
);
localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
() => console.log("local track muted")
);
localTracks[i].addEventListener(
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
() => console.log("local track stoped")
);
localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
(deviceId) =>
console.log(`track audio output device was changed to ${deviceId}`)
);
if (localTracks[i].getType() === "video") {
$("body").append(`<video autoplay='1' id='localVideo${i}' />`);
localTracks[i].attach($(`#localVideo${i}`)[0]);
} else {
$("body").append(
`<audio autoplay='1' muted='true' id='localAudio${i}' />`
);
localTracks[i].attach($(`#localAudio${i}`)[0]);
}
if (isJoined) {
room.addTrack(localTracks[i]);
}
}
}
/**
* Handles remote tracks
* @param track JitsiTrack object
*/
function onRemoteTrack(track) {
if (track.isLocal()) {
return;
}
const participant = track.getParticipantId();
if (!remoteTracks[participant]) {
remoteTracks[participant] = [];
}
const idx = remoteTracks[participant].push(track);
track.addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
(audioLevel) => console.log(`Audio Level remote: ${audioLevel}`)
);
track.addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED, () =>
console.log("remote track muted")
);
track.addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED, () =>
console.log("remote track stoped")
);
track.addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
(deviceId) =>
console.log(`track audio output device was changed to ${deviceId}`)
);
const id = participant + track.getType() + idx;
if (track.getType() === "video") {
$("body").append(`<video autoplay='1' id='${participant}video${idx}' />`);
} else {
$("body").append(`<audio autoplay='1' id='${participant}audio${idx}' />`);
}
track.attach($(`#${id}`)[0]);
}
/**
* That function is executed when the conference is joined
*/
function onConferenceJoined() {
console.log("conference joined!");
isJoined = true;
for (let i = 0; i < localTracks.length; i++) {
room.addTrack(localTracks[i]);
}
}
/**
*
* @param id
*/
function onUserLeft(id) {
console.log("user left");
if (!remoteTracks[id]) {
return;
}
const tracks = remoteTracks[id];
for (let i = 0; i < tracks.length; i++) {
tracks[i].detach($(`#${id}${tracks[i].getType()}`));
}
}
/**
* That function is called when connection is established successfully
*/
function onConnectionSuccess() {
room = connection.initJitsiConference("s123", confOptions);
room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, (track) => {
console.log(`track removed!!!${track}`);
});
room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
room.on(JitsiMeetJS.events.conference.USER_JOINED, (id) => {
console.log("user join");
remoteTracks[id] = [];
});
room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
room.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, (track) => {
console.log(`${track.getType()} - ${track.isMuted()}`);
});
room.on(
JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED,
(userID, displayName) => console.log(`${userID} - ${displayName}`)
);
room.on(
JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED,
(userID, audioLevel) => console.log(`${userID} - ${audioLevel}`)
);
room.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, () =>
console.log(`${room.getPhoneNumber()} - ${room.getPhonePin()}`)
);
room.join();
}
/**
* This function is called when the connection fail.
*/
function onConnectionFailed() {
console.error("Connection Failed!");
}
/**
* This function is called when the connection fail.
*/
function onDeviceListChanged(devices) {
console.info("current devices", devices);
}
/**
* This function is called when we disconnect.
*/
function disconnect() {
console.log("disconnect!");
connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
onConnectionSuccess
);
connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_FAILED,
onConnectionFailed
);
connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
disconnect
);
}
/**
*
*/
function unload() {
for (let i = 0; i < localTracks.length; i++) {
localTracks[i].dispose();
}
room.leave();
connection.disconnect();
}
let isVideo = true;
/**
*
*/
export function switchVideo() {
// eslint-disable-line no-unused-vars
isVideo = !isVideo;
if (localTracks[1]) {
localTracks[1].dispose();
localTracks.pop();
}
JitsiMeetJS.createLocalTracks({
devices: [isVideo ? "video" : "desktop"],
})
.then((tracks) => {
localTracks.push(tracks[0]);
localTracks[1].addEventListener(
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
() => console.log("local track muted")
);
localTracks[1].addEventListener(
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
() => console.log("local track stoped")
);
localTracks[1].attach($("#localVideo1")[0]);
room.addTrack(localTracks[1]);
})
.catch((error) => console.log(error));
}
/**
*
* @param selected
*/
function changeAudioOutput(selected) {
// eslint-disable-line no-unused-vars
JitsiMeetJS.mediaDevices.setAudioOutputDevice(selected.value);
}
$(window).bind("beforeunload", unload);
$(window).bind("unload", unload);
// JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
const initOptions = {
disableAudioLevels: true,
};
window.JitsiMeetJS.init(initOptions);
connection = new window.JitsiMeetJS.JitsiConnection(null, null, options);
connection.addEventListener(
JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
onConnectionSuccess
);
connection.addEventListener(
JitsiMeetJS.events.connection.CONNECTION_FAILED,
onConnectionFailed
);
connection.addEventListener(
JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
disconnect
);
JitsiMeetJS.mediaDevices.addEventListener(
JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED,
onDeviceListChanged
);
connection.connect();
JitsiMeetJS.createLocalTracks({ devices: ["audio", "video"] })
.then(onLocalTracks)
.catch((error) => {
throw error;
});
if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable("output")) {
JitsiMeetJS.mediaDevices.enumerateDevices((devices) => {
const audioOutputDevices = devices.filter((d) => d.kind === "audiooutput");
if (audioOutputDevices.length > 1) {
$("#audioOutputSelect").html(
audioOutputDevices
.map((d) => `<option value="${d.deviceId}">${d.label}</option>`)
.join("\n")
);
$("#audioOutputSelectWrapper").show();
}
});
}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/strophe.js/1.2.16/strophe.min.js"></script>
<script src="strophe.disco.min.js?v=1"></script>
<script src="lib-jitsi-meet.min.js"></script>
<script src="jitsi.js"></script>
</head>
<body>
<a href="#" onclick="unload()">Unload</a>
<a href="#" onclick="switchVideo()">switchVideo</a>
<div id="audioOutputSelectWrapper" style="display: none;">
Change audio output device
<select
id="audioOutputSelect"
onchange="changeAudioOutput(this)"
></select>
</div>
<!-- <video id="localVideo" autoplay="true"></video> -->
<!--<audio id="localAudio" autoplay="true" muted="true"></audio>-->
</body>
</html>
© 2020 GitHub, Inc.
Заранее спасибо.