Skip to main content

Expo Room Operations

Use mediasfu-reactnative-expo 2.5.0 to add room state, participant updates, camera and microphone controls, remote-media handling, screen sharing, and participant exit to an Expo application. This guide gives each operation its package-specific name and keeps room authority in your application backend.

Before you start

  • Use Expo SDK 57 with React Native 0.86, as required by this package.
  • Configure microphone and camera permissions for every mobile platform you support, and test capture on physical devices.
  • Put room policy, authentication, rate limits, and long-lived MediaSFU credentials in an authenticated HTTPS backend.
  • Treat screen sharing as a platform-specific release test. Availability and operating-system prompts differ by device and OS version.

Room authority and the Expo prebuilt screen

The Expo package exposes createMediaSFURoom and joinMediaSFURoom callbacks. Their callback shape includes apiUserName and apiKey, and the pre-join flow validates the configured credential shape before invoking them. In a released app, supply syntactically valid placeholders, inject both callbacks, and make both adapters ignore the callback credential values. The placeholders are routing inputs, not authentication.

You can still use the callback types when your application has an established server-side room handoff. The adapter below accepts the callback shape but sends only the requested room payload to your backend. It never forwards callback credential arguments.

import type {
CreateRoomOnMediaSFUType,
JoinRoomOnMediaSFUType,
} from 'mediasfu-reactnative-expo';

export const createMediaSFURoom: CreateRoomOnMediaSFUType = async ({ payload }) => {
const response = await appFetch('https://api.example.test/rooms/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`Create failed: ${response.status}`);
return response.json();
};

export const joinMediaSFURoom: JoinRoomOnMediaSFUType = async ({ payload }) => {
const response = await appFetch('https://api.example.test/rooms/join', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`Join failed: ${response.status}`);
return response.json();
};

appFetch is your application's authenticated HTTP client. Your backend must authenticate the user, enforce room and role policy, call MediaSFU with protected authority, and return only the allowed room result. Do not add reusable MediaSFU credentials to an Expo app, an over-the-air update, or local storage.

const clientPlaceholderCredentials = {
apiUserName: 'client00',
apiKey: '0'.repeat(64),
};

<ModernMediasfuGeneric
credentials={clientPlaceholderCredentials}
createMediaSFURoom={createMediaSFURoom}
joinMediaSFURoom={joinMediaSFURoom}
/>

If either callback is omitted, that path can fall back to the default credential-bearing request. Test create and join separately before release.

The room operations available in this package

When an approved room integration supplies the live room parameters, use these Expo package operations for the following jobs:

What you needPackage operationWhat to observe
Prepare a media devicecreateDeviceClientA device is created from the room's RTP capabilities.
Start or stop microphoneclickAudioThe app shows the requested microphone state; confirm remote audio on a second device.
Start or stop cameraclickVideoThe app shows the requested camera state; confirm remote video on a second device.
Receive participant mediaprocessConsumerTransportsA remote participant's media is rendered by your app.
Start or stop screen shareclickScreenShareThe operating system grants capture and another participant sees the shared content.
Open participant exitlaunchConfirmExitThe exit confirmation is visible, then the participant leaves without ending the room for others.

Participant updates arrive through the room's allMembers handling and are rendered by ParticipantsModal. A participant list confirms membership state; it does not by itself prove that remote media is playing.

The operations above receive the current room parameter object. Keep that object owned by the active room. Do not fabricate a partial parameter object merely to call a media operation: it needs the live transports, permissions, streams, and room callbacks established during connection.

Success, failure, and cleanup

  • A successful create or join request returns the backend-approved room result. Handle 401 and 403 as an authentication or role problem, 404 as an unavailable room, 429 with bounded backoff, and 5xx as a recoverable service interruption. Never replace a failed backend request with a client credential.
  • Treat permission approval as permission only. Confirm microphone, camera, remote playback, and screen share separately with another device.
  • For participant exit, use launchConfirmExit with the room's active exit parameters. Stop app-owned tracks, remove app-owned subscriptions and timers, close the room screen after the exit result is handled, and clear local room snapshots.

For a headless host surface, the current Expo hook keeps end and preserve-room leave explicit:

import { Button } from 'react-native';
import { useMediasfuHeadless } from 'mediasfu-reactnative-expo';

export function HostExitButtons() {
const room = useMediasfuHeadless();
return <>
<Button title="End room" onPress={() => void room.controls.leave(false, true)} />
<Button title="Leave and keep room open" onPress={() => void room.controls.leave(false, false)} />
</>;
}

The second argument defaults to true. Await the result before closing the screen, and use the normal authorized join flow when a host returns to a room that was kept open.

Release checklist

  1. Test signed-in create and join policy against your application backend.
  2. Test denial, retry, and expired-session messages without exposing secrets.
  3. Test microphone, camera, remote audio/video, and leave with two physical devices on every supported OS.
  4. Test screen-share start, stop, and denial for each supported device and OS.
  5. Test backgrounding, reconnect, and cleanup so a later room cannot show stale participants or media state.

Build and test the Expo application after every native configuration change, then complete the checklist on physical Android and iOS devices. A JavaScript or web build cannot prove native capture, audio routing, or screen sharing.