react-video-call
Version:
ReactVideoCall is a simple yet powerful WebRTC-based video call component for React. It uses Firebase for signaling and supports both desktop and mobile views with minimal setup.
92 lines • 6.46 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import React, { useEffect, useRef, useState } from "react";
import "./ReactVideoCall.scss";
import { WebRTCManager } from "./libs/webrtcManager";
import { Icon } from "../icons";
export const ReactVideoCall = ({ roomName, firebaseConfig, RTCConfiguration }) => {
const [webrtcManager, setWebRtcManager] = useState();
const [connectionStatus, setconnectionStatus] = useState(null);
const [selectedCamera, setSelectedCamera] = useState();
const [selectedAudio, setSelectedAudio] = useState();
const [videoDevices, setvideoDevices] = useState([]);
const [audioDevices, setaudioDevices] = useState([]);
const [isMicMuted, setisMicMuted] = useState(false);
const [isVolumeMute, setisVolumeMute] = useState(true);
const localVidRef = useRef(null);
const remortVidRef = useRef(null);
const initRTCConnection = () => __awaiter(void 0, void 0, void 0, function* () {
setconnectionStatus(null);
const manager = new WebRTCManager(firebaseConfig, localVidRef, remortVidRef, RTCConfiguration);
const { videoDevices, audioDevices } = yield manager.getDevices();
manager.onStateChange = (status) => {
setconnectionStatus(status);
};
setWebRtcManager(manager);
setvideoDevices(videoDevices);
setaudioDevices(audioDevices);
});
useEffect(() => {
if (!webrtcManager && remortVidRef && localVidRef) {
initRTCConnection();
}
}, [localVidRef, remortVidRef, webrtcManager]);
useEffect(() => {
if (webrtcManager) {
webrtcManager.selectDevice(selectedCamera, selectedAudio);
}
}, [selectedCamera, selectedAudio, webrtcManager]);
return (React.createElement("div", { className: "rv-call-container" },
React.createElement("div", { className: "device-selection", style: { display: "none" } },
React.createElement("select", { id: "camera-select", className: "block appearance-none w-full bg-black/[.05] border border-gray-300 text-gray-700 py-2 px-3 pr-8 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", value: selectedCamera, onChange: (e) => {
setSelectedCamera(e.target.value);
}, suppressHydrationWarning: true },
React.createElement("option", null, "Select Camera"),
videoDevices.map((m) => (React.createElement("option", { value: m.value, key: m.value }, m.label)))),
React.createElement("select", { id: "audio-select", className: " bg-black/[.05] block appearance-none w-full border border-gray-300 text-gray-700 py-2 px-3 pr-8 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", value: selectedAudio, onChange: (e) => {
setSelectedAudio(e.target.value);
}, suppressHydrationWarning: true },
React.createElement("option", null, "Select mic"),
audioDevices.map((m) => (React.createElement("option", { value: m.value, key: m.value }, m.label))))),
React.createElement("div", { className: "rv-video-container" },
connectionStatus && React.createElement("span", { className: "status" }, connectionStatus),
React.createElement("video", { className: "local-video", ref: localVidRef, autoPlay: true, playsInline: true, muted: true }),
React.createElement("video", { className: "remort-video", ref: remortVidRef, autoPlay: true, playsInline: true, muted: isVolumeMute })),
React.createElement("div", { className: "control-bar" }, connectionStatus === null || connectionStatus === "" ?
(React.createElement(React.Fragment, null,
React.createElement("button", { type: "button", className: "bg-white text-blue-600 font-medium mx-4 py-2 px-6 rounded-full shadow-md hover:bg-gray-100 focus:bg-gray-100", onClick: () => {
if (webrtcManager && roomName) {
webrtcManager.joinOrStartRoom(roomName);
setconnectionStatus("waiting...");
}
} }, "Start")))
: (React.createElement(React.Fragment, null,
React.createElement("button", { type: "button", className: "bg-white text-blue-600 font-medium py-2 px-6 rounded-full shadow-md hover:bg-gray-100 focus:bg-gray-100", onClick: () => {
if (webrtcManager) {
webrtcManager.muteMic(!isMicMuted);
setisMicMuted(!isMicMuted);
}
} },
React.createElement(Icon, { type: isMicMuted ? "mic-off" : "mic" })),
React.createElement("button", { type: "button", className: "bg-white text-blue-600 font-medium py-2 px-6 rounded-full shadow-md hover:bg-gray-300 focus:bg-gray-300 active:bg-gray-300", onClick: () => {
setisVolumeMute(!isVolumeMute);
} },
React.createElement(Icon, { type: isVolumeMute ? "volume-off" : "volume" })),
React.createElement("button", { type: "button", className: "bg-red-800 text-white font-medium py-2 px-6 rounded-full shadow-md active:bg-red-500 hover:bg-red-500 focus:bg-red-500", onClick: () => {
if (webrtcManager) {
webrtcManager.disconnectAll();
setconnectionStatus(null);
setWebRtcManager(null);
setisMicMuted(false);
}
} },
React.createElement(Icon, { type: "hangup" })))))));
};
//# sourceMappingURL=ReactVideoCall.js.map