Controlling the stream

Quality, resolution, fullscreen, mouse behaviour, sound and screenshots of an Eagle 3D Streaming stream — driven from your own interface rather than the default one. Each is shown for both the SDK and the iframe.

The pattern is the same throughout. With the SDK you call a function on e3ds_controller. With an iframe you post a JSON message carrying a cmd key to the frame:

document.getElementById("iframe_1")
  .contentWindow
  .postMessage(JSON.stringify({ cmd: "…", /* … */ }), "*");

Quality

Call
SDKe3ds_controller.setQualityPoint(n)
iframe{ cmd: "setQualityPoint", value: n }

There is also setAdaptiveQualityPoint in the SDK, which lets the stream move within a range rather than holding one setting. Use a fixed point when you want predictability, adaptive when you want the best picture the connection can carry at that moment.

Resolution

By default the stream follows the size of the frame or window. That is usually right, and on phones it has a consequence worth knowing: a smaller screen means a smaller frame, which means a lower stream resolution. The picture is correctly sized and looks softer than the same app on a desktop.

To hold a fixed resolution instead:

Pin itRelease it
SDK e3ds_controller.setResolution(1920, 1080) e3ds_controller.useViewportResolution()
iframe { cmd: "freezeResolutionAt", x: 1920, y: 1080 } { cmd: "useViewportResolution" }

Fullscreen

Three places this can be driven from, and they are not equivalent.

SDK

toggleFullscreen()

One call, and it handles the platform differences — including iOS, where only the video element can go fullscreen.

iframe

Use the browser's own Fullscreen API on your page, not a message to the frame — requestFullscreen() on the element you want enlarged. Give the iframe the allowfullscreen attribute or nothing will happen.

Blueprint

Not directly — Unreal cannot put a browser into fullscreen. What a Blueprint can do is send a message to your page (Send Pixel Streaming Response), and your page then makes one of the two calls above. Worth knowing when the trigger belongs to your scene rather than your interface.

Mouse behaviour

Call
SDKe3ds_controller.switchMouseControlSchemeTo(scheme)
iframe{ cmd: "switchMouseControlSchemeTo", value: scheme }

Two schemes. Hovering leaves the cursor free, which suits configurators and anything with an interface to click. Locked captures the pointer for camera control, which suits first-person movement and is what most games expect. Choose per app, or offer both.

Sending keys to the app

For an on-screen control that should behave like a key press — a touch-screen movement pad, an action button, a menu shortcut.

Whatiframe command
Press and release together{ cmd: "emulateKeyboardKeyPress", value: "M" }
Hold down{ cmd: "emulateKeyboardKeyDown", value: "W" }
Release{ cmd: "emulateKeyboardKeyUp", value: "W" }

Any single letter or digit works, as do Space, Enter, Escape, Tab, Backspace, Shift, Control, Alt and the four arrows. The reply is a keyEmulated event saying whether the key was recognised.

Press and hold are different things. Press is a down and an up together, which is what a menu or an action key wants. Hold leaves the key down until you release it, which is what movement wants — and a single button that does both cannot hold anything.

Sound, touch and screenshots

WhatSDK calliframe command
VolumesetVolume(level){ cmd: "setVolume", value: level }
Touch input on or offsetTouchInputEnabled(enabled){ cmd: "setTouchInputEnabled", value: enabled }
Capture a framecaptureScreenShot(){ cmd: "captureScreenShot" }
End the sessionterminate(){ cmd: "ForceEndSession" }
Which device is watching—{ cmd: "sendDeviceInfo" } — replies takeUserDeviceInfo, see Detect the viewer's device
Which app is streaming—{ cmd: "getAppInfo" }

Knowing what the stream is doing

The SDK reports progress and events by calling functions you assign. Every one is optional; the ones you do not define are never called.

CallbackWhen it fires
onDataChannelOpenThe stream is live and ready for your commands.
onResponseFromUnrealYour app sent something back to the page.
onSessionEndingAny reason the session is ending, with a line of text for the viewer.
onSessionExpiredThe session's time limit was reached.
onReceivingApp…ProgressAcquiring, preparing and starting, for your own loading screen.
Set stream quality from an iframeWatch on YouTube

Last updated