Исправь ошибку и добавь больше серверов по мимо гугловских
// public/client.js
const socket = io();

// Элементы интерфейса
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');
const chat = document.getElementById('chat');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const toggleAudioButton = document.getElementById('toggleAudio');
const toggleVideoButton = document.getElementById('toggleVideo');
const shareScreenButton = document.getElementById('shareScreen');

// Получение медиапотоков
let localStream;
let screenStream;
const peers = {};

// Конфигурация ICE серверов
const config = {
    iceServers: [
        { urls: 'stun:stun.l.google.com:19302' }
    ]
};

// Получение локального видео и аудио
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
    .then(stream => {
        localStream = stream;
        localVideo.srcObject = stream;
    })
    .catch(err => {
        console.error('Ошибка получения медиапотоков:', err);
    });

// Обработка отправки сообщений
sendButton.addEventListener('click', () => {
    const message = messageInput.value;
    if (message.trim() !== '') {
        appendMessage(\`Вы: \${message}\`);
        // Отправка сообщения через Data Channel каждому пиру
        for (let peerId in peers) {
            if (peers[peerId].dataChannel && peers[peerId].dataChannel.readyState === 'open') {
                peers[peerId].dataChannel.send(message);
            }
        }
        messageInput.value = '';
    }
});

// Функция для добавления сообщений в чат
function appendMessage(message) {
    const msg = document.createElement('div');
    msg.textContent = message;
    chat.appendChild(msg);
    chat.scrollTop = chat.scrollHeight;
}

// Обработка сигналов от сервера
socket.on('signal', async (data) => {
    const { from, signal } = data;
    if (!peers[from]) {
        await createPeerConnection(from, false);
    }
    const peer = peers[from].peerConnection;

    if (signal.type === 'offer') {
        await peer.setRemoteDescription(new RTCSessionDescription(signal));
        const answer = await peer.createAnswer();
        await peer.setLocalDescription(answer);
        socket.emit('signal', { to: from, signal: peer.localDescription });
    } else if (signal.type === 'answer') {
        await peer.setRemoteDescription(new RTCSessionDescription(signal));
    } else if (signal.candidate) {
        try {
            await peer.addIceCandidate(new RTCIceCandidate(signal.candidate));
        } catch (e) {
            console.error('Ошибка добавления ICE кандидата:', e);
        }
    }
});

// Обработка подключения нового пользователя
socket.on('user-connected', (userId) => {
    console.log('Пользователь подключился: ' + userId);
    connectToPeer(userId);
});

// Обработка отключения пользователя
socket.on('user-disconnected', (userId) => {
    console.log('Пользователь отключился: ' + userId);
    if (peers[userId]) {
        peers[userId].peerConnection.close();
        if (peers[userId].dataChannel) {
            peers[userId].dataChannel.close();
        }
        delete peers[userId];
        appendMessage(\`Пир \${userId} отключился\`);
    }
});

// Создание и инициализация Peer Connection
async function createPeerConnection(peerId, isInitiator) {
    const peerConnection = new RTCPeerConnection(config);

    // Добавление локальных потоков
    if (localStream) {
        localStream.getTracks().forEach(track => {
            peerConnection.addTrack(track, localStream);
        });
    }

    // Создание Data Channel для текстовых сообщений
    let dataChannel;
    if (isInitiator) {
        dataChannel = peerConnection.createDataChannel('chat');
        dataChannel.onmessage = (event) => {
            appendMessage(\`Пир \${peerId}: \${event.data}\`);
        };
    } else {
        peerConnection.ondatachannel = (event) => {
            dataChannel = event.channel;
            dataChannel.onmessage = (event) => {
                appendMessage(\`Пир \${peerId}: \${event.data}\`);
            };
        };
    }

    // Обработка полученных треков
    peerConnection.ontrack = (event) => {
        if (event.streams && event.streams[0]) {
            remoteVideo.srcObject = event.streams[0];
        }
    };

    // Обработка ICE кандидатов
    peerConnection.onicecandidate = (event) => {
        if (event.candidate) {
            socket.emit('signal', { to: peerId, signal: { candidate: event.candidate } });
        }
    };

    // Создание описания соединения для инициатора
    if (isInitiator) {
        const offer = await peerConnection.createOffer();
        await peerConnection.setLocalDescription(offer);
        socket.emit('signal', { to: peerId, signal: peerConnection.localDescription });
    }

    // Сохранение данных пира
    peers[peerId] = { peerConnection, dataChannel };
}

// Функция для подключения к новому пиру
async function connectToPeer(peerId) {
    await createPeerConnection(peerId, true);
}

// Управление микрофоном
toggleAudioButton.addEventListener('click', () => {
    const audioTrack = localStream.getAudioTracks()[0];
    if (audioTrack) {
        audioTrack.enabled = !audioTrack.enabled;
        toggleAudioButton.textContent = audioTrack.enabled ? 'Отключить Аудио' : 'Включить Аудио';
    }
});

// Управление видеокамерой
toggleVideoButton.addEventListener('click', () => {
    const videoTrack = localStream.getVideoTracks()[0];
    if (videoTrack) {
        videoTrack.enabled = !videoTrack.enabled;
        toggleVideoButton.textContent = videoTrack.enabled ? 'Отключить Видео' : 'Включить Видео';
    }
});

// Демонстрация экрана
shareScreenButton.addEventListener('click', async () => {
    try {
        screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });
        const screenTrack = screenStream.getVideoTracks()[0];

        for (let peerId in peers) {
            const sender = peers[peerId].peerConnection.getSenders().find(s => s.track.kind === 'video');
            if (sender) {
                await sender.replaceTrack(screenTrack);
            }
        }

        screenTrack.onended = async () => {
            for (let peerId in peers) {
                const sender = peers[peerId].peerConnection.getSenders().find(s => s.track.kind === 'video');
                if (sender) {
                    await sender.replaceTrack(localStream.getVideoTracks()[0]);
                }
            }
        };
    } catch (err) {
        console.error('Ошибка захвата экрана:', err);
    }
});