(function () { 'use strict'; var MAX_DEMO_S = 300; var timer = null; var secondsLeft = MAX_DEMO_S; var mediaStream = null; var sessionId = ''; var webrtc = null; function basePath() { return document.body.getAttribute('data-base-path') || ''; } function el(id) { return document.getElementById(id); } function detectPlatform() { var ua = navigator.userAgent || ''; if (/Firefox\//i.test(ua)) return 'firefox'; if (/Edg\//i.test(ua)) return 'edge'; if (/Chrome\//i.test(ua)) return 'chrome'; if (/Safari\//i.test(ua)) return 'safari'; return 'desktop'; } function apiUrl() { return basePath() + '/api/live_cast.php'; } function postJson(body, cb) { var xhr = new XMLHttpRequest(); xhr.open('POST', apiUrl(), true); xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); xhr.onload = function () { var payload = null; try { payload = JSON.parse(xhr.responseText); } catch (e) { cb(null); return; } cb(payload); }; xhr.onerror = function () { cb(null); }; xhr.send(JSON.stringify(body)); } function setStatus(text) { var node = el('edu-status'); if (node) node.textContent = text; } function updateTimer() { var node = el('edu-timer'); if (!node) return; var m = Math.floor(secondsLeft / 60); var s = secondsLeft % 60; node.textContent = m + ':' + (s < 10 ? '0' : '') + s; } function renderShare(session) { var box = el('edu-share'); if (!box || !session) return; var joinUrl = session.join_short_url || ''; var qrUrl = session.join_qr_url || ''; var longJoin = basePath() + '/live/join?session_id=' + encodeURIComponent(session.session_id || sessionId); if (!joinUrl) joinUrl = longJoin; var html = '

Share this demo

Viewers open this link in another browser (same LAN or online).

'; html += '

' + joinUrl + '

'; if (qrUrl) { html += '
Viewer QR code
Scan to open viewer page
'; } box.hidden = false; box.innerHTML = html; } function stopDemo() { if (timer) { clearInterval(timer); timer = null; } if (webrtc) { webrtc.stop(); webrtc = null; } if (mediaStream) { mediaStream.getTracks().forEach(function (t) { t.stop(); }); mediaStream = null; } var preview = el('edu-preview'); if (preview) preview.srcObject = null; if (sessionId) { postJson({ action: 'heartbeat', session_id: sessionId, status: 'ended' }, function () {}); sessionId = ''; } var share = el('edu-share'); if (share) share.hidden = true; el('edu-start').disabled = false; el('edu-stop').disabled = true; setStatus('Demo ended. Thanks for trying AndroidCast education mode.'); } function startWebRtc() { if (!window.LiveCastWebRtc || !sessionId || !mediaStream) return; webrtc = window.LiveCastWebRtc.connect({ basePath: basePath(), sessionId: sessionId, role: 'caster', localStream: mediaStream, onStatus: setStatus, onStats: function (stats) { var nerds = el('edu-stats'); if (!nerds) return; nerds.hidden = false; nerds.textContent = 'Stats: ICE ' + (stats.ice_state || '—') + ' · out ' + (stats.outbound_kbps || 0) + ' kbps' + ' · RTT ' + (stats.rtt_ms || 0) + ' ms'; } }); } function startDemo() { if (!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) { setStatus('Screen sharing is not supported in this browser.'); return; } if (!window.RTCPeerConnection) { setStatus('WebRTC is not available in this browser.'); return; } setStatus('Requesting screen share permission…'); navigator.mediaDevices.getDisplayMedia({ video: true, audio: false }) .then(function (stream) { mediaStream = stream; var preview = el('edu-preview'); if (preview) { preview.hidden = false; preview.srcObject = stream; preview.play().catch(function () {}); } stream.getVideoTracks()[0].addEventListener('ended', stopDemo); setStatus('Creating demo session…'); postJson({ action: 'create_intent', platform: 'education_' + detectPlatform(), max_duration_s: MAX_DEMO_S, codec_video: 'browser_screen', codec_audio: 'none', bw_mode: 'demo' }, function (resp) { if (!resp || !resp.ok || !resp.session) { setStatus('Could not register demo session. Try again later.'); stopDemo(); return; } sessionId = resp.session.session_id || ''; renderShare(resp.session); startWebRtc(); secondsLeft = MAX_DEMO_S; updateTimer(); el('edu-start').disabled = true; el('edu-stop').disabled = false; setStatus('Live demo — share the link so others can watch.'); timer = setInterval(function () { secondsLeft -= 1; updateTimer(); if (secondsLeft <= 0) { stopDemo(); } }, 1000); if (window.AndroidCastAnalytics && window.AndroidCastAnalytics.trackEvent) { window.AndroidCastAnalytics.trackEvent('live_education_start', { platform: detectPlatform() }); } }); }) .catch(function () { setStatus('Screen share permission denied or cancelled.'); }); } function boot() { if (!el('live-education-app')) return; updateTimer(); var startBtn = el('edu-start'); var stopBtn = el('edu-stop'); if (startBtn) startBtn.addEventListener('click', startDemo); if (stopBtn) { stopBtn.disabled = true; stopBtn.addEventListener('click', stopDemo); } var notifBtn = el('edu-notify'); if (notifBtn && 'Notification' in window) { notifBtn.addEventListener('click', function () { Notification.requestPermission().then(function (perm) { setStatus(perm === 'granted' ? 'Notifications enabled.' : 'Notifications not granted.'); }); }); } else if (notifBtn) { notifBtn.hidden = true; } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); } })();