<!DOCTYPE html>
<html>
<head>
<title>AgentHuman WebRTC Avatar</title>
</head>
<body>
<video id="avatar-video" autoplay playsinline></video>
<button id="send-audio">Send Audio</button>
<script>
const ws = new WebSocket('wss://api.agenthuman.com/webrtc');
let pc = null;
let sessionId = null;
ws.onmessage = async (event) => {
const message = JSON.parse(event.data);
if (message.type === 'connection.established') {
sessionId = message.session_id;
console.log('Connected with session:', sessionId);
await setupWebRTC();
} else if (message.type === 'webrtc.answer') {
await handleAnswer(message);
} else if (message.type === 'webrtc.ice_candidate') {
await handleIceCandidate(message);
}
};
async function setupWebRTC() {
pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.ontrack = (event) => {
document.getElementById('avatar-video').srcObject = event.streams[0];
};
pc.onicecandidate = (event) => {
if (event.candidate) {
ws.send(JSON.stringify({
type: 'webrtc.ice_candidate',
session_id: sessionId,
candidate: {
candidate: event.candidate.candidate,
sdpMid: event.candidate.sdpMid,
sdpMLineIndex: event.candidate.sdpMLineIndex
}
}));
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
ws.send(JSON.stringify({
type: 'webrtc.offer',
session_id: sessionId,
sdp: offer.sdp
}));
}
async function handleAnswer(message) {
await pc.setRemoteDescription({
type: 'answer',
sdp: message.sdp
});
}
async function handleIceCandidate(message) {
await pc.addIceCandidate(message.candidate);
}
document.getElementById('send-audio').onclick = async () => {
const response = await fetch('sample-audio.wav');
const blob = await response.blob();
const reader = new FileReader();
reader.onload = () => {
const base64 = reader.result.split(',')[1];
ws.send(JSON.stringify({
type: 'agent.speak',
session_id: sessionId,
audio: base64,
format: 'wav',
sample_rate: 16000
}));
};
reader.readAsDataURL(blob);
};
</script>
</body>
</html>