Загрузка React приложения...

🏗️ Архитектура приложения

🔌

WebRTC Connection

// iceConfig.js - ICE серверы
const iceConfig = {
    iceServers: [
        { 
            urls: 'stun:stun.l.google.com:19302' 
        },
        {
            urls: 'turn:turn.example.com:3478',
            username: '••••••',
            credential: '••••••'
        }
    ]
};

export default iceConfig;
📹

Video Stream

// useWebRTC.js - Hook для WebRTC
import { useState, useEffect, useRef } from 'react';

export const useWebRTC = () => {
    const [localStream, setLocalStream] = useState(null);
    const [remoteStream, setRemoteStream] = useState(null);
    const peerConnection = useRef(null);

    const getUserMedia = async () => {
        try {
            const stream = await navigator.mediaDevices
                .getUserMedia({
                    video: true,
                    audio: true
                });
            setLocalStream(stream);
            return stream;
        } catch (error) {
            console.error('Ошибка доступа к медиа:', error);
        }
    };

    return { localStream, remoteStream, getUserMedia };
};
📡

WebSocket сигнализация

// websocket.js - Сигнализация
class WebSocketSignaling {
    constructor(url) {
        this.ws = new WebSocket(url);
        this.callbacks = {};
        
        this.ws.onmessage = (e) => {
            const data = JSON.parse(e.data);
            if (this.callbacks[data.type]) {
                this.callbacks[data.type](data);
            }
        };
    }

    sendOffer(sdp, callId) {
        this.ws.send(JSON.stringify({
            type: 'call_offer',
            sdp: sdp,
            callId: callId
        }));
    }

    sendIceCandidate(candidate) {
        this.ws.send(JSON.stringify({
            type: 'ice_candidate',
            candidate: candidate
        }));
    }
}
⚛️

React компоненты

// VideoCall.js - Основной компонент
import React, { useState, useEffect, useRef } from 'react';
import { useWebRTC } from './hooks/useWebRTC';
import WebSocketSignaling from './services/websocket';

export const VideoCall = () => {
    const { localStream, remoteStream, getUserMedia } = useWebRTC();
    const [isCallActive, setIsCallActive] = useState(false);
    const localVideoRef = useRef(null);
    const remoteVideoRef = useRef(null);

    useEffect(() => {
        if (localStream && localVideoRef.current) {
            localVideoRef.current.srcObject = localStream;
        }
        if (remoteStream && remoteVideoRef.current) {
            remoteVideoRef.current.srcObject = remoteStream;
        }
    }, [localStream, remoteStream]);

    return (
        <div className="video-call">
            <div className="video-grid">
                <video ref={localVideoRef} autoPlay muted />
                <video ref={remoteVideoRef} autoPlay />
            </div>
            <button onClick={getUserMedia}>
                Включить камеру
            </button>
        </div>
    );
};

ℹ️ О проекте

🛠️

Технологии

  • ⚛️ React 18 (без create-react-app)
  • 📹 WebRTC для видео/аудио
  • 🔌 WebSocket для сигнализации
  • 🌐 STUN/TURN серверы
  • 📦 Manual CDN загрузка
🎯

Возможности

  • 📞 Видеозвонки в реальном времени
  • 🎥 Включение/отключение камеры
  • 🎤 Включение/отключение микрофона
  • 📋 Лог событий соединения
  • 🔄 Автоматическое переподключение

Особенности

  • 📦 Ручная загрузка React из CDN
  • 🚫 Без create-react-app
  • 🎮 Полный контроль над сборкой
  • 🔌 Интеграция с WordPress
  • 📱 Адаптивный дизайн

📁 Структура проекта

Компоненты

src/
├── components/
│   ├── VideoCall.jsx
│   ├── CallControls.jsx
│   ├── MessageLog.jsx
│   └── ConnectionStatus.jsx
├── hooks/
│   └── useWebRTC.js
├── services/
│   └── websocket.js
└── config/
    └── iceConfig.js

Интеграция с WordPress

wp-content/themes/jordan-portfolio/
├── assets/js/
│   └── react-app.js  // Сборка React
├── page-react.php    // Шаблон
└── functions.php     // Подключение