Проверка

This commit is contained in:
Халимов Рустам
2026-03-11 16:31:32 +03:00
parent 926482861f
commit 0f89b21dd4
3 changed files with 34 additions and 18 deletions
+2
View File
@@ -72,3 +72,5 @@ SECURITY_AUDIT.md
.npm/ .npm/
.tmp/ .tmp/
tmp/ tmp/
.env.example
+16 -11
View File
@@ -120,16 +120,28 @@ app.get('/api/ice-servers', authenticateToken, (_req: AuthRequest, res) => {
const iceServers: Array<{ urls: string | string[]; username?: string; credential?: string }> = []; const iceServers: Array<{ urls: string | string[]; username?: string; credential?: string }> = [];
// STUN серверы // STUN серверы
if (config.stunUrls.length > 0) { const stunUrls = [...config.stunUrls];
iceServers.push({ urls: config.stunUrls }); // Добавляем ваш VPS и как STUN тоже (раз он работает)
if (config.turnUrl) {
const vpsStun = config.turnUrl.replace('turn:', 'stun:');
if (!stunUrls.includes(vpsStun)) stunUrls.push(vpsStun);
}
if (stunUrls.length > 0) {
iceServers.push({ urls: stunUrls });
} }
// TURN сервер (динамическая или статическая аутентификация) // TURN сервер (динамическая или статическая аутентификация)
if (config.turnUrl) { if (config.turnUrl) {
const urls = config.turnUrl.split(',').map(s => s.trim()); const urls = config.turnUrl.split(',').map(s => s.trim());
if (config.turnSecret) { if (config.turnUsername && config.turnPassword) {
// Динамический пароль (HMAC-SHA1) iceServers.push({
urls: urls,
username: config.turnUsername,
credential: config.turnPassword,
});
} else if (config.turnSecret) {
const ttl = 48 * 3600; const ttl = 48 * 3600;
const timestamp = Math.floor(Date.now() / 1000) + ttl; const timestamp = Math.floor(Date.now() / 1000) + ttl;
const username = `${timestamp}:vortex`; const username = `${timestamp}:vortex`;
@@ -143,13 +155,6 @@ app.get('/api/ice-servers', authenticateToken, (_req: AuthRequest, res) => {
username, username,
credential, credential,
}); });
} else if (config.turnUsername && config.turnPassword) {
// Статичный логин/пароль
iceServers.push({
urls: urls,
username: config.turnUsername,
credential: config.turnPassword,
});
} }
} }
+16 -7
View File
@@ -285,12 +285,18 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
}); });
} }
// Handle audio via stable audio element // Handle remote media via the remoteVideoRef
if (remoteAudioRef.current) { if (remoteVideoRef.current) {
if (remoteAudioRef.current.srcObject !== stream) { if (remoteVideoRef.current.srcObject !== stream) {
remoteAudioRef.current.srcObject = stream; console.log('[WebRTC] Binding stream to video element');
remoteVideoRef.current.srcObject = stream;
remoteVideoRef.current.load();
} }
remoteAudioRef.current.play().catch(e => console.warn('[WebRTC] Audio play failed:', e)); // Important: Unmute for remote audio to work
remoteVideoRef.current.muted = false;
remoteVideoRef.current.play().catch(e => {
console.warn('[WebRTC] Play failed, waiting for user interaction:', e);
});
} }
track.onunmute = checkVideo; track.onunmute = checkVideo;
@@ -309,6 +315,10 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
endCallSafe(); endCallSafe();
} }
}; };
pc.oniceconnectionstatechange = () => {
console.log('[WebRTC] ICE Connection state:', pc.iceConnectionState);
};
}, [endCallSafe]); // REMOVED callType dependency to prevent handler reset during call }, [endCallSafe]); // REMOVED callType dependency to prevent handler reset during call
// Start outgoing call // Start outgoing call
@@ -1429,7 +1439,7 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
return ( return (
<AnimatePresence> <AnimatePresence>
<audio key="remote-audio" ref={remoteAudioRef} autoPlay playsInline /> {/* Remote audio is handled by the video element below */}
{/* === MINIMIZED VIEW === */} {/* === MINIMIZED VIEW === */}
{isMinimized && callState === 'connected' ? ( {isMinimized && callState === 'connected' ? (
@@ -1577,7 +1587,6 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
ref={remoteVideoRef} ref={remoteVideoRef}
autoPlay autoPlay
playsInline playsInline
muted
className={` className={`
bg-black transition-all duration-500 bg-black transition-all duration-500
${showVideoArea ${showVideoArea