(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 += '
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();
}
})();