diff --git a/app/.env.local.sample b/app/.env.local.sample index c0c15538..edb7dd0e 100644 --- a/app/.env.local.sample +++ b/app/.env.local.sample @@ -44,3 +44,5 @@ NEXT_PUBLIC_ROCKET_CHAT_HOST=requiredInProd NEXT_PUBLIC_ROCKET_CHAT_CONF_RID=required # id of the greenroom NEXT_PUBLIC_ROCKET_CHAT_GREENROOM_RID=required +NEXT_PUBLIC_ROCKET_CHAT_GREENROOM_RTMP="rtmp://bkk.contribute.live-video.net/app/{stream_key}" + diff --git a/app/components/clientsideonly/jitsibroadcaster.js b/app/components/clientsideonly/jitsibroadcaster.js index f87c8b06..f9a80f08 100644 --- a/app/components/clientsideonly/jitsibroadcaster.js +++ b/app/components/clientsideonly/jitsibroadcaster.js @@ -1,269 +1,412 @@ - -import dynamic from 'next/dynamic' -import React, { useRef, useState } from 'react' - - -const JitsiMeeting = dynamic( () => import('@jitsi/web-sdk').then((mod) => mod.JitsiMeeting) , {ssr: false } ) - - -const Jitsibroadcaster = () => { - const apiRef = useRef(); - const apiRefNew = useRef(); - const [ logItems, updateLog ] = useState([]); - const [ showNew, toggleShowNew ] = useState(false); - const [ knockingParticipants, updateKnockingParticipants ] = useState([]); - - const printEventOutput = payload => { - updateLog(items => [ ...items, JSON.stringify(payload) ]); - }; - - const handleAudioStatusChange = (payload, feature) => { - if (payload.muted) { - updateLog(items => [ ...items, `${feature} off` ]) - } else { - updateLog(items => [ ...items, `${feature} on` ]) - } - }; - - const handleChatUpdates = (payload, ref) => { - if (payload.isOpen || !payload.unreadCount) { - return; - } - ref.current.executeCommand('toggleChat'); - updateLog(items => [ ...items, `you have ${payload.unreadCount} unread messages` ]) - }; - - const handleKnockingParticipant = payload => { - updateLog(items => [ ...items, JSON.stringify(payload) ]); - updateKnockingParticipants(participants => [ ...participants, payload?.participant ]) - }; - - const resolveKnockingParticipants = (ref, condition) => { - knockingParticipants.forEach(participant => { - ref.current.executeCommand('answerKnockingParticipant', participant?.id, condition(participant)); - updateKnockingParticipants(participants => participants.filter(item => item.id === participant.id)); +import dynamic from "next/dynamic"; +import React, { useEffect, useRef, useState } from "react"; +import { Button, ButtonGroup } from "react-bootstrap"; +import { BiMicrophone, BiMicrophoneOff } from "react-icons/bi"; + +const JitsiMeeting = dynamic( + () => import("@jitsi/react-sdk").then((mod) => mod.JitsiMeeting), + { ssr: false } +); + +const rtmp = process.env.NEXT_PUBLIC_ROCKET_CHAT_GREENROOM_RTMP; + +const Jitsibroadcaster = ({room, disName, rtmpSrc}) => { + const apiRef = useRef(); + const [logItems, updateLog] = useState([]); + const [knockingParticipants, updateKnockingParticipants] = useState([]); + const [mute, setMute] = useState(true); + const [name, setName] = useState(null) + const dataArr = [{speaker: "A", hour: "10"}, {speaker: "B", hour: "20"}, {speaker: "C", hour: "30"}, {speaker: "D", hour: "40"}, {speaker: "Z", hour: "50"}] + + const handleDisplayName = async (hr) => { + const tar = dataArr.find(o => o.hour === hr) + if (!tar || tar.speaker == name) { + return + } + setName(tar.speaker) + await apiRef.current.executeCommand("displayName", tar.speaker) + } + + useEffect(() => { + setInterval(() => { + const tada = new Date() + handleDisplayName(tada.getHours().toString()) + }, 900000); + }, []) + + const printEventOutput = (payload) => { + updateLog((items) => [...items, JSON.stringify(payload)]); + }; + + const handleAudioStatusChange = (payload, feature) => { + if (payload.muted) { + updateLog((items) => [...items, `${feature} off`]); + } else { + updateLog((items) => [...items, `${feature} on`]); + } + }; + + const handleChatUpdates = (payload, ref) => { + if (payload.isOpen || !payload.unreadCount) { + return; + } + ref.current.executeCommand("toggleChat"); + updateLog((items) => [ + ...items, + `you have ${payload.unreadCount} unread messages`, + ]); + }; + + const handleKnockingParticipant = (payload) => { + updateLog((items) => [...items, JSON.stringify(payload)]); + updateKnockingParticipants((participants) => [ + ...participants, + payload?.participant, + ]); + }; + + const resolveKnockingParticipants = (ref, condition) => { + knockingParticipants.forEach((participant) => { + ref.current.executeCommand( + "answerKnockingParticipant", + participant?.id, + condition(participant) + ); + updateKnockingParticipants((participants) => + participants.filter((item) => item.id === participant.id) + ); + }); + }; + + const handleJitsiIFrameRef1 = (iframeRef) => { + iframeRef.style.border = "10px solid cadetblue"; + iframeRef.style.background = "cadetblue"; + iframeRef.style.height = "720px"; + iframeRef.style.overflow = "auto"; + iframeRef.style.resize = "both"; + }; + + const showDevices = async (ref) => { + const videoInputs = []; + // get all available video input + const devices = await ref.current.getAvailableDevices(); + + for (const [key, value] of Object.entries(devices)) { + if (key == "videoInput") { + value.forEach((vid) => { + videoInputs.push(vid.label); }); - }; - - const handleJitsiIFrameRef1 = iframeRef => { - iframeRef.style.border = '10px solid cadetblue'; - iframeRef.style.background = 'cadetblue'; - iframeRef.style.height = '720px'; - }; - - const handleJitsiIFrameRef2 = iframeRef => { - iframeRef.style.marginTop = '10px'; - iframeRef.style.border = '10px dashed tomato'; - iframeRef.style.padding = '5px'; - iframeRef.style.height = '400px'; - }; - - - const showDevices = async (ref) => { - const videoInputs = []; - let currentDevice = ""; - // get all available video input - const devices = await ref.current.getAvailableDevices(); - - for (const [key, value] of Object.entries(devices)) { - if ( key == 'videoInput') { - value.forEach( (vid) => { - videoInputs.push( vid.label ); - }); - - } + } + } + // log for debug + updateLog((items) => [...items, JSON.stringify(videoInputs)]); + + let nextDevice = ""; + let devs = await ref.current.getCurrentDevices(); + + for (const [key, value] of Object.entries(devs)) { + if (key == "videoInput") { + updateLog((items) => [...items, "found " + JSON.stringify(value)]); + let devLabel = value.label; + let idx = 0; + videoInputs.forEach((vid) => { + if (devLabel == vid) { + let cur = idx + 1; + if (cur >= videoInputs.length) { + nextDevice = videoInputs[0]; + } else { + nextDevice = videoInputs[cur]; + updateLog((items) => [...items, "next is " + nextDevice]); } - // log for debug - updateLog(items => [ ...items, JSON.stringify(videoInputs) ]) - - let nextDevice = ""; - let devs = await ref.current.getCurrentDevices(); - - for (const [key, value] of Object.entries(devs)) { - if ( key == 'videoInput') { - updateLog(items => [ ...items, "found " + JSON.stringify(value) ]) - let devLabel = value.label; - let idx = 0; - videoInputs.forEach( (vid) => { - if (devLabel == vid) { - let cur = idx + 1; - if (cur >= videoInputs.length) { - nextDevice = videoInputs[0]; - } else { - nextDevice = videoInputs[cur]; - updateLog(items => [ ...items, "next is " + nextDevice ]) - } - - } - idx++; - }); - - - } - - - } - updateLog(items => [ ...items, "switching to " + nextDevice ]) - await ref.current.setVideoInputDevice(nextDevice); - }; - - const handleApiReady = async (apiObj, ref) => { - ref.current = apiObj; - await ref.current.addEventListeners({ - // Listening to events from the external API - audioMuteStatusChanged: payload => handleAudioStatusChange(payload, 'audio'), - videoMuteStatusChanged: payload => handleAudioStatusChange(payload, 'video'), - raiseHandUpdated: printEventOutput, - tileViewChanged: printEventOutput, - chatUpdated: payload => handleChatUpdates(payload, ref), - knockingParticipant: handleKnockingParticipant + } + idx++; }); - - - await ref.current.executeCommand('toggleFilmStrip'); - - } ; - - // Multiple instances demo - const showUsers = async (ref, which) => { - - const pinfo = await ref.current.getParticipantsInfo(); - updateLog(items => [ ...items, "participantes " + JSON.stringify(pinfo) ]) - await ref.current.executeCommand('setTileView', false); - await ref.current.setLargeVideoParticipant( pinfo[which].participantId); - }; - - const makeTile = (ref) => { - - ref.current.executeCommand('setTileView', true); - }; - const renderButtons = () => ( -