Code to get remotevideo from roomclient
In html, the remoteVideoEl obtained here can be displayed directly on the screen with roomclient.remoteVideoEl, but I don’t know how to display it in a react-type script
I’d like to display several remoteVideoEl from the code below on the screen
async produce(type: string, deviceId: string | null = null) {
let mediaConstraints: any = {};
let audio = false;
let screen = false;
switch (type) {
case mediaType.audio:
mediaConstraints = {
audio: {
deviceId: deviceId
},
video: false
};
audio = true;
break;
case mediaType.video:
mediaConstraints = {
audio: false,
video: {
width: {
min: 640,
ideal: 640
},
height: {
min: 480,
ideal: 480
},
deviceId: deviceId
}
};
break;
case mediaType.screen:
mediaConstraints = false;
screen = true;
break;
default:
return;
}
if (!this.device!.canProduce('video') && !audio) {
console.error('Cannot produce video');
return;
}
if (this.producerLabel.has(type)) {
console.log('Producer already exists for this type ' + type);
return;
}
console.log('Media constraints:', mediaConstraints);
let stream;
try {
stream = screen ? await (navigator.mediaDevices as any).getDisplayMedia() : await navigator.mediaDevices.getUserMedia(mediaConstraints);
console.log(navigator.mediaDevices.getSupportedConstraints());
const track = audio ? stream.getAudioTracks()[0] : stream.getVideoTracks()[0];
const params = {
track
};
const producer = await this.producerTransport!.produce(params);
console.log('Producer', producer);
this.producers.set(producer.id, producer);
let elem: HTMLVideoElement;
if (!audio) {
elem = document.createElement('video');
elem.srcObject = stream;
elem.id = producer.id;
elem.playsInline = false;
elem.autoplay = true;
elem.className = 'vid';
this.localMediaEl.appendChild(elem);
}
producer.on('trackended', () => {
this.closeProducer(type);
});
producer.on('transportclose', () => {
console.log('Producer transport closed');
if (!audio) {
elem!.parentNode!.removeChild(elem!);
}
this.producers.delete(producer.id);
});
producer.on('@close', () => {
console.log('Closing producer');
if (!audio) {
elem!.parentNode!.removeChild(elem!);
}
this.producers.delete(producer.id);
});
this.producerLabel.set(type, producer.id);
switch (type) {
case mediaType.audio:
this.event(_EVENTS.startAudio);
break;
case mediaType.video:
this.event(_EVENTS.startVideo);
break;
case mediaType.screen:
this.event(_EVENTS.startScreen);
break;
default:
return;
}
} catch (err) {
console.log(err);
}
}
async consume(producer_id: string) {
try {
const { consumer, stream, kind } = await this.getConsumeStream(producer_id);
this.consumers.set(consumer.id, consumer);
let elem: HTMLVideoElement | HTMLAudioElement;
if (kind === 'video') {
elem = document.createElement('video');
elem.srcObject = stream;
elem.id = consumer.id;
if ("playsInline" in elem) {
elem.playsInline = false;
} // For video
elem.autoplay = true;
elem.className = 'vid';
this.remoteVideoEl.appendChild(elem);
} else {
elem = document.createElement('audio');
elem.srcObject = stream;
elem.id = consumer.id;
elem.autoplay = true;
// Handle playsInline property for audio
if ("playsInline" in elem) {
// Some browsers might support it, so set it to false if available
elem.playsInline = false;
}
this.remoteAudioEl.appendChild(elem);
}
consumer.on('trackended', () => {
this.removeConsumer(consumer.id);
});
consumer.on('transportclose', () => {
this.removeConsumer(consumer.id);
});
} catch (error) {
console.error('Error consuming stream:', error);
}
}
async getConsumeStream(producerId: string): Promise<ConsumeResult> {
const { rtpCapabilities } = this.device!;
const data = await this.socket.request('consume', {
rtpCapabilities,
consumerTransportId: this.consumerTransport!.id,
producerId
});
const { id, kind, rtpParameters } = data;
const consumer = await this.consumerTransport!.consume({
id,
producerId,
kind,
rtpParameters,
});
const stream = new MediaStream();
stream.addTrack(consumer.track);
return {
consumer,
stream,
kind
};
}
If you look at the code below, I’m showing you the video through videoRef, but instead of this, please tell me how to float the remote video obtained from the code one by one from A1 to B3
import React, {useEffect, useRef, useState} from 'react';
import {useLocation, useNavigate} from "react-router-dom";
import "./DebateRoom.css"
import RoomClient from "../../socket/RoomClient";
import {rc} from "../../socket/socket";
interface DebateRoomProps {
onLeave: () => void;
}
const DebateRoom: React.FC<DebateRoomProps> = ({onLeave}) => {
const navigate = useNavigate();
const location = useLocation();
const { selectedMicDevice, selectedAudioDevice, selectedVideoDevice } = location.state;
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const initVideo = async () => {
try {
console.log("device start")
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
if (videoRef.current) {
console.log(selectedVideoDevice + " video");
console.log(selectedAudioDevice + " audio");
await rc.produce(RoomClient.mediaType.video, selectedVideoDevice);
await rc.produce(RoomClient.mediaType.audio, selectedAudioDevice);
videoRef.current.srcObject = stream;
}
} catch (error) {
console.error('Error accessing local media:', error);
}
};
initVideo();
}, []);
return (
<div>
<div className="AteamArea">
<div className="A1">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
<div className="A2">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
<div className="A3">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
</div>
<div className="BteamArea">
<div className="B1">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
<div className="B2">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
<div className="B3">
<video className="Cam" ref={videoRef} autoPlay width="526px" height="332px" ></video>
</div>
</div>
</div>
);
};
export default DebateRoom;
This is a code with an rc
import { Socket } from 'socket.io-client';
import RoomClient from "./RoomClient";
interface SocketData {
error?: string;
[key: string]: any;
}
export interface CustomSocket extends Socket {
request: <T = any>(type: string, data?: object) => Promise<T>;
}
export const setupSocket = (socket: Socket): CustomSocket => {
const customSocket = socket as CustomSocket;
customSocket.request = function request<T = any>(type: string, data = {}): Promise<T> {
return new Promise((resolve, reject) => {
this.emit(type, data, (response: SocketData) => {
if (response.error) {
reject(response.error);
} else {
resolve(response as T);
}
});
});
};
return customSocket;
};
export let producer: any = null;
export let rc: any = null;
export let isEnumerateDevices = false;
export function start() {
rc.start();
}
export function joinRoom(name: string, room_id: string, audioSelect: HTMLOptionElement, videoSelect: HTMLOptionElement, localMediaEl: HTMLVideoElement,
remoteVideoEl: HTMLVideoElement,
remoteAudioEl: HTMLAudioElement,
mediasoupClientInstance: any,
socketUrl: string,
successCallback: () => void) {
if (rc && rc.isOpen()) {
console.log('Already connected to a room');
} else {
initEnumerateDevices(audioSelect,videoSelect);
rc = new RoomClient(localMediaEl, remoteVideoEl, remoteAudioEl, mediasoupClientInstance, socketUrl, room_id, name, successCallback);
}
}
export function initEnumerateDevices(audioSelect: HTMLOptionElement, videoSelect: HTMLOptionElement) {
console.log("initinitinit0")
// Many browsers, without the consent of getUserMedia, cannot enumerate the devices.
if (isEnumerateDevices) return;
const constraints = {
audio: true,
video: true
};
navigator.mediaDevices
.getUserMedia(constraints)
.then((stream: MediaStream) => {
enumerateDevices(audioSelect, videoSelect);
stream.getTracks().forEach(function (track: MediaStreamTrack) {
track.stop();
});
})
.catch((err: any) => {
console.error('Access denied for audio/video: ', err);
});
}
export function enumerateDevices(audioSelect: HTMLOptionElement, videoSelect: HTMLOptionElement) {
// Load mediaDevice options
navigator.mediaDevices.enumerateDevices().then((devices: MediaDeviceInfo[]) =>
devices.forEach((device) => {
let el = null;
if ('audioinput' === device.kind) {
el = audioSelect;
} else if ('videoinput' === device.kind) {
el = videoSelect;
}
if (!el) return;
let option = document.createElement('option');
option.value = device.deviceId || '';
option.innerText = device.label || '';
el.appendChild(option);
isEnumerateDevices = true;
})
);
}