The live connection state (stream statistics) is the live view of how well the video is reaching a viewer in an Eagle 3D Streaming session: round trip, lost packets, jitter, bitrate, frame rate and picture size. It is measured on the real path between the viewer and the streaming machine, from the moment the video starts, and your page receives the numbers every 5 seconds. What counts as good is your decision: your page reads the numbers and applies its own rules.
| Where | How you get it | When |
|---|---|---|
| Streaming page | the Info button on the stream's settings bar | while the video plays, updated live |
| iframe | the message {type: "connection.stats", ...} sent to your page | from the first video frame, every 5 seconds |
| Web SDK | the callback e3ds_controller.callbacks.onConnectionStats | from the first video frame, every 5 seconds |
Only after the video starts. The numbers come from the video itself, so there is nothing to report before the first frame. To check a connection before that, see Connection speed and health.
On the Eagle 3D Streaming page itself, open the settings bar and press Info. The panel shows the network round trip, data received, resolution, frame rate, codec and bitrate, updated while the video plays. Nothing to set up. See the settings bar.
Embed the stream as described in Embed with an iframe, then listen for the message on your page:
window.addEventListener("message", function (e) {
if (e.data && e.data.type === "connection.stats") {
showQuality(e.data); // the numbers: rttMs, fps, packetLossPercent, ...
}
});
How often: every 5 seconds by default. To change it, send the frame a command with a number of seconds from 1 to 60, or 0 to stop:
document.getElementById("e3ds").contentWindow.postMessage(
JSON.stringify({ cmd: "setConnectionStatsInterval", seconds: 2 }), "*");
Set up the page as described in Embed with the Web SDK, then add the callback:
e3ds_controller.callbacks.onConnectionStats = function (stats) {
showQuality(stats); // the same numbers as in the iframe
};
How often: every 5 seconds by default. To change it (1 to 60 seconds, or 0 to stop):
e3ds_controller.setConnectionStatsInterval(2);
Does a shorter interval cost anything? No noticeable cost. Nothing extra is sent to your Unreal app, so it has no extra work. The reports reuse numbers the browser already collects about once a second, so a report every 2 seconds instead of 5 adds only a small message to your page.
Every report carries the same fields, for example:
{ "type": "connection.stats", "rttMs": 48, "packetLossPercent": 0.2, "jitterMs": 3,
"bitrateKbps": 6200, "fps": 60, "framesDropped": 0, "resolution": "1920x1080", "intervalSeconds": 5, "time": "2026-10-14T13:39:34.849Z" }
| field | what it is | what to look for |
|---|---|---|
rttMs | Round trip between the viewer and the streaming machine, in milliseconds: how long a click takes to reach the app and its result to come back. | Under 100 feels instant. Over 250 is noticeably slow to respond. |
packetLossPercent | Video packets lost since the previous report, in percent. null on the first report. | Up to 1% is normal. Over 5% shows as stutter or blur. |
jitterMs | How unevenly the packets arrive, in milliseconds. | A few milliseconds is normal. Tens of milliseconds means an unsteady connection. |
bitrateKbps | Video received right now, in kilobits per second. | It follows the picture: a still scene needs much less than a moving one, so a low value alone is not a problem. |
fps | Frames per second the viewer sees. | 25 or more is smooth. Under 15 looks choppy. |
framesDropped | Frames the viewer's browser dropped since the previous report. | Steady drops point at the viewer's device, not the connection. |
resolution | The picture size shown, for example 1920x1080. | |
intervalSeconds | How often reports are coming. | |
time | When this report was made. |
A number the viewer's browser did not report is null.
The numbers describe two separate experiences, and one can be poor while the other is good. A poor round trip does not mean a poor picture: it means the viewer's keyboard, mouse and touch input reach the app late, so the app feels slow to react, even if the picture looks sharp. A poor picture (blurry, choppy) can happen on a connection that responds instantly.
| field | good | fair | poor | what poor feels like |
|---|---|---|---|---|
rttMs | up to 100 | 101 to 250 | over 250 | a click or key press shows its result a quarter of a second or more later; the camera trails the mouse |
jitterMs | up to 20 | 21 to 50 | over 50 | response is uneven: sometimes quick, sometimes late |
| field | good | fair | poor | what poor looks like |
|---|---|---|---|---|
fps | 25 or more | 15 to 24 | under 15 | choppy movement |
packetLossPercent | up to 1 | 1 to 5 | over 5 | blocky patches, short freezes |
framesDropped (per report) | 0 to 5 | 6 to 30 | over 30 | stutter caused by the viewer's device, not the connection |
bitrateKbps, at 1920x1080 in a moving scene | 4000 or more | 1500 to 4000 | under 1500 | soft, smeared detail. A still scene needs far less, so judge it only while the picture moves |
resolution tells you the picture size these numbers apply to; a smaller
window needs proportionally less bitrate for the same sharpness.
Eagle 3D Streaming sends the numbers, not a verdict: what is good depends on your app (a walkthrough tolerates more delay than a game). Start from these samples and change the limits to suit your app. They use the values from the two tables above.
// Response: how fast the app reacts to keyboard, mouse and touch
function responseRating(s) {
if (s.rttMs === null) return "unknown";
if (s.rttMs <= 100) return "good";
if (s.rttMs <= 250) return "fair";
return "poor";
}
// Picture: how the video looks and moves
function pictureRating(s) {
var loss = s.packetLossPercent || 0;
if ((s.fps !== null && s.fps < 15) || loss > 5) return "poor";
if ((s.fps === null || s.fps >= 25) && loss <= 1) return "good";
return "fair";
}
Two separate results let you tell the viewer the right thing: "slow to respond" (response) is a different problem from "low picture quality" (picture).
| What you see | Why | What to do |
|---|---|---|
| No reports at all | The video has not started yet, or the interval was set to 0. | Reports start with the first frame. Send a new interval (1 to 60) to restart them. |
| iframe: reports never reach your listener | The listener is on a different window, or filters the wrong field. | Listen on your page's own window and check e.data.type === "connection.stats". |
Some fields are null | That browser does not report the number (Safari reports fewer). | Treat null as unknown in your own rules. |
| You need other numbers | Ask support (Email / Discord). |
The other features, each with the same ways to use it.
Last updated