React WebRTC Video Call Dashboard
Реальный проект с интеграцией WebRTC и WebSocket
Video Call Dashboard
React 18Полноценное React приложение для видео/аудио звонков через WebRTC. Подключается к вашему серверу через WebSocket и использует STUN/TURN серверы для установки peer-to-peer соединения.
WebRTC
Технология
18.2.0
React версия
100%
Кастомный код
Загрузка 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 // Подключение