Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 7 additions & 142 deletions frontend/src/components/Calls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,174 +25,41 @@ const Calls = () => {

useEffect(() => {
if (localVideoRef.current && localStream) {
console.log('🎥 SETTING LOCAL STREAM TO VIDEO ELEMENT');
console.log('Local stream:', localStream);
console.log('Local stream tracks:', localStream.getTracks().map(t => ({
kind: t.kind,
enabled: t.enabled,
readyState: t.readyState,
muted: t.muted
})));
console.log('Local stream active:', localStream.active);
console.log('Local video element:', localVideoRef.current);
console.log('Video element readyState before:', localVideoRef.current.readyState);

// Check if video element already has a stream
if (localVideoRef.current.srcObject) {
console.log('Local video element already has srcObject, replacing it');
}

console.log('Setting local stream to video element');

localVideoRef.current.srcObject = localStream;

// Force the video element to load the new stream
localVideoRef.current.load();
console.log('Called load() on local video element');

// Try to play immediately
// Try to play the video
const playPromise = localVideoRef.current.play();
if (playPromise !== undefined) {
playPromise.then(() => {
console.log('Local video started playing successfully');
}).catch(error => {
playPromise.catch(error => {
console.error('Error playing local video:', error);
});
}

// Add event listeners for debugging
localVideoRef.current.onloadedmetadata = () => {
console.log('Local video metadata loaded');
console.log('Local video dimensions:', localVideoRef.current.videoWidth, 'x', localVideoRef.current.videoHeight);
console.log('Video element readyState:', localVideoRef.current.readyState);
};

localVideoRef.current.oncanplay = () => {
console.log('Local video can play');
console.log('Video element readyState:', localVideoRef.current.readyState);
};

localVideoRef.current.onplay = () => {
console.log('Local video started playing');
};

localVideoRef.current.onpause = () => {
console.log('Local video paused');
};

localVideoRef.current.onerror = (error) => {
console.error('Local video error:', error);
console.error('Video error code:', error.code);
console.error('Video error message:', error.message);
};

localVideoRef.current.onwaiting = () => {
console.log('Local video is waiting for data');
};

localVideoRef.current.onstalled = () => {
console.log('Local video stalled');
};
} else if (localVideoRef.current && !localStream) {
console.log('Clearing local video element');
localVideoRef.current.srcObject = null;
}
}, [localStream]);

useEffect(() => {
if (remoteVideoRef.current && remoteStream) {
console.log('Setting remote stream to video element:', remoteStream);
console.log('Remote stream tracks:', remoteStream.getTracks());
console.log('Remote stream active:', remoteStream.active);
console.log('Remote video element:', remoteVideoRef.current);
console.log('Remote video element readyState:', remoteVideoRef.current.readyState);
window.remoteStream = remoteStream; // Add global reference for debugging

// Check if video element already has a stream
if (remoteVideoRef.current.srcObject) {
console.log('Video element already has srcObject, replacing it');
}

console.log('🎥 REMOTE STREAM ALREADY SET VIA CALLBACK REF');
console.log('Remote stream object:', remoteStream);
console.log('Remote stream active:', remoteStream.active);
console.log('Remote stream tracks:', remoteStream.getTracks().map(t => ({
kind: t.kind,
enabled: t.enabled,
muted: t.muted,
readyState: t.readyState
})));
console.log('Called load() on remote video element');

// Check video element state after setting stream
setTimeout(() => {
console.log('🎥 VIDEO ELEMENT STATE AFTER STREAM SET:');
console.log('Video readyState:', remoteVideoRef.current.readyState);
console.log('Video networkState:', remoteVideoRef.current.networkState);
console.log('Video srcObject:', remoteVideoRef.current.srcObject);
console.log('Video videoWidth:', remoteVideoRef.current.videoWidth);
console.log('Video videoHeight:', remoteVideoRef.current.videoHeight);
}, 1000);

// Add event listeners for debugging
remoteVideoRef.current.onloadedmetadata = () => {
console.log('Remote video metadata loaded');
console.log('Video dimensions:', remoteVideoRef.current.videoWidth, 'x', remoteVideoRef.current.videoHeight);
};

remoteVideoRef.current.oncanplay = () => {
console.log('Remote video can play');
console.log('Video readyState:', remoteVideoRef.current.readyState);
};

remoteVideoRef.current.onplay = () => {
console.log('Remote video started playing');
};

remoteVideoRef.current.onpause = () => {
console.log('Remote video paused');
};

remoteVideoRef.current.onerror = (error) => {
console.error('Remote video error:', error);
console.error('Video error code:', error.code);
console.error('Video error message:', error.message);
};

remoteVideoRef.current.onwaiting = () => {
console.log('Remote video is waiting for data');
};

remoteVideoRef.current.onstalled = () => {
console.log('Remote video stalled');
};

// Try to play the video, but handle autoplay restrictions
// The stream is set via the callback ref in the video element below
// This effect triggers playback when the stream changes
const playPromise = remoteVideoRef.current.play();
if (playPromise !== undefined) {
playPromise.then(() => {
console.log('Remote video started playing successfully');
}).catch(error => {
playPromise.catch(error => {
console.error('Error playing remote video:', error);
console.error('Play error name:', error.name);
console.error('Play error message:', error.message);
// If autoplay fails, we'll rely on user interaction
// The video will show but won't autoplay due to browser policies
});
}
} else if (remoteVideoRef.current && !remoteStream) {
console.log('Clearing remote video element');
remoteVideoRef.current.srcObject = null;
}
}, [remoteStream]);

console.log('Calls component render check:', { isInCall, isCalling, isReceivingCall });

if (!isInCall && !isCalling && !isReceivingCall) {
console.log('Calls component not rendering - no active call state');
return null;
}

console.log('Calls component rendering with state:', { isInCall, isCalling, isReceivingCall, callType, caller });

return (
<div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50">
<div className="bg-bg-primary rounded-lg p-6 max-w-4xl w-full mx-4">
Expand Down Expand Up @@ -264,9 +131,7 @@ const Calls = () => {
ref={(el) => {
remoteVideoRef.current = el;
if (el && remoteStream) {
console.log('Setting remote stream via callback ref:', remoteStream);
el.srcObject = remoteStream;
el.load();
}
}}
autoPlay
Expand Down
51 changes: 11 additions & 40 deletions frontend/src/components/GroupCalls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ const GroupCalls = () => {

useEffect(() => {
if (localVideoRef.current && groupLocalStream) {
console.log('Setting group local stream to video element:', groupLocalStream);
localVideoRef.current.srcObject = groupLocalStream;
localVideoRef.current.load();
} else if (localVideoRef.current && !groupLocalStream) {
localVideoRef.current.srcObject = null;
}
Expand All @@ -34,31 +32,21 @@ const GroupCalls = () => {
// Update remote video elements when remote streams change
Object.entries(groupRemoteStreams).forEach(([userId, stream]) => {
const videoRef = remoteVideoRefs.current[userId];
if (videoRef && stream) {
console.log('🎥 Setting remote stream for user', userId, ':', stream);
console.log('🎥 Stream tracks:', stream.getTracks().map(t => ({ kind: t.kind, enabled: t.enabled })));

// Check if the video element already has this stream
if (videoRef.srcObject !== stream) {
videoRef.srcObject = stream;
videoRef.load();

// Force play
const playPromise = videoRef.play();
if (playPromise !== undefined) {
playPromise.then(() => {
console.log('🎥 Remote video started playing for user:', userId);
}).catch(error => {
console.error('🎥 Error playing remote video for user:', userId, error);
});
}
if (videoRef && stream && videoRef.srcObject !== stream) {
videoRef.srcObject = stream;

// Try to play the video
const playPromise = videoRef.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.error('Error playing remote video for user:', userId, error);
});
}
}
});
}, [groupRemoteStreams]);

if (!isInGroupCall && !isStartingGroupCall && !isReceivingGroupCall) {
console.log('GroupCalls component not rendering - no active group call state');
return null;
}

Expand All @@ -79,17 +67,6 @@ const GroupCalls = () => {
const remoteParticipants = participants.filter(p => p !== authUser?._id);
const totalParticipants = participants.length;

console.log('GroupCalls component render check:', {
isInGroupCall,
isStartingGroupCall,
isReceivingGroupCall,
currentGroupCall,
participants: currentGroupCall?.participants,
remoteParticipants,
groupRemoteStreams: Object.keys(groupRemoteStreams),
totalParticipants
});

// Dynamic grid classes based on number of video slots (local + remote participants)
const getGridClasses = () => {
const videoSlots = (groupLocalStream ? 1 : 0) + remoteParticipants.length;
Expand Down Expand Up @@ -196,18 +173,15 @@ const GroupCalls = () => {
ref={(el) => {
if (el) {
remoteVideoRefs.current[participantId] = el;
console.log('🎥 Video element created for user:', participantId);


// If we already have a stream, set it immediately
const stream = groupRemoteStreams[participantId];
if (stream && el.srcObject !== stream) {
console.log('🎥 Setting stream immediately for user:', participantId);
el.srcObject = stream;
el.load();
const playPromise = el.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.error('🎥 Error playing video for user:', participantId, error);
console.error('Error playing video for user:', participantId, error);
});
}
}
Expand All @@ -217,9 +191,6 @@ const GroupCalls = () => {
playsInline
muted={false}
className="w-full h-full object-cover"
onLoadedMetadata={() => console.log('🎥 Video metadata loaded for user:', participantId)}
onCanPlay={() => console.log('🎥 Video can play for user:', participantId)}
onError={(e) => console.error('🎥 Video error for user:', participantId, e)}
/>
) : (
<div className="w-full h-full flex items-center justify-center">
Expand Down