AFK detection disconnects inactive viewers to free up workers. The timeout is a project-level setting — applied to every session whether the viewer connects via the share link, an iframe, or the Web SDK. See Session rules for the dashboard configuration.
What the SDK adds is runtime hooks: events you can listen for to render a custom warning UI before the disconnect, or override the default timeout for SDK-based sessions.
Video tutorial
Configuration
Set the timeout duration in seconds (1-7200):
await StreamPixelApplication({
appId: 'your-project-id',
afktimeout: 120, // 2 minutes
});
How it works
- The SDK monitors user input (mouse, keyboard, touch, gamepad)
- After
afktimeout seconds of inactivity, a warning is shown
- If the user interacts during the warning countdown, the timer resets
- If the countdown reaches zero, the stream disconnects
Events
afkWarningActivate
Fires when the AFK warning should be displayed. Provides a countdown value and a dismiss function.
pixelStreaming.addEventListener('afkWarningActivate', (e) => {
const countdown = e.data.countDown; // Seconds remaining
const dismiss = e.data.dismissAfk; // Call this to dismiss the warning
showAfkWarning(countdown, dismiss);
});
The dismissAfk callback from the afkWarningActivate event is the key to resetting the AFK timer. Call it when the user confirms they are still active (e.g., clicks an “I’m still here” button) to dismiss the warning and restart the idle countdown.
afkWarningUpdate
Fires every second during the countdown with the updated value.
pixelStreaming.addEventListener('afkWarningUpdate', (e) => {
updateCountdown(e.data.countDown);
});
afkWarningDeactivate
Fires when the user interacts during the warning, dismissing it.
pixelStreaming.addEventListener('afkWarningDeactivate', () => {
hideAfkWarning();
});
afkTimedOut
Fires when the countdown reaches zero and the session ends.
pixelStreaming.addEventListener('afkTimedOut', () => {
hideAfkWarning();
showMessage('Session ended due to inactivity.');
});
Custom AFK overlay
The SDK includes a default AFK overlay. To replace it with your own, hide the default and use the events above:
/* Hide the default AFK overlay */
#afkOverlay {
display: none !important;
}
You can hide the SDK’s built-in AFK overlay with #afkOverlay { display: none !important; } in your CSS and build a fully custom overlay using the AFK events listed above.
Full example
let dismissAfk = null;
pixelStreaming.addEventListener('afkWarningActivate', (e) => {
dismissAfk = e.data.dismissAfk;
document.getElementById('afk-overlay').style.display = 'flex';
document.getElementById('afk-countdown').textContent = e.data.countDown + 's';
});
pixelStreaming.addEventListener('afkWarningUpdate', (e) => {
document.getElementById('afk-countdown').textContent = e.data.countDown + 's';
});
pixelStreaming.addEventListener('afkWarningDeactivate', () => {
document.getElementById('afk-overlay').style.display = 'none';
dismissAfk = null;
});
pixelStreaming.addEventListener('afkTimedOut', () => {
document.getElementById('afk-overlay').style.display = 'none';
dismissAfk = null;
alert('You were disconnected due to inactivity.');
});
// "I'm still here" button
document.getElementById('afk-dismiss-btn').addEventListener('click', () => {
if (dismissAfk) dismissAfk();
});
Next steps
Queue system
Show waiting users their position when all UE instances are busy.
Reconnection
Recover from unexpected WebSocket drops automatically.