The stage is how a viewer becomes a co-host mid-stream and back again,
like Agora's setClientRole. Viewers raise a hand. Your backend invites,
promotes and demotes. The viewer's app switches roles without a gap.
Where this fits: hosts and viewers already join with credentials your
backend mints (Hosts & co-hosts). The stage adds
three server calls and one client call, switchRole().
The flow
-
A viewer raises a hand. On the device:
await live.raiseHand();Every client in the stream sees a
stageevent withaction: 'raise_hand'and the viewer'sidentity. Your host UI lists them. A viewer retracts it withawait live.lowerHand();, which sends the matchinglower_handevent. -
Your backend invites or promotes. An invite only announces. Promote registers the viewer as a co-host and returns host credentials:
await livqeno.liveStreams.stage.invite(stream.id, 'viewer-42'); const hostCredential = await livqeno.liveStreams.stage.promote(stream.id, 'viewer-42');livqeno.live_streams.invite_to_stage(stream["id"], "viewer-42") host_credential = livqeno.live_streams.promote_to_stage(stream["id"], "viewer-42") -
The viewer switches. Send
hostCredentialto that viewer's app:await live.switchRole(hostCredential); await live.room.enableCamera(); await live.room.enableMicrophone();switchRole()joins the stream's room as a co-host before leaving wherever the viewer was watching from (an edge room, or HLS). Their picture never drops.live.roomchanges, so listen forroleChangedrather than holding on to the old room. -
Take them off stage when you're done:
await livqeno.liveStreams.stage.demote(stream.id, 'viewer-42');Their publishing stops at once. Their app gets a
demotedstage event. Mint them a viewer token and callswitchRole()again to keep them watching.
Stage events
live.on('stage', (event) => {
// event.action: 'raise_hand' | 'lower_hand' | 'invited' | 'promoted' | 'demoted'
// event.identity: who it's about; event.forMe: whether that's you
});invited, promoted and demoted are only ever sent by Livqeno itself, so
a viewer can't fake an invite. raise_hand and lower_hand come from the
viewer named. The same events are delivered as webhooks
(live_stream.stage_invited, live_stream.stage_promoted,
live_stream.stage_demoted). See the Event catalogue.
The stream's HOST can't be demoted. A stream always has one; end the stream
instead.