Skip to main content
Markdown

Live streams in Express

One person presents live to everyone watching: the picture, a chat beside it, reactions, and the count of who watches. The host goes live from the browser, a phone or OBS. Viewers may be signed in or not.

Who is who​

Your server declares streams as it declares rooms and calls, by pattern. The rule says who each person is in the stream:

// The show of the shop, show:mugs: Ann presents it, and everyone else watches and writes in its chat, signed in or not.
realtime.streams( 'show:{id}', ( user, { id } ) => {
if ( id !== 'mugs' ) return false;
return user === ANN ? 'host' : 'viewer';
}, { reactions: true } );
  • The answer: false, 'host' or 'viewer', or { role, info, chat, mod, src, quality } for more: what others see of them, whether they write in the chat (write or read), whether they keep it, and what the host sends.
  • A visitor who is not signed in comes with user null, and may only be a viewer.
  • The settings of the stream, the third argument: reactions, people and chat: { offline, links, fresh } (live streams in depth).

The calls route (/api/realtime/calls) answers streams too: nothing more to add to realtime.node().

The page​

const calls = await rt.calls();
const show = await calls.stream( 'show:mugs' );

show.watch( document.querySelector( '#show video' ) ); // the picture and its sound
show.on( 'state', ( state ) => draw( state ) ); // idle, live, ended
show.on( 'viewers', ( n ) => ( count.textContent = `${ n } watching` ) );
show.on( 'message', ( m ) => addLine( m.from.name, m.text ) );
await show.chat.send( 'Hello!' );

The page of the host goes live with the camera and ends it:

if ( show.role === 'host' ) {
await show.preview(); // the camera, shown in the same video
await show.goLive();
// …
await show.end();
}

The show card of the Example Shop does exactly this, in showCard() of examples/shop/shop.js.

More​

Reactions, keeping the chat, OBS, and the refusals: live streams in depth.