Putting an Eagle 3D Streaming stream inside your own website. There are three ways to do it, they differ in how much you build rather than in what you can have, and choosing is the first thing to do — so it is what this page is for.
Streaming URL
AvailableNothing to build. Copy the streaming URL from your application in the Control Panel and send it to whoever needs it.
https://connector.eagle3dstreaming.com/v5/YOURNAME/YourApp/default
iframe
AvailableOne tag on a page you host, so the viewer sees your address. allowfullscreen is required if you ever want fullscreen, and allow matters if your app uses the microphone or camera.
<iframe id="e3ds"
src="https://connector.eagle3dstreaming.com/v5/YOURNAME/YourApp/default"
allow="camera;microphone" allowfullscreen
width="100%" height="100%"></iframe>
SDK
AvailableThe player renders into an element on your own page. Request a short-lived token, then hand it to main(). Full setup in the SDK guide.
<div id="playerUI"></div>
const tokenData = await requestSessionToken();
const result = e3ds_controller.main(tokenData);
if (result && result.ok === false) showYourOwnError(result.message);
Streaming URL
Not applicableThere is no page of yours to send from. Anything your app needs has to come from inside it. If the surrounding page must tell the app something, that is the reason to move to an iframe — a plain link has no page to send from.
iframe
AvailablePost a message to the frame. Two things are required, and getting either wrong fails silently — no error, no warning. The message must be a string: wrap it in JSON.stringify, because a plain object is dropped. And it must carry cmd: "sendDataToUE", exactly. (A message with a Type field is also passed straight to your app.) If data is not arriving in your app, check these two first.
document.getElementById("e3ds").contentWindow.postMessage(
JSON.stringify({ cmd: "sendDataToUE", value: { Character: "Aurora" } }), "*");
SDK
AvailableOne call. sendToUnreal is the same function under a second name.
e3ds_controller.sendDataToUE({ Character: "Aurora" });
Streaming URL
Not applicableYour app can send, but there is no page of yours listening. The Unreal half is identical in all three methods — a Pixel Streaming Input component and a Send Pixel Streaming Response node — so this works the moment you host a page.
iframe
AvailableWhat your Blueprint sent arrives as an ordinary message from the frame.
window.addEventListener("message", function (event) {
console.log("From Unreal:", event.data);
});
SDK
AvailableA callback. Assign it before the stream starts — one registered late has already missed whatever arrived first.
e3ds_controller.callbacks.onResponseFromUnreal = function (descriptor) {
console.log("From Unreal:", descriptor);
};
Streaming URL
AvailableSwitch on Fullscreen Button on the UI tab of your configuration and the player shows one. Nothing to write — what it does on each device. Not yet in effect: the switch is in the Control Panel, but the current production player does not read it yet.
iframe
AvailableThere is no fullscreen message to send the frame. Instead put your own button on your page and call the browser's own Fullscreen API on the iframe element. The iframe must carry allowfullscreen or nothing happens.
document.getElementById("e3ds").requestFullscreen();
Features API › Fullscreen: every way to call it, with demos.
SDK
AvailableOne call, and it handles the platform differences — including iOS, where only the video element can go fullscreen.
e3ds_controller.toggleFullscreen();
Features API › Fullscreen: every way to call it, with demos.
Streaming URL
AvailableYour logo, loading background, queue screen and play button are all configuration settings — see the loading screen and branding. This is the whole of the customisation available here, and for many apps it is enough.
iframe
AvailableThe same configuration settings apply, since the frame is showing the same player. You also get a second layer: your own page around the frame, so a loading state of your own can sit over or beside it until the stream appears.
SDK
AvailableThe configuration settings still apply, and you can replace the experience outright: the progress callbacks let you build your own loading screen and show real progress rather than a spinner.
e3ds_controller.callbacks.onReceivingAppStartingProgress = function (percent) {
myLoadingBar.style.width = percent + "%";
};
Streaming URL
AvailableThe stream follows the size of the window, which is usually what you want. On a phone that means a smaller frame and a softer picture — correct behaviour, not a fault. To hold one size instead, set Browser Resolution to Custom, with a width and height, on the Common tab of your configuration.
iframe
AvailablePinning works. Releasing it back to following the window has no iframe command — reload the frame to undo it.
post({ cmd: "freezeResolutionAt", x: 1920, y: 1080 });
SDK
AvailableUse these rather than sending a raw Resolution command. A raw command does change the picture — then a few seconds later the viewport watcher sends the window size again and your change is gone. Only these calls turn that watcher off.
e3ds_controller.setResolution(1920, 1080);
e3ds_controller.useViewportResolution(); // back to following the window
Streaming URL
AvailableThe player's own settings panel carries a quality control. The viewer chooses; you do not.
iframe
AvailableA named level is the simplest: low, medium, high or ultra. A fixed point holds one quantisation value. Adaptive lets the stream move between a minimum and a maximum — the best picture the connection can carry at that moment.
post({ cmd: "setVideoDetailLevel", value: "high" });
post({ cmd: "setQualityPoint", value: 20 });
post({ cmd: "setAdaptiveQualityPoint", minValue: 20, maxValue: 40 });
Adaptive does not take effect yet from an iframe on the current production player. Use a named level or a fixed point, or the SDK, until it does.
SDK
AvailableThe same choices as the iframe, as direct calls. A fixed point holds one setting whatever the connection does, which is what you want when the picture has to be predictable — a product shot, a screenshot people will keep. Adaptive gives the best picture the connection can carry moment to moment, which is what you want for everything else.
e3ds_controller.setVideoDetailLevel("high");
e3ds_controller.setQualityPoint(20);
e3ds_controller.setAdaptiveQualityPoint(20, 40); // minimum, maximum
Streaming URL
AvailableMouse scheme and touch input are configuration settings. They apply for the whole session and cannot be changed while it runs.
iframe
AvailableChangeable at runtime. Hovering leaves the cursor free, which suits configurators; locked captures the pointer for camera control. The keyboard commands let a button on your page act as a key press — useful on a touch device with no keyboard.
post({ cmd: "switchMouseControlSchemeTo", value: scheme });
post({ cmd: "setTouchInputEnabled", value: true });
post({ cmd: "emulateKeyboardKeyPress", value: key });
post({ cmd: "emulateKeyboardKeyDown", value: key }); // hold, e.g. movement
post({ cmd: "emulateKeyboardKeyUp", value: key });
Features API › Mouse mode: locked or hovering: every way to call it, with demos.
SDK
AvailableKeyboard emulation has no SDK equivalent, because a page using the SDK can send real key events to the player.
e3ds_controller.switchMouseControlSchemeTo(scheme);
e3ds_controller.setTouchInputEnabled(true);
Features API › Mouse mode: locked or hovering: every way to call it, with demos.
Streaming URL
AvailableThe player's own interface carries a volume control the viewer can use. Note that every stream starts muted until the viewer interacts with the page — that is the browser's rule, not Eagle 3D Streaming's.
iframe
ComingNot built yet. Today there is no volume command, and your page cannot reach the video element inside the frame because it is on the Eagle 3D Streaming website and the browser blocks it.
Until it lands: send your app a value and change the sound inside Unreal — that controls the game's audio rather than the stream's — or use the SDK, where setVolume() already exists.
Features API › Volume: every way to call it, with demos.
SDK
AvailableOne call, so the volume control can live in your own interface rather than the player's. It changes the stream's audio, which is the difference from sending a value into Unreal — that would change the game's own mix and every viewer would hear it.
Remember the stream starts muted until the viewer interacts with the page. Setting a volume before that happens does not unmute it; the browser is holding the audio, not the player.
e3ds_controller.setVolume(level);
Features API › Volume: every way to call it, with demos.
Streaming URL
AvailableAdd the E3DS capture ScreenShot node from the E3DS Features plugin and trigger it in your Blueprint. This works in all three methods because the trigger is inside your app; the player then saves the frame the viewer is seeing — see screenshots.
iframe
ComingA screenshot command for the frame is not built yet.
Until it lands: the Blueprint route above works today and needs nothing else, so the feature is reachable now — the trigger just lives inside your app rather than on your page.
SDK
AvailableCaptures the frame the viewer is seeing, from the video in the page, and downloads it. The plugin's capture node does the same, triggered from inside your app.
e3ds_controller.captureScreenShot();
Streaming URL
Not applicableThe session starts when the page is opened and ends on the rules in your configuration — idle timeout, session limit. There is nothing outside it to start or stop it from.
iframe
ComingA terminate command is not built yet.
Until it lands: setting src again is the nearest thing to a restart, and a session you want gone ends on the configuration's idle timeout rather than on your say-so.
Features API › End the session: every way to call it, with demos.
SDK
AvailableFetch the token before ending the session, so a failed request leaves the viewer with the stream they already had. Then call main() again: it ends the running session itself before starting the new one.
async function restartStream() {
const tokenData = await requestSessionToken();
if (!tokenData) return; // the current stream carries on
e3ds_controller.main(tokenData);
}
Features API › End the session: every way to call it, with demos.
Streaming URL
Not applicableAnyone with the link. You can add a password or restrict a link in the configuration — see sessions and access — but the link itself is what grants access, and you cannot revoke it for one person.
iframe
Not applicableThe same. Your page can require a login before it shows the frame, but the streaming URL inside is still a working link to anyone who reads your page source.
SDK
AvailableThis is the real reason to choose the SDK. The session starts from a short-lived token, so your backend decides who gets one, when, and for which app. Keep the API key there and the browser never holds anything reusable.
Streaming URL
Not applicableThere is no page of yours to put a login on. The link goes straight to the Eagle 3D Streaming player, so the only gate available is the one the platform provides: a password on the link, the same password for everyone.
That tells you nothing about who is watching, and it cannot be revoked for one person. If you need to know your viewer, that is the reason to move to a hosted method.
iframe
AvailableYour page, your login: authenticate however you already do, and render the <iframe> only for a signed-in visitor.
SDK
AvailableThe same login, and this time it holds: being signed in is what gets a token, not just what reveals the player — and your server can refuse.
Check the session, the subscription, a seat limit, anything you like, and decline. A copied token is worth one session and expires in about a minute, so there is nothing durable to leak. This is the difference the iframe cannot close — see keeping your API key off the browser.
Streaming URL
AvailableThe Eagle 3D Streaming player shows the startup phases and, when a session ends, the reason. You can restyle that screen but not receive the events.
The loading screen covers what is adjustable.
iframe
AvailableThe frame posts events to your page with postMessage. Match on type:
stage1_inqueued waiting for a machine (carries positionInQueue)
stage4_playBtnShowedUp ready; waiting for the viewer's click
stage5_playBtnPressed the stream is starting
sessionEnding the session is ending (message: the reason, for a person)
sessionExpired the time limit was reached
The SDK gives the same moments as callbacks, plus progress percentages.
SDK
AvailableProgress callbacks for your own loading screen, onDataChannelOpen when the stream is live, and onSessionEnding for any reason it ends.
All eleven are in the SDK reference, and why a session ended lists every message the last one can deliver — kicked, session expired, app crashed, and the rest.
Scripting is off, so every combination is listed above rather than one at a time.
Click through a few topics and the pattern shows itself: the same feature is reachable in all three, by different means. What actually differs is how much you build, and how much of the session you control — not what you are allowed to have.
| Streaming URL | iframe | SDK | |
|---|---|---|---|
| What you build | Nothing | One HTML page | A page, plus a token endpoint for production |
| Address the viewer sees | Eagle 3D Streaming's | Yours | Yours |
| Your own interface around the stream | No | Yes | Yes |
| Needs an API key | No | No | Yes — keep it server-side |
| Who may start a session | Anyone with the link | Anyone with the link | Whoever your server issues a token to |
| Control over the session | None | Reload the frame | Start, restart, end, react to every stage |
| Volume and screenshots from your page | Built-in controls | Coming — workarounds today | Yes |
The sample project, the one file you edit, and getting your key off the browser.
Last updated