signalR video chat
<!DOCTYPE html>
<html>
<head>
<title>Video Chat</title>
</head>
<body>
<h1>Video Chat</h1>
<video id="localVideo" autoplay muted></video>
<video id="remoteVideo" autoplay></video>
<button id="startButton">Start Call</button>
<button id="hangupButton">Hang Up</button>
<script src="https://cdn.jsdelivr.net/npm/webrtc-adapter/out/adapter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.10/signalr.min.js"></script>
@*<script src="video-chat.js"></script>*@
</body>
</html>
<script>
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');
const startButton = document.getElementById('startButton');
const hangupButton = document.getElementById('hangupButton');
let localStream;
let remoteStream;
let peerConnection;
startButton.addEventListener('click', startCall);
hangupButton.addEventListener('click', hangUp);
// Initialize SignalR connection
const connection = new signalR.HubConnectionBuilder()
.withUrl('/chatHub')
.build();
connection.start().catch(err => console.error(err.toString()));
// Handle incoming calls
connection.on('StartCall', async (callerConnectionId) => {
try {
// Create an offer
peerConnection = new RTCPeerConnection();
// Add local stream to peer connection
localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream));
// Create an offer and set it as the local description
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// Send the offer to the caller
connection.invoke('AnswerCall', callerConnectionId, offer);
} catch (error) {
console.error('Error creating offer:', error);
}
});
// Handle the answer from the callee
connection.on('CallAnswered', async (calleeConnectionId, answer) => {
try {
// Set the remote description with the answer
await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
} catch (error) {
console.error('Error setting remote description:', error);
}
});
// Handle ICE candidates
connection.on('IceCandidate', async (candidate) => {
try {
// Add the ICE candidate to the peer connection
await peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
} catch (error) {
console.error('Error adding ICE candidate:', error);
}
});
// Function to start a call
async function startCall() {
try {
debugger;
localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localVideo.srcObject = localStream;
// Join a room and start a call
await connection.invoke('JoinRoom', 'roomName');
await connection.invoke('StartCall', 'roomName');
} catch (error) {
console.error('Error starting call:', error);
}
}
// Function to hang up the call
function hangUp() {
if (localStream) {
localStream.getTracks().forEach(track => track.stop());
}
if (remoteStream) {
remoteStream.getTracks().forEach(track => track.stop());
}
if (peerConnection) {
peerConnection.close();
}
localVideo.srcObject = null;
remoteVideo.srcObject = null;
// Leave the room
connection.invoke('LeaveRoom', 'roomName');
}
</script>
-----
--controller
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
namespace ResumeManager.Controllers
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task JoinRoom(string roomName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
}
public async Task LeaveRoom(string roomName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomName);
}
public async Task StartCall(string roomName)
{
await Clients.Group(roomName).SendAsync("StartCall", Context.ConnectionId);
}
public async Task AnswerCall(string targetConnectionId)
{
await Clients.Client(targetConnectionId).SendAsync("CallAnswered", Context.ConnectionId);
}
public async Task IceCandidate(string targetConnectionId, string iceCandidate)
{
await Clients.Client(targetConnectionId).SendAsync("IceCandidate", iceCandidate);
}
}
}
Comments
Post a Comment