inc.reactor.sdk.android.Reactor represents a client connection and its session. It implements
AutoCloseable. Calls that wait are suspend functions, and state is exposed as flows. See
Installation for the dependency and a complete example, and
the API reference for every
signature.
The snippets below run inside a coroutine with a Reactor reactor; command and media operations
need a connected session. Import SDK types from inc.reactor.sdk.android.
Create a client
BuildReactorOptions and pass it to the Reactor constructor. Creating a client does not connect
it.
The constructor’s second parameter,
dispatcher, sets where control events are delivered. It
defaults to Dispatchers.Main.immediate, so status and error collectors can update UI directly.
Frame handlers run separately; see Track.
apiUrl = "http://localhost:8080" and local = true. From an emulator, the
host machine is 10.0.2.2 rather than localhost.
Authentication
Usejwt in apps you distribute. During development, apiKey lets the client exchange the key for
a token on each connect(), scoped to the model it creates a session for, or to the session it
joins. A jwt you set takes priority, and the SDK never replaces it.
A trusted backend or tool can exchange its API key with Reactor.fetchJwt(apiUrl, apiKey). Without
options, the token grants everything the key allows. Pass a JSON scope to limit it:
sessions array instead of models. See Authentication
for token scope and expiry.
Session lifecycle
Model names are
owner/name. connect() returns once the connection is set up; wait for READY
before sending commands:
disconnect() before close() to end a session you created. A session joined by ID remains
available to its owner after you disconnect. To restore a connection on the same session, call
reconnect() without first calling disconnect(). Receiving tracks resume after connect and
reconnect. Sending tracks must be published again before pushing frames.
Cancelling a coroutine stops waiting for a call. It does not undo an operation already sent. See
Errors for handling failures.
Commands and schema
Use command names and arguments from the model’s API reference. Arguments are a JSON object as a string.requestSchema() returns the running model’s schema as a
Map<String, Any?>.
sendCommand(name) sends a command with no arguments. The call returns a
CommandReply. An empty reply means the model
acknowledged the command without returning a message; it is a successful result.
Upload files
Each returns a
FileRef. uploadContent and uploadStream
copy the stream to a cache file first, up to 64 MiB by default; pass maxBytes to change the limit.
Pass the uploaded file in uploads, keyed by the command’s parameter name:
set_image command accepting an image parameter. Give the
upload a name with the right extension: the MIME type is inferred from it, and a content URI’s own
name often has none. See File uploads.
Recordings
requestClip(durationSeconds) requests a recent window; requestRecording() requests the session
recording. Each returns a Clip once the
request is accepted. The media may not be ready yet. downloadClip waits for it and assembles a
playable file:
readyTimeoutSeconds bounds the wait beyond the clip’s predicted
ready time; by default it waits while the session can still produce the clip. Keep the session open
until the download completes. Closing the client while a download runs fails the call but does not
cancel the download; the file may still arrive. See Recordings.
Events
Collect them from a lifecycle-aware scope, for example
lifecycleScope.launch { reactor.errors.collect { … } }. Start collecting errors and messages
before connecting to see every one. messages carries each message the model sends as a
{"type", "data"} object, including the ones no call returns, such as state updates. A command’s
reply also arrives as the return value of sendCommand. runtimeMessages carries what the platform
sends about the session, such as recording lifecycle notices. Media is delivered on individual
tracks.
Stepped generation
A model that supports it can generate one step at a time instead of streaming. Setgeneration = Generation.STEPPED, then call step():
StepResult. Every
argument is optional: step() runs on the model’s current state. connect() fails when the model
cannot run a stepped session.
In a stepped session, Track.pushFrame buffers a frame for the next step instead of sending it.
clearStepInputs() drops what is buffered. Frame handlers are refused, because nothing streams.
Connection statistics
stats() returns a Stats snapshot of the connection.
droppedFrames counts received frames that arrived on a track with no handler.