Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Button } from '@mantine/core';
- import { io } from 'socket.io-client';
- import { v4 as generateUuid } from 'uuid';
- interface Peer {
- id: string;
- consumerId?: string;
- pc?: RTCPeerConnection;
- }
- const upPeers = new Map<string, Peer>();
- const downPeers = new Map<string, RTCPeerConnection>();
- let state = false;
- const socket = io('http://localhost:8000');
- const consume = async (p: Peer) => {
- if (p.id === socket.id || upPeers.has(p.id)) return;
- const consumerId = generateUuid();
- console.log('Consuming', p.id);
- const peer = upPeers.set(p.id, p).get(p.id);
- if (!peer) return;
- peer.consumerId = consumerId;
- const pc = new RTCPeerConnection({
- iceServers: [
- { urls: 'stun:stun.stunprotocol.org:3478' },
- { urls: 'stun:stun.l.google.com:19302' },
- ],
- });
- const downPeer = downPeers.set(consumerId, pc).get(consumerId);
- if (!downPeer) return;
- downPeer.addTransceiver('video', { direction: 'recvonly' });
- downPeer.addTransceiver('audio', { direction: 'recvonly' });
- const offer = await downPeer.createOffer();
- await downPeer.setLocalDescription(offer);
- downPeer.onicecandidate = ({ candidate }) => {
- if (candidate && candidate.candidate && candidate.candidate.length > 0)
- socket.emit('down_ice', { consumerId, candidate });
- };
- downPeer.ontrack = (event) => {
- const container = document.querySelector('#container');
- if (!container) return;
- const video = document.querySelector<HTMLVideoElement>(`#down_${peer.id}`);
- const remoteStream = event.streams[0];
- if (video) {
- remoteStream.getTracks().forEach((track) => {
- video.srcObject.addTrack(track);
- });
- } else {
- const video = document.createElement('video');
- video.id = `down_${peer.id}`;
- video.srcObject = remoteStream;
- video.autoplay = true;
- video.muted = false;
- container.appendChild(video);
- }
- };
- socket.emit(
- 'down',
- { id: peer.id, consumerId, offer },
- (answer: RTCSessionDescriptionInit) => {
- downPeer.setRemoteDescription(new RTCSessionDescription(answer));
- },
- );
- };
- const join = async () => {
- const localStream = await navigator.mediaDevices.getUserMedia({
- audio: true,
- video: {
- mandatory: {
- width: { min: 320 },
- height: { min: 180 },
- },
- optional: [
- { width: { max: 1280 } },
- { frameRate: 30 },
- { facingMode: 'user' },
- ],
- },
- });
- const container = document.querySelector('#container');
- if (!container) return;
- const video = document.createElement('video');
- video.id = `up`;
- video.srcObject = localStream;
- video.autoplay = true;
- video.muted = true;
- container.appendChild(video);
- const pc = new RTCPeerConnection({
- iceServers: [
- { urls: 'stun:stun.stunprotocol.org:3478' },
- { urls: 'stun:stun.l.google.com:19302' },
- ],
- });
- pc.onicecandidate = ({ candidate }) => {
- if (candidate && candidate.candidate && candidate.candidate.length > 0)
- socket.emit('up_ice', candidate);
- };
- pc.onnegotiationneeded = async () => {
- const offer = await pc.createOffer();
- await pc.setLocalDescription(offer);
- socket.emit(
- 'up',
- offer,
- ({
- upPeers: peers,
- answer,
- }: {
- upPeers: Peer[];
- answer: RTCSessionDescriptionInit;
- }) => {
- pc.setRemoteDescription(new RTCSessionDescription(answer));
- peers.forEach(consume);
- state = true;
- },
- );
- };
- localStream.getTracks().forEach((track) => {
- pc.addTrack(track, localStream);
- });
- };
- socket.on('newUp', (id) => {
- if (state) consume({ id });
- });
- socket.on('producerLeft', (id) => {
- const client = upPeers.get(id);
- if (!client?.consumerId) return;
- downPeers.delete(client.consumerId);
- upPeers.delete(id);
- const video = document.querySelector<HTMLVideoElement>(`#other_${id}`);
- if (!video) return;
- if (video.srcObject)
- video.srcObject.getTracks().forEach((track) => track.stop());
- video.remove();
- });
- const Unite = () => {
- return (
- <div>
- {!state ? (
- <Button
- onClick={() => {
- join();
- }}
- >
- Join
- </Button>
- ) : (
- socket.id
- )}
- <div id="container" />
- </div>
- );
- };
- export default Unite;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement