Skip to main content
Markdown

Group calls

A group call is a room on WordPlus Cloud's media servers. Everyone in it sends their camera, microphone and screen once, and gets everyone else's. The servers form a mesh across regions, so a room's people may sit on different servers. A busy server sends a newcomer to another, and a full mesh holds their place while it adds a server.

The call screen's <wordplus-room> joins one with no code. This page is for building your own interface.

Who may join​

The same callback as for calls, with $with set to null:

wordplus_realtime()->calls( 'class-', function ( $user_id, $room, $with ) {
if ( null !== $with ) {
return false; // this plugin has no calls between two people
}

$class = (int) substr( $room, strlen( 'class-' ) );

if ( my_school_teacher_of( $class ) === $user_id ) {
return array( 'admin' => true ); // the teacher runs the room
}

return my_school_student_of( $class, $user_id ) ? array( 'publish' => false ) : false; // students watch
} );

The array may say what the user does in the room:

KeyDefault
infoname and picturewhat the others see of them
publishtruesends their camera, microphone and screen
subscribetruegets the others'
adminfalsemay manage the room through the media server's own API
hiddenfalseisn't listed to the others, as for a silent observer

Joining in the browser​

const { calls } = wordplusRealtimeCalls.page();

const room = await calls.room( 'class-7', { type: 'video' } ); // rejects with `forbidden` when your callback says no

room.on( 'state', ( state ) => showState( state ) ); // connecting, connected, reconnecting, ended
room.on( 'person', ( person ) => drawPerson( person ) ); // someone arrived, or what they send changed
room.on( 'person_left', ( person ) => removePerson( person.identity ) );
room.on( 'speakers', ( people ) => markSpeaking( people ) );
room.on( 'ended', ( reason ) => showEnded( reason ) );

const media = await navigator.mediaDevices.getUserMedia( { audio: true, video: true } );
await room.setTrack( 'microphone', media.getAudioTracks()[ 0 ] );
await room.setTrack( 'camera', media.getVideoTracks()[ 0 ] );

// Later:
room.leave();
  • calls.room() resolves at once with the room connecting. Tracks set before it connects are sent once it does.
  • room.people() lists everyone else in it now.
  • A person is { identity, user, info, camera, microphone, screen, screenAudio, speaking }. user is their user id on the site, info what your callback gave for them, and each track has attach( element ) and detach().
  • room.livekit is the media server client's own room, for what the kit doesn't wrap: a group call's rooms are LiveKit rooms on WordPlus Cloud's own servers.

Limits​

32 people in a video room and 50 in an audio room, which the plan sets. The room's type is the one the first person joined it with.

Where it runs​

A room is sdk_<site key>_<room name> on the mesh, apart from the site's Better Messages rooms and live streams. The page loads the media client only when it first joins a room (realtime-rooms.min.js, about 580 KB), so a page that never joins one never loads it.