Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Audio Call App</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
.container { | |
text-align: center; | |
} | |
#callButton, #hangupButton { | |
padding: 10px 20px; | |
margin: 10px; | |
font-size: 16px; | |
cursor: pointer; | |
} | |
#localAudio, #remoteAudio { | |
display: none; | |
} | |
#status { | |
margin: 20px 0; | |
font-weight: bold; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Audio Call App</h1> | |
<div id="status">Ready to connect</div> | |
<button id="callButton">Start Call</button> | |
<button id="hangupButton" disabled>End Call</button> | |
<audio id="localAudio" autoplay muted></audio> | |
<audio id="remoteAudio" autoplay></audio> | |
</div> | |
<script> | |
let localStream; | |
let peerConnection; | |
const configuration = { | |
iceServers: [ | |
{ urls: 'stun:stun.l.google.com:19302' } | |
] | |
}; | |
const callButton = document.getElementById('callButton'); | |
const hangupButton = document.getElementById('hangupButton'); | |
const statusDiv = document.getElementById('status'); | |
// Initialize WebRTC | |
async function startCall() { | |
try { | |
// Get local audio stream | |
localStream = await navigator.mediaDevices.getUserMedia({ audio: true }); | |
document.getElementById('localAudio').srcObject = localStream; | |
// Create peer connection | |
peerConnection = new RTCPeerConnection(configuration); | |
// Add local stream to peer connection | |
localStream.getTracks().forEach(track => { | |
peerConnection.addTrack(track, localStream); | |
}); | |
// Handle incoming audio stream | |
peerConnection.ontrack = (event) => { | |
document.getElementById('remoteAudio').srcObject = event.streams[0]; | |
}; | |
// Create and send offer | |
const offer = await peerConnection.createOffer(); | |
await peerConnection.setLocalDescription(offer); | |
// Here you would typically send the offer to the other peer through your signaling server | |
statusDiv.textContent = "Offer created: " + JSON.stringify(offer); | |
callButton.disabled = true; | |
hangupButton.disabled = false; | |
} catch (err) { | |
console.error('Error starting call:', err); | |
statusDiv.textContent = "Error starting call: " + err.message; | |
} | |
} | |
function hangup() { | |
if (localStream) { | |
localStream.getTracks().forEach(track => track.stop()); | |
} | |
if (peerConnection) { | |
peerConnection.close(); | |
} | |
callButton.disabled = false; | |
hangupButton.disabled = true; | |
statusDiv.textContent = "Call ended"; | |
} | |
callButton.addEventListener('click', startCall); | |
hangupButton.addEventListener('click', hangup); | |
</script> | |
</body> | |
</html> |