Created
April 3, 2025 14:30
-
-
Save recursivecodes/6f894ce2e18061dda49216a612ef48e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Amazon IVS Broadcaster</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
.video-container { | |
margin-bottom: 20px; | |
} | |
#local-video { | |
width: 100%; | |
background-color: #000; | |
} | |
.control-panel { | |
display: flex; | |
gap: 10px; | |
margin-bottom: 20px; | |
} | |
button { | |
padding: 10px 15px; | |
cursor: pointer; | |
} | |
.streaming { | |
background-color: #ff4d4d; | |
} | |
.status { | |
padding: 10px; | |
border-radius: 5px; | |
margin-top: 10px; | |
} | |
.error { | |
background-color: #ffcccc; | |
} | |
.success { | |
background-color: #ccffcc; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Amazon IVS Broadcaster</h1> | |
<div class="video-container"> | |
<video id="local-video" autoplay muted playsinline></video> | |
</div> | |
<div class="control-panel"> | |
<button id="start-camera">Start Camera</button> | |
<button id="start-stream" disabled>Start Streaming</button> | |
<button id="stop-stream" disabled>Stop Streaming</button> | |
</div> | |
<div> | |
<h3>Stream Settings</h3> | |
<div> | |
<label for="ingest-url">Ingest Server URL:</label> | |
<input type="text" id="ingest-url" placeholder="rtmps://..." size="50"> | |
</div> | |
<div> | |
<label for="stream-key">Stream Key:</label> | |
<input type="password" id="stream-key" placeholder="Your IVS stream key" size="50"> | |
</div> | |
</div> | |
<div id="status-message" class="status"></div> | |
<!-- Amazon IVS Web Broadcast SDK --> | |
<script src="https://web-broadcast.live-video.net/1.4.0/amazon-ivs-web-broadcast.js"></script> | |
<script> | |
const startCameraButton = document.getElementById('start-camera'); | |
const startStreamButton = document.getElementById('start-stream'); | |
const stopStreamButton = document.getElementById('stop-stream'); | |
const localVideo = document.getElementById('local-video'); | |
const ingestUrlInput = document.getElementById('ingest-url'); | |
const streamKeyInput = document.getElementById('stream-key'); | |
const statusMessage = document.getElementById('status-message'); | |
// Stream configuration | |
const streamConfig = { | |
maxResolution: { | |
width: 1280, | |
height: 720, | |
}, | |
maxFramerate: 30, | |
maxBitrate: 2500000, | |
}; | |
let client; | |
let streamSession; | |
let cameraStream; | |
// Check if the browser supports the IVS Web Broadcast SDK | |
if (!IVSBroadcastClient.isSupported) { | |
updateStatus("Browser is not supported for IVS broadcasting", true); | |
} | |
// Start camera and microphone | |
startCameraButton.addEventListener('click', async () => { | |
try { | |
// Initialize the IVS Broadcast client | |
client = IVSBroadcastClient.create({ | |
streamConfig: streamConfig, | |
ingestEndpoint: "", // Will be set when starting the stream | |
}); | |
// Get camera and microphone permissions | |
cameraStream = await navigator.mediaDevices.getUserMedia({ | |
video: true, | |
audio: true | |
}); | |
// Display the camera preview | |
localVideo.srcObject = cameraStream; | |
// Add camera and microphone to the client | |
const devices = await client.getDevices(); | |
// Add the video device | |
await client.addVideoInputDevice(cameraStream, 'camera', { index: 0 }); | |
// Add the audio device | |
await client.addAudioInputDevice(cameraStream, 'microphone'); | |
updateStatus("Camera started successfully. Ready to stream.", false); | |
startStreamButton.disabled = false; | |
startCameraButton.disabled = true; | |
} catch (error) { | |
updateStatus(`Error starting camera: ${error.message}`, true); | |
} | |
}); | |
// Start streaming | |
startStreamButton.addEventListener('click', async () => { | |
const ingestUrl = ingestUrlInput.value.trim(); | |
const streamKey = streamKeyInput.value.trim(); | |
if (!ingestUrl || !streamKey) { | |
updateStatus("Please enter both ingest URL and stream key", true); | |
return; | |
} | |
try { | |
client.ingestEndpoint = ingestUrl; | |
// Create a stream session | |
streamSession = client.createStreamSession({ | |
ingestEndpoint: ingestUrl, | |
streamKey: streamKey | |
}); | |
// Listen for stream status events | |
streamSession.addEventListener('error', (event) => { | |
updateStatus(`Stream error: ${event.detail}`, true); | |
}); | |
streamSession.addEventListener('connectionStateChange', (state) => { | |
updateStatus(`Stream state: ${state}`, false); | |
}); | |
// Start the stream | |
await streamSession.start(); | |
updateStatus("Streaming started...", false); | |
startStreamButton.disabled = true; | |
stopStreamButton.disabled = false; | |
startStreamButton.classList.add('streaming'); | |
} catch (error) { | |
updateStatus(`Error starting stream: ${error.message}`, true); | |
} | |
}); | |
// Stop streaming | |
stopStreamButton.addEventListener('click', async () => { | |
try { | |
if (streamSession) { | |
await streamSession.stop(); | |
streamSession = null; | |
} | |
updateStatus("Stream stopped", false); | |
startStreamButton.disabled = false; | |
stopStreamButton.disabled = true; | |
startStreamButton.classList.remove('streaming'); | |
} catch (error) { | |
updateStatus(`Error stopping stream: ${error.message}`, true); | |
} | |
}); | |
// Update status message | |
function updateStatus(message, isError) { | |
statusMessage.textContent = message; | |
statusMessage.className = isError ? 'status error' : 'status success'; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment