mediasfu-reactnative-expo
v2.3.3
Published
MediaSFU Prebuilt React Native (Expo) SDK
Maintainers
Keywords
Readme
🚨 BREAKING: AI Phone Agents at $0.10 per 1,000 minutes
📞 Call our live AI demos right now:
- 🇺🇸 +1 (785) 369-1724 - Mixed Support Demo
- 🇬🇧 +44 7445 146575 - AI Conversation Demo
- 🇨🇦 +1 (587) 407-1990 - Technical Support Demo
- 🇨🇦 +1 (647) 558-6650 - Friendly AI Chat Demo
Traditional providers charge $0.05 per minute. We charge $0.10 per 1,000 minutes. That's 500x cheaper.
✅ Deploy AI phone agents in 30 minutes
✅ Works with ANY SIP provider (Twilio, Telnyx, Zadarma, etc.)
✅ Seamless AI-to-human handoffs
✅ Real-time call analytics & transcription
📖 Complete SIP/PSTN Documentation →
Quick Reference: Component Props & UI Overrides
New: UI override parity now extends across Webinar and Chat layouts, unifying customization for every MediaSFU interface.
Every primary MediaSFU UI export—MediasfuGeneric, MediasfuBroadcast, MediasfuConference, MediasfuWebinar, and MediasfuChat—now ships with a consistent prop surface and a powerful uiOverrides map, so you can bend the bundled experience to match your product without losing MediaSFU's hardened real-time logic.
Shared component props (applies to every MediaSFU UI component)
| Prop | Type | Default | What it does |
| --- | --- | --- | --- |
| PrejoinPage | (options) => React.ReactNode | WelcomePage | Swap in a custom pre-join experience. Receives unified pre-join options so you can add branding, legal copy, or warm-up flows. |
| localLink | string | "" | Point the SDK at your self-hosted MediaSFU server. Leave empty when using MediaSFU Cloud. |
| connectMediaSFU | boolean | true | Toggle automatic socket/WebRTC connections. Set to false when you only need the UI shell. |
| credentials | { apiUserName: string; apiKey: string } | { apiUserName: "", apiKey: "" } | Supply cloud credentials without hard-coding them elsewhere. |
| useLocalUIMode | boolean | false | Run the interface in local/demo mode with no remote signaling. |
| seedData, useSeed | SeedData, boolean | {}, false | Pre-populate the UI for demos, snapshot tests, or onboarding tours. |
| imgSrc | string | https://mediasfu.com/images/logo192.png | Default artwork used across pre-join and modal flows. |
| sourceParameters | Record<string, unknown> | undefined | Shared helper bag (media devices, participant helpers, layout handlers). Pair with updateSourceParameters to mirror the SDK's internal utilities. |
| updateSourceParameters | (helpers) => void | undefined | Receive the latest helper bundle so you can bridge MediaSFU logic into your own components. |
| returnUI | boolean | true | When false, mount the logic only—a perfect stepping stone to a fully bespoke interface. |
| noUIPreJoinOptions | CreateMediaSFURoomOptions \| JoinMediaSFURoomOptions | undefined | Feed pre-join data when returnUI is false and you want to bypass the on-screen wizard. |
| joinMediaSFURoom, createMediaSFURoom | Functions | undefined | Inject your own networking layers for joining or creating rooms. |
| customComponent | CustomComponentType | undefined | Replace the entire UI while retaining transports, sockets, and helpers. |
| customVideoCard, customAudioCard, customMiniCard | Factories | undefined | Override participant card renders to add metadata, CTAs, or badges. |
| containerStyle | React.CSSProperties | undefined | Apply inline styles to the root wrapper (dashboards, split views, etc.). |
| uiOverrides | MediasfuUICustomOverrides | undefined | Targeted component/function overrides described below. |
Power combo: Set
returnUI={false}to run MediaSFU logic headless, capture helpers viaupdateSourceParameters, and selectively bring UI pieces back withuiOverrides. That gives you progressive migration with minimal code churn.
import type { MediasfuUICustomOverrides } from "mediasfu-reactnative-expo";
const overrides: MediasfuUICustomOverrides = { /* ... */ };Bring the types into your project to unlock full IntelliSense for every override slot.
Custom UI Playbook
Use a toggle-driven "playbook" component to experiment with MediaSFU's customization layers. Flip a couple of booleans and you can watch the SDK jump between prebuilt layouts, headless logic, or a fully bespoke workspace driven by customComponent.
What the playbook demonstrates
- Connection presets: toggle
connectionScenariobetweencloud,hybrid, orceto swap credentials, local links, and connection modes in one place. - Experience selector: the
selectedExperienceswitch rendersMediasfuGeneric,MediasfuBroadcast,MediasfuWebinar,MediasfuConference, orMediasfuChatwithout touching the rest of your stack. - UI strategy flags: booleans like
showPrebuiltUI,enableFullCustomUI, andenableNoUIPreJoindemonstrate how to run the MediaSFU logic with or without the bundled UI. - Layered overrides: toggles enable the custom video/audio/mini cards, drop-in
uiOverridesfor layout and modal surfaces, container styling, and backend proxy helpers. - Custom workspace demo: a
customComponentreceives live MediaSFU helpers so you can build dashboards, CRM surfaces, or any bespoke host interface. - Debug panel & helpers: optional JSON panel exposes the
updateSourceParameterspayload so you can see exactly what to wire into your own components.
Try it quickly
const connectionScenario: "cloud" | "hybrid" | "ce" = "cloud";
const selectedExperience = "generic" as const;
const showPrebuiltUI = true;
const enableFullCustomUI = false;
const connectionPresets = {
cloud: { credentials: { apiUserName: "demo", apiKey: "demo" }, localLink: "", connectMediaSFU: true },
hybrid: { credentials: { apiUserName: "demo", apiKey: "demo" }, localLink: "http://localhost:3000", connectMediaSFU: true },
ce: { credentials: undefined, localLink: "http://localhost:3000", connectMediaSFU: false },
};
const Experience = {
generic: MediasfuGeneric,
broadcast: MediasfuBroadcast,
webinar: MediasfuWebinar,
conference: MediasfuConference,
chat: MediasfuChat,
}[selectedExperience];
export const CustomUIPlaybook = () => {
const overrides = useMemo(() => ({
mainContainer: enableFullCustomUI
? {
render: (props) => (
<View style={{ borderWidth: 4, borderColor: 'purple', borderRadius: 24, padding: 16 }}>
<MainContainerComponent {...props} />
</View>
),
}
: undefined,
}), [enableFullCustomUI]);
const current = connectionPresets[connectionScenario];
return (
<Experience
{...current}
showPrebuiltUI={showPrebuiltUI}
uiOverrides={overrides}
containerStyle={{ background: "linear-gradient(135deg, #0f172a, #1e3a8a)", minHeight: "100%" }}
/>
);
};Toggle the configuration values at the top of the playbook and watch the UI reconfigure instantly. It's the fastest path to understand MediaSFU's override surface before you fold the patterns into your production entrypoint.
Passing custom props and UI overrides
Use the same playbook to validate bespoke cards, override bundles, and fully custom workspaces before you move them into production code:
const videoCard: CustomVideoCardType = (props) => (
<VideoCard
{...props}
customStyle={{
borderRadius: 20,
border: "3px solid #4c1d95",
boxShadow: "0 28px 65px rgba(76,29,149,0.35)",
background: "linear-gradient(140deg, rgba(15,23,42,0.78), rgba(30,64,175,0.45))",
...(props.customStyle ?? {}),
}}
/>
);
const audioCard: CustomAudioCardType = (props) => (
<AudioCard
{...props}
barColor="#22c55e"
customStyle={{ borderRadius: 22, background: "rgba(34,197,94,0.1)" }}
/>
);
const miniCard: CustomMiniCardType = (props) => (
<MiniCard
{...props}
renderContainer={({ defaultContainer }) => (
<View style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100%" }}>
{defaultContainer}
</View>
)}
/>
);
const uiOverrides = useMemo<MediasfuUICustomOverrides>(() => ({
mainContainer: {
render: (props) => (
<View style={{ borderWidth: 4, borderColor: 'rgba(139,92,246,0.8)', borderRadius: 28, padding: 16 }}>
<MainContainerComponent {...props} />
</View>
),
},
menuModal: {
component: (modalProps) => <MenuModal {...modalProps} variant="glass" />,
},
consumerResume: {
wrap: (original) => async (params) => {
const startedAt = performance.now();
const result = await original(params);
analytics.track("consumer_resume", {
durationMs: performance.now() - startedAt,
consumerId: params?.consumer?.id,
});
return result;
},
},
}), []);
return (
<Experience
{...current}
customVideoCard={videoCard}
customAudioCard={audioCard}
customMiniCard={miniCard}
customComponent={enableFullCustomUI ? CustomWorkspace : undefined}
containerStyle={{ background: "#0f172a", borderRadius: 32, overflow: "hidden" }}
uiOverrides={uiOverrides}
/>
);Because the playbook surfaces updateSourceParameters, you can also log or snapshot the helper bundle (getParticipantMedia, toggleMenuModal, showAlert, and more) to ensure your custom UI always receives the hooks it expects.
uiOverrides map — override keys at a glance
Each key accepts a CustomComponentOverride<Props> object with optional component and render fields. You can fully replace the default implementation or wrap it while forwarding props.
Layout & control surfaces
| Key | Default component | Typical use |
| --- | --- | --- |
| mainContainer | MainContainerComponent | Inject theming providers or dashboard layouts. |
| mainAspect | MainAspectComponent | Tune how the main region splits space. |
| mainScreen | MainScreenComponent | Orchestrate hero video + gallery interplay. |
| mainGrid | MainGridComponent | Modify layout or layering of primary participants. |
| subAspect | SubAspectComponent | Restyle fixed control strips in webinar/conference modes. |
| otherGrid | OtherGridComponent | Change presentation of off-stage attendees. |
| flexibleGrid, flexibleGridAlt | FlexibleGrid | Implement AI-driven or branded array layouts. |
| flexibleVideo | FlexibleVideo | Add captions, watermarks, or overlays to highlighted speakers. |
| audioGrid | AudioGrid | Customise audio-only attendee presentation. |
| pagination | Pagination | Introduce infinite scroll or auto-cycling carousels. |
| controlButtons | ControlButtonsComponent | Rebrand the primary action bar. |
| controlButtonsAlt | ControlButtonsAltComponent | Control secondary button clusters. |
| controlButtonsTouch | ControlButtonsComponentTouch | Deliver mobile-first controls (used heavily by MediasfuChat). |
Participant cards & widgets
| Key | Default component | Typical use |
| --- | --- | --- |
| videoCard | VideoCard | Add host badges, reactions, or CRM overlays. |
| audioCard | AudioCard | Swap avatars or expose spoken-language info. |
| miniCard | MiniCard | Customize thumbnails in picture-in-picture modes. |
| miniAudio | MiniAudio | Re-style the audio-only mini indicators. |
| meetingProgressTimer | MeetingProgressTimer | Replace the elapsed-time widget with countdowns or milestones. |
| miniAudioPlayer | MiniAudioPlayer | Provide alternative UI for recorded clip playback. |
Modals, dialogs, and collaboration surfaces
| Key | Default component | Typical use |
| --- | --- | --- |
| loadingModal | LoadingModal | Show branded skeletons while connecting. |
| alert | AlertComponent | Route alerts through your notification system. |
| menuModal | MenuModal | Redesign quick-action trays. |
| eventSettingsModal | EventSettingsModal | Extend host tools with your own settings. |
| requestsModal | RequestsModal | Build moderation queues tailored to your workflows. |
| waitingRoomModal | WaitingRoomModal | Deliver custom waiting-room experiences. |
| coHostModal | CoHostModal | Manage co-hosts with bespoke UX. |
| mediaSettingsModal | MediaSettingsModal | Embed device tests or instructions. |
| participantsModal | ParticipantsModal | Introduce advanced filters, search, or notes. |
| messagesModal | MessagesModal | Drop in your full-featured chat module. |
| displaySettingsModal | DisplaySettingsModal | Let users pick layouts, themes, or captions. |
| confirmExitModal | ConfirmExitModal | Meet compliance wording requirements. |
| confirmHereModal | ConfirmHereModal | Customize attendance confirmations for webinars. |
| shareEventModal | ShareEventModal | Add referral codes or QR sharing. |
| recordingModal | RecordingModal | Tailor recording confirmation flows. |
| pollModal | PollModal | Integrate your polling/quiz engine. |
| backgroundModal | BackgroundModal | Hook AI background replacement or brand presets. |
| breakoutRoomsModal | BreakoutRoomsModal | Implement drag-and-drop or AI room suggestions. |
| configureWhiteboardModal | ConfigureWhiteboardModal | Adjust collaboration permissions before launch. |
| whiteboard | Whiteboard | Replace with your whiteboard provider. |
| screenboard | Screenboard | Modify shared-screen annotation layers. |
| screenboardModal | ScreenboardModal | Reimagine how users enable shared annotations. |
Entry flows & custom renderers
| Key | Default component | Typical use |
| --- | --- | --- |
| welcomePage | WelcomePage | Provide a fully branded welcome/marketing splash. |
| preJoinPage | PrejoinPage | Override the wizard used before joining live sessions. |
| customMenuButtonsRenderer | ControlButtonsAltComponent | Supply a bespoke renderer for menu button groups without overriding each button. |
Function overrides
| Key | Default function | Typical use |
| --- | --- | --- |
| consumerResume | consumerResume | Wrap errors, capture analytics, or rate-limit consumer resume behavior. |
| addVideosGrid | addVideosGrid | Replace participant ordering or layout heuristics on the fly. |
Function overrides support
{ implementation, wrap }. Provideimplementationfor a full replacement, orwrapto intercept the default behavior before/after it runs.
Example: swap the chat modal and theme the controls
import { MediasfuGeneric } from "mediasfu-reactnative-expo";
import { MyChatModal } from "./ui/MyChatModal";
import { MyControls } from "./ui/MyControls";
const uiOverrides = {
messagesModal: {
component: MyChatModal,
},
controlButtons: {
render: (props) => <MyControls {...props} variant="glass" />,
},
};
export const MyMeeting = () => (
<MediasfuGeneric credentials={credentials} uiOverrides={uiOverrides} />
);Example: wrap a MediaSFU helper instead of replacing it
const uiOverrides = {
consumerResume: {
wrap: (original) => async (params) => {
const startedAt = performance.now();
const result = await original(params);
analytics.track("consumer_resume", {
durationMs: performance.now() - startedAt,
consumerId: params?.consumer?.id,
});
return result;
},
},
};
<MediasfuConference uiOverrides={uiOverrides} />;The same override hooks power the newly refreshed MediasfuWebinar and MediasfuChat layouts, so you can guarantee a unified experience across events, webinars, or chat-first rooms.
MediaSFU offers a cutting-edge streaming experience that empowers users to customize their recordings and engage their audience with high-quality streams. Whether you're a content creator, educator, or business professional, MediaSFU provides the tools you need to elevate your streaming game.
MediaSFU React Native (Expo) Module Documentation
🚀 Quick Access to New Features
Media Device & Stream Utilities
The SDK now includes powerful utility methods for advanced media control:
getMediaDevicesList - Enumerate available cameras and microphones with automatic permission handling:
const cameras = await parameters.getMediaDevicesList('videoinput');
const microphones = await parameters.getMediaDevicesList('audioinput');getParticipantMedia - Retrieve specific participant's video or audio stream from the session:
import { getParticipantMedia } from 'mediasfu-reactnative-expo';
const videoStream = getParticipantMedia({
participantId: 'producer-123',
mediaType: 'video',
parameters: sourceParameters,
});These utilities enable advanced features like custom device selection interfaces, participant stream monitoring, and dynamic media routing. See full documentation.
Unlock the Power of MediaSFU Community Edition
MediaSFU Community Edition is free and open-source—perfect for developers who want to run their own media server without upfront costs. With robust features and simple setup, you can launch your media solution in minutes. Ready to scale? Upgrade seamlessly to MediaSFU Cloud for enterprise-grade performance and global scalability.
✅ React Native SDK Setup Guide

🎥 Watch the React Native SDK Setup Guide
Table of Contents
- Features
- Getting Started
- Basic Usage Guide
- Custom Components Guide
- Intermediate Usage Guide
- Advanced Usage Guide
- API Reference
- Troubleshooting
- Contributing
Features
MediaSFU's React Native (Expo) SDK comes with a host of powerful features out of the box:
- Breakout Rooms: Create multiple sub-meetings within a single session to enhance collaboration and focus.
- Pagination: Efficiently handle large participant lists with seamless pagination.
- Polls: Conduct real-time polls to gather instant feedback from participants.
- Media Access Requests Management: Manage media access requests with ease to ensure smooth operations.
- Video Effects: Apply various video effects, including virtual backgrounds, to enhance the visual experience.
- Chat (Direct & Group): Facilitate communication with direct and group chat options.
- Cloud Recording (track-based): Customize recordings with track-based options, including watermarks, name tags, background colors, and more.
- Managed Events: Manage events with features to handle abandoned and inactive participants, as well as enforce time and capacity limits.
- AI Phone Agents: Integrate AI-powered phone agents for automated customer interactions at a fraction of the cost of traditional providers.
getMediaDevicesList: Enumerate available cameras and microphones with permission handlinggetParticipantMedia: Retrieve specific participant's video or audio streams by ID or name
🆕 New Advanced Media Access
Interested in getting just the media stream of a specific participant? You can now easily retrieve individual participant streams using getParticipantMedia() method. Learn more →
Need to access available cameras and microphones? Use getMediaDevicesList() to enumerate all available media devices on the user's system programmatically with automatic permission handling.
Getting Started
This section will guide users through the initial setup and installation of the npm module.
Note: this is specifically for React-Native-Expo. If you are integrating into a React Native CLI app, the best option is to use the core
mediasfu-reactnativepackage, which you can find on npm at mediasfu-reactnative.
Documentation Reference
For comprehensive documentation on the available methods, components, and functions, please visit mediasfu.com. This resource provides detailed information for this guide and additional documentation.
Installation
Instructions on how to install the module using npm.
1. Add the Package to Your Project
To install the mediasfu-reactnative-expo package, run:
npm install mediasfu-reactnative-expo1.1 Important Installation Notes for React Native
🚫 Avoid Using --force or --legacy-peer-deps
Using these flags can override important dependency checks, potentially causing unstable builds or unexpected behavior.
- Why Avoid Them?
They bypass compatibility checks, which can introduce bugs or conflicts within your project.
⚙️ Use Package Overrides (Recommended)
If you encounter peer dependency conflicts, use the overrides field in your package.json instead of forcing installations.
✅ Example of Safe Overrides:
{
"overrides": {
"some-package": {
"dependency-name": "^1.2.3"
}
}
}- Why This Works:
Overrides let you resolve conflicts safely without compromising the integrity of your project.
🚩 If You Absolutely Need to Use --force or --legacy-peer-deps
- Some peer dependencies might be skipped.
- You’ll need to manually install them to avoid runtime errors.
🔑 Install the Required Peer Dependencies:
npm install \
"@config-plugins/react-native-webrtc@^9.0.0" \
"@expo/metro-runtime@^4.0.0" \
"@expo/vector-icons@^14.0.2" \
"@react-native-async-storage/async-storage@^1.23.1" \
"@react-native-community/slider@^4.5.2" \
"@react-native-picker/picker@^2.7.5" \
"expo@^52.0.11" \
"expo-av@~15.0.1" \
"expo-camera@~16.0.9" \
"expo-clipboard@~7.0.0" \
"expo-dev-client@~5.0.5" \
"expo-router@~4.0.11" \
"expo-web-browser@~13.0.3" \
"expo-screen-orientation@~8.0.1" \
"expo-splash-screen@~0.29.13" \
"expo-status-bar@~2.0.0" \
"mediasoup-client@^3.16.0" \
"[email protected]" \
"react-color@^2.19.3" \
"[email protected]" \
"[email protected]" \
"react-native-gesture-handler@~2.20.2" \
"react-native-orientation-locker@^1.6.0" \
"react-native-picker-select@^9.0.0" \
"react-native-reanimated@~3.16.1" \
"[email protected]" \
"react-native-web@~0.19.13" \
"react-native-webrtc@^118.0.0" \
"react-native-webrtc-web-shim@^1.0.7" \
"reanimated-color-picker@^2.4.2" \
"socket.io-client@^4.7.2"- Why This Is Important:
These peer dependencies are critical formediasfu-reactjsto function correctly within React Native.
🔍 How to Check for Peer Dependencies
Open your
package.json.Look for the
peerDependenciessection:"peerDependencies": { "@config-plugins/react-native-webrtc": "^9.0.0", "@expo/metro-runtime": "^4.0.0", "@expo/vector-icons": "^14.0.2", "@react-native-async-storage/async-storage": "^1.23.1", "@react-native-community/slider": "^4.5.2", "@react-native-picker/picker": "^2.7.5", "expo": "^52.0.11", "expo-av": "~15.0.1", "expo-camera": "~16.0.9", "expo-clipboard": "~7.0.0", "expo-dev-client": "~5.0.5", "expo-router": "~4.0.11", "expo-web-browser": "~13.0.3", "expo-screen-orientation": "~8.0.1", "expo-splash-screen": "~0.29.13", "expo-status-bar": "~2.0.0", "mediasoup-client": "^3.16.0", "react": "18.3.1", "react-color": "^2.19.3", "react-dom": "18.3.1", "react-native": "0.76.3", "react-native-gesture-handler": "~2.20.2", "react-native-orientation-locker": "^1.6.0", "react-native-picker-select": "^9.0.0", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "4.12.0", "react-native-web": "~0.19.13", "react-native-webrtc": "^118.0.0", "react-native-webrtc-web-shim": "^1.0.7", "reanimated-color-picker": "^2.4.2", "socket.io-client": "^4.7.2" }Ensure all are installed. If not, run the install command above.
✅ Final Recommendations
- Always try to resolve conflicts using overrides first.
- Only use
--forceor--legacy-peer-depsas a last resort.
Resolving Dependency Issues
If you encounter an error related to @config-plugins/react-native-webrtc@"^9.0.0" during installation, you can resolve it by adding the following override to your package.json:
"overrides": {
"@config-plugins/react-native-webrtc": {
"expo": "^52.0.11"
}
}Ensure the version specified (
^52.0.11) matches the Expo SDK version used in your project. You can replace it with the latest compatible version if needed.
2.1 Obtain an API Key (If Required)
You can get your API key by signing up or logging into your account at mediasfu.com.
2.2 Self-Hosting MediaSFU
If you plan to self-host MediaSFU or use it without MediaSFU Cloud services, you don't need an API key. You can access the open-source version of MediaSFU from the MediaSFU Open Repository.
This setup allows full flexibility and customization while bypassing the need for cloud-dependent credentials.
3. Configure Your Project
Before proceeding, ensure that your project is properly configured to work with mediasfu-reactnative-expo. Follow the steps below to set up the necessary configuration files.
a. Update app.json
Ensure that your app.json does not have the output field set to 'static' in the web configuration. Remove or clear this field to prevent build issues.
{
"expo": {
// ... other configurations
"web": {
// Remove or ensure the output field is not set to 'static'
// "output": "static" // This line should be removed or cleared
}
}
}b. Configure babel.config.js
Your babel.config.js should include the necessary presets and plugins for Expo and React Native Reanimated. Here is an example configuration:
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
'react-native-reanimated/plugin',
'@babel/plugin-transform-block-scoping'
],
};
};c. Configure metro.config.js
Ensure your metro.config.js file includes the correct settings for Metro bundler:
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');
const config = getDefaultConfig(__dirname);
config.resolver.nodeModulesPaths = [path.resolve(__dirname, 'node_modules')];
module.exports = config;4. Complete the Setup
After completing the above steps, you can proceed to set up and run your project.
Start the Development Server:
npx expo startCreate a Development Build:
Since
react-native-webrtcdoes not run on Expo Go, you will need to create a development build to test WebRTC functionalities on an actual device. Follow the Expo Development Builds documentation for guidance on creating a development build.
📱 React Native Expo SDK Comprehensive Guide
This comprehensive guide provides clear, progressive learning paths from beginner to advanced usage. Each section builds upon the previous one with practical examples and detailed explanations tailored for React Native Expo development.
Table of Contents - SDK Guide
- Quick Start (5 Minutes)
- Understanding MediaSFU Architecture
- Core Concepts & Components
- Working with Methods
- Customization & Styling
- Deployment Patterns
- Understanding Data Structures
- Complete Production Example
Quick Start (5 Minutes)
Get your first MediaSFU app running in just a few minutes with React Native Expo.
Step 1: Install the Package
npm install mediasfu-reactnative-expoStep 2: Import and Use
import React from 'react';
import { MediasfuGeneric } from 'mediasfu-reactnative-expo';
const App = () => {
// Option 1: Use without credentials (for testing/development)
return <MediasfuGeneric />;
// Option 2: Use with MediaSFU Cloud credentials
// const credentials = { apiUserName: 'your_username', apiKey: 'your_api_key' };
// return <MediasfuGeneric credentials={credentials} />;
};
export default App;Step 3: Run Your App
npx expo startThat's it! You now have a fully functional video conferencing app with:
- ✅ Video and audio streaming
- ✅ Screen sharing
- ✅ Chat messaging
- ✅ Participant management
- ✅ Recording capabilities
- ✅ Breakout rooms
- ✅ Polls
- ✅ Custom UI components support
Understanding MediaSFU Architecture
Before diving deeper, let's understand how MediaSFU is structured. This knowledge will help you make better decisions when building your application.
The Three-Layer Architecture
┌─────────────────────────────────────────────┐
│ Your React Native Expo Application │
│ (App.js, screens, navigation, logic) │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ MediaSFU Components Layer │
│ (MediasfuGeneric, MediasfuBroadcast, etc.) │
│ - Pre-built UI components │
│ - Event handling │
│ - State management │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ MediaSFU Core Methods Layer │
│ (Stream control, room management, │
│ WebRTC handling, socket communication) │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ MediaSFU Backend Services │
│ (MediaSFU Cloud or Community Edition) │
└─────────────────────────────────────────────┘Understanding the layers:
- Your Application Layer: Where you build your app-specific features and navigation
- Components Layer: Pre-built MediaSFU components that you can use or customize
- Core Methods Layer: The engine that handles all real-time communication
- Backend Layer: MediaSFU's servers that orchestrate the entire experience
Event Room Types
MediaSFU provides 5 specialized room types, each optimized for specific use cases:
| Room Type | Best For | Key Features | Import |
|-----------|----------|--------------|--------|
| MediasfuGeneric | General purpose meetings | Flexible layout, all features enabled | import { MediasfuGeneric } from 'mediasfu-reactnative-expo' |
| MediasfuBroadcast | Live streaming events | Optimized for one-to-many communication | import { MediasfuBroadcast } from 'mediasfu-reactnative-expo' |
| MediasfuWebinar | Educational sessions | Presenter focus, Q&A features | import { MediasfuWebinar } from 'mediasfu-reactnative-expo' |
| MediasfuConference | Business meetings | Equal participant layout, collaboration tools | import { MediasfuConference } from 'mediasfu-reactnative-expo' |
| MediasfuChat | Interactive discussions | Chat-first interface, quick connections | import { MediasfuChat } from 'mediasfu-reactnative-expo' |
Example: Choosing the right room type
import {
MediasfuGeneric,
MediasfuWebinar,
MediasfuBroadcast,
MediasfuConference,
MediasfuChat
} from 'mediasfu-reactnative-expo';
// For a webinar
<MediasfuWebinar credentials={credentials} />
// For a broadcast
<MediasfuBroadcast credentials={credentials} />
// For a conference
<MediasfuConference credentials={credentials} />The Three Usage Modes
MediaSFU offers three progressive levels of customization. Understanding these modes is crucial for choosing the right approach for your project.
Mode 1: Default UI (Simplest) ⭐ Best for Beginners
Use MediaSFU's complete pre-built interface - perfect for rapid development.
import React from 'react';
import { MediasfuGeneric } from 'mediasfu-reactnative-expo';
const App = () => {
const credentials = {
apiUserName: 'your_username',
apiKey: 'your_api_key'
};
return <MediasfuGeneric credentials={credentials} />;
};
export default App;When to use:
- ✅ Prototyping or MVP development
- ✅ Need a production-ready UI quickly
- ✅ Standard video conferencing features are sufficient
- ✅ Want to minimize development time
Advantages:
- Zero UI development needed
- All features work out of the box
- Automatic responsive layouts
- Professional appearance
Mode 2: Custom UI with MediaSFU Backend (Most Flexible) ⭐ Best for Custom Brands
Build your own UI while using MediaSFU's powerful backend infrastructure.
import React, { useState } from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { MediasfuGeneric } from 'mediasfu-reactnative-expo';
const App = () => {
const [sourceParameters, setSourceParameters] = useState(null);
const credentials = { apiUserName: 'your_username', apiKey: 'your_api_key' };
return (
<View style={{ flex: 1 }}>
<MediasfuGeneric
returnUI={false}
sourceParameters={sourceParameters}
updateSourceParameters={setSourceParameters}
credentials={credentials}
noUIPreJoinOptions={{
action: 'create',
userName: 'Your Name',
capacity: 50,
duration: 30,
eventType: 'conference'
}}
/>
{/* Your completely custom UI */}
{sourceParameters && (
<View style={styles.customControls}>
<TouchableOpacity
onPress={() => sourceParameters.clickVideo({
parameters: sourceParameters
})}
style={styles.controlButton}
>
<Text style={styles.buttonText}>
{sourceParameters.videoAlreadyOn ? 'Stop Video' : 'Start Video'}
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => sourceParameters.clickAudio({
parameters: sourceParameters
})}
style={styles.controlButton}
>
<Text style={styles.buttonText}>
{sourceParameters.audioAlreadyOn ? 'Mute' : 'Unmute'}
</Text>
</TouchableOpacity>
{/* Display participant count */}
<Text style={styles.participantCount}>
{sourceParameters.participants.length} Participants
</Text>
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
customControls: {
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
backgroundColor: 'rgba(0,0,0,0.8)',
padding: 15,
borderRadius: 10,
},
controlButton: {
backgroundColor: '#4CAF50',
padding: 12,
borderRadius: 8,
marginVertical: 5,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
participantCount: {
color: 'white',
fontSize: 16,
marginTop: 10,
textAlign: 'center',
}
});
export default App;When to use:
- ✅ Need complete control over UI/UX
- ✅ Building a custom branded experience
- ✅ Integrating into existing app design
- ✅ Want to position controls differently
What you get:
- Access to all MediaSFU methods via
sourceParameters - Full control over when and how to display UI
- Ability to create completely custom layouts
- Access to real-time room state and participant data
Mode 3: Component Replacement (Balanced) ⭐ Best for Partial Customization
Replace specific MediaSFU components while keeping the rest of the infrastructure.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import {
MediasfuGeneric,
FlexibleVideo,
FlexibleGrid,
AudioGrid
} from 'mediasfu-reactnative-expo';
// Your custom main screen component
function CustomMainScreen({ parameters }) {
return (
<View style={styles.container}>
{/* Custom header */}
<View style={styles.header}>
<Text style={styles.roomName}>{parameters.roomName}</Text>
<Text style={styles.participantCount}>
{parameters.participants.length} participants
</Text>
</View>
{/* Use MediaSFU's FlexibleVideo for main display */}
<View style={styles.mainVideo}>
<FlexibleVideo
customWidth={parameters.componentSizes.mainWidth}
customHeight={parameters.componentSizes.mainHeight}
parameters={parameters}
/>
</View>
{/* Use MediaSFU's FlexibleGrid for participants */}
<View style={styles.participantGrid}>
<FlexibleGrid
customWidth={parameters.componentSizes.otherWidth}
customHeight={parameters.componentSizes.otherHeight}
parameters={parameters}
/>
</View>
{/* Show audio-only participants */}
<View style={styles.audioContainer}>
<AudioGrid parameters={parameters} />
</View>
</View>
);
}
const App = () => {
const credentials = { apiUserName: 'your_username', apiKey: 'your_api_key' };
return (
<MediasfuGeneric
credentials={credentials}
customComponent={CustomMainScreen}
/>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#1a1a1a',
},
header: {
backgroundColor: '#2d2d2d',
padding: 15,
flexDirection: 'row',
justifyContent: 'space-between',
},
roomName: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
participantCount: {
color: '#4CAF50',
fontSize: 14,
},
mainVideo: {
flex: 3,
},
participantGrid: {
flex: 2,
},
audioContainer: {
height: 80,
},
});
export default App;When to use:
- ✅ Need custom main interface but want to keep MediaSFU's components
- ✅ Partial customization with minimal effort
- ✅ Want to maintain MediaSFU's functionality while customizing layout
Parameters Object: Your Control Center
The sourceParameters object is your gateway to all MediaSFU functionality. Think of it as the control panel for your entire real-time communication experience.
// The sourceParameters object contains everything you need:
// Media Controls
sourceParameters.clickVideo(options) // Toggle video on/off
sourceParameters.clickAudio(options) // Toggle audio on/off
sourceParameters.clickScreenShare(options) // Toggle screen sharing
// Room State
sourceParameters.roomName // Current room name
sourceParameters.participants // Array of all participants
sourceParameters.allVideoStreams // All video streams
sourceParameters.allAudioStreams // All audio streams
// UI State
sourceParameters.videoAlreadyOn // Is video currently on?
sourceParameters.audioAlreadyOn // Is audio currently on?
sourceParameters.screenAlreadyOn // Is screen sharing active?
// And 200+ more properties and methods...Access patterns in different modes:
// Mode 1 (Default UI): Parameters are managed internally
// You don't need to access them directly
// Mode 2 (Custom UI): Access via sourceParameters
<MediasfuGeneric
returnUI={false}
sourceParameters={sourceParameters}
updateSourceParameters={setSourceParameters}
/>
// Then use:
sourceParameters?.clickVideo({ parameters: sourceParameters });
// Mode 3 (Component Replacement): Passed to your custom component
function CustomMainScreen({ parameters }) {
// Use parameters directly
parameters.clickVideo({ parameters });
}Core Concepts & Components
Now that you understand the architecture, let's explore the building blocks that make up a MediaSFU application.
Display Components
These components handle the visual presentation of media streams and participants.
Primary Layout Components
1. FlexibleVideo - Main video display area
import { FlexibleVideo } from 'mediasfu-reactnative-expo';
<FlexibleVideo
customWidth={Dimensions.get('window').width}
customHeight={400}
parameters={parameters}
/>Features:
- Automatically handles main presenter or screen share
- Smooth transitions between different video sources
- Responsive sizing
- Aspect ratio preservation
Use cases:
- Main stage video in webinars
- Screen sharing display
- Featured speaker in conferences
- Primary content area
2. FlexibleGrid - Participant grid layout
import { FlexibleGrid } from 'mediasfu-reactnative-expo';
<FlexibleGrid
customWidth={Dimensions.get('window').width}
customHeight={600}
parameters={parameters}
/>Features:
- Intelligent grid sizing (2x2, 3x3, 4x4, etc.)
- Pagination for large participant lists
- Automatic reflow on orientation change
- Optimized for different screen sizes
Use cases:
- Conference room participant display
- Breakout room participant view
- Gallery view in meetings
- Multi-participant discussions
3. AudioGrid - Audio-only participants
import { AudioGrid } from 'mediasfu-reactnative-expo';
<AudioGrid parameters={parameters} />Features:
- Displays participants without video
- Audio level indicators
- Compact layout for efficiency
- Visual speaking indicators
Use cases:
- Phone-in participants
- Participants with video off
- Audio-only mode
- Bandwidth-constrained participants
Container Components
| Component | Purpose | Use Case | Example |
|-----------|---------|----------|---------|
| MainContainerComponent | Primary content wrapper | Wraps all main content areas | <MainContainerComponent>...</MainContainerComponent> |
| MainAspectComponent | Aspect ratio container | Maintains proper video proportions | Used internally by video components |
| MainScreenComponent | Screen layout manager | Organizes screen regions | Structures the main display area |
| SubAspectComponent | Secondary content container | For picture-in-picture, sidebars | Side panels, floating windows |
| MainGridComponent | Main grid organizer | Primary participant grid | Central participant display |
| OtherGridComponent | Secondary grid organizer | Overflow participants | Additional participant pages |
Example: Building a custom layout with containers
import React from 'react';
import { View, StyleSheet } from 'react-native';
import {
FlexibleVideo,
FlexibleGrid,
AudioGrid,
MainContainerComponent
} from 'mediasfu-reactnative-expo';
function CustomLayoutExample({ parameters }) {
return (
<MainContainerComponent>
<View style={styles.container}>
{/* Main video area - 60% of screen */}
<View style={styles.mainSection}>
<FlexibleVideo
customWidth="100%"
customHeight="100%"
parameters={parameters}
/>
</View>
{/* Participant grid - 30% of screen */}
<View style={styles.gridSection}>
<FlexibleGrid
customWidth="100%"
customHeight="100%"
parameters={parameters}
/>
</View>
{/* Audio-only participants - 10% of screen */}
<View style={styles.audioSection}>
<AudioGrid parameters={parameters} />
</View>
</View>
</MainContainerComponent>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
mainSection: {
flex: 6,
backgroundColor: '#000',
},
gridSection: {
flex: 3,
backgroundColor: '#1a1a1a',
},
audioSection: {
flex: 1,
backgroundColor: '#2d2d2d',
},
});Control Components
These components provide user interaction interfaces for controlling media and meeting features.
1. ControlButtonsComponent - Standard control bar
import { ControlButtonsComponent } from 'mediasfu-reactnative-expo';
<ControlButtonsComponent
parameters={parameters}
position="bottom" // or 'top', 'left', 'right'
/>Includes:
- Microphone toggle
- Camera toggle
- Screen share button
- Participants list
- Chat button
- Settings
- End call button
2. ControlButtonsAltComponent - Alternative layout
import { ControlButtonsAltComponent } from 'mediasfu-reactnative-expo';
<ControlButtonsAltComponent
parameters={parameters}
// Different button arrangement or styling
/>Features:
- Alternative button configurations
- Customizable layouts
- Different visual styles
- Recording controls
3. ControlButtonsComponentTouch - Touch-optimized floating controls
import { ControlButtonsComponentTouch } from 'mediasfu-reactnative-expo';
<ControlButtonsComponentTouch
parameters={parameters}
/>Features:
- Floating action buttons for mobile
- Touch-optimized sizing
- Easy thumb access
- Gesture-friendly design
Example: Building custom control buttons
import React from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome5';
function CustomControls({ parameters }) {
return (
<View style={styles.controlBar}>
{/* Video Control */}
<TouchableOpacity
style={[
styles.button,
parameters.videoAlreadyOn ? styles.activeButton : styles.inactiveButton
]}
onPress={() => parameters.clickVideo({ parameters })}
>
<Icon
name={parameters.videoAlreadyOn ? 'video' : 'video-slash'}
size={24}
color="white"
/>
<Text style={styles.buttonText}>Video</Text>
</TouchableOpacity>
{/* Audio Control */}
<TouchableOpacity
style={[
styles.button,
parameters.audioAlreadyOn ? styles.activeButton : styles.inactiveButton
]}
onPress={() => parameters.clickAudio({ parameters })}
>
<Icon
name={parameters.audioAlreadyOn ? 'microphone' : 'microphone-slash'}
size={24}
color="white"
/>
<Text style={styles.buttonText}>Mic</Text>
</TouchableOpacity>
{/* Screen Share */}
<TouchableOpacity
style={[
styles.button,
parameters.screenAlreadyOn ? styles.activeButton : styles.inactiveButton
]}
onPress={() => parameters.clickScreenShare({ parameters })}
>
<Icon name="desktop" size={24} color="white" />
<Text style={styles.buttonText}>Share</Text>
</TouchableOpacity>
{/* Participants */}
<TouchableOpacity
style={styles.button}
onPress={() => parameters.updateIsParticipantsModalVisible(true)}
>
<Icon name="users" size={24} color="white" />
<Text style={styles.buttonText}>
{parameters.participants.length}
</Text>
</TouchableOpacity>
{/* Chat */}
<TouchableOpacity
style={styles.button}
onPress={() => parameters.updateIsMessagesModalVisible(true)}
>
<Icon name="comment" size={24} color="white" />
<Text style={styles.buttonText}>Chat</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
controlBar: {
flexDirection: 'row',
justifyContent: 'space-evenly',
padding: 15,
backgroundColor: 'rgba(0,0,0,0.8)',
},
button: {
alignItems: 'center',
justifyContent: 'center',
padding: 10,
borderRadius: 8,
minWidth: 60,
},
activeButton: {
backgroundColor: '#4CAF50',
},
inactiveButton: {
backgroundColor: '#f44336',
},
buttonText: {
color: 'white',
fontSize: 12,
marginTop: 4,
},
});
export default CustomControls;Modal Components
MediaSFU includes pre-built modals for various features. These can be triggered programmatically or through UI interactions.
Available Modals:
| Modal | Purpose | Trigger Method | Example |
|-------|---------|----------------|---------|
| ParticipantsModal | Manage participants | parameters.updateIsParticipantsModalVisible(true) | View, mute, remove participants |
| MessagesModal | Chat interface | parameters.updateIsMessagesModalVisible(true) | Send/receive messages |
| SettingsModal | General settings | parameters.updateIsSettingsModalVisible(true) | Configure meeting settings |
| DisplaySettingsModal | Display options | parameters.updateIsDisplaySettingsModalVisible(true) | Layout, theme, display preferences |
| RecordingModal | Recording controls | parameters.updateIsRecordingModalVisible(true) | Start/stop/configure recording |
| PollModal | Conduct polls | parameters.updateIsPollModalVisible(true) | Create and manage polls |
| BreakoutRoomsModal | Manage breakout rooms | parameters.updateIsBreakoutRoomsModalVisible(true) | Create and assign breakout rooms |
| CoHostModal | Co-host management | parameters.updateIsCoHostModalVisible(true) | Manage co-hosts |
| WaitingRoomModal | Waiting room | parameters.updateIsWaitingModalVisible(true) | Admit/reject participants |
| RequestsModal | Handle requests | parameters.updateIsRequestsModalVisible(true) | Approve media requests |
| ShareEventModal | Share meeting | parameters.updateIsShareEventModalVisible(true) | Share meeting link |
| ConfirmExitModal | Exit confirmation | parameters.updateIsConfirmExitModalVisible(true) | Confirm leaving meeting |
| ConfirmHereModal | Presence confirmation | parameters.updateIsConfirmHereModalVisible(true) | Confirm still present |
| MediaSettingsModal | Media settings | parameters.updateIsMediaSettingsModalVisible(true) | Camera/mic settings |
| MenuModal | Main menu | parameters.updateIsMenuModalVisible(true) | Access all features |
| LoadingModal | Loading indicator | parameters.updateIsLoadingModalVisible(true) | Show loading state |
| AlertComponent | Alert messages | parameters.showAlert({...}) | Display alerts |
Example: Using modals programmatically
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { MediasfuGeneric } from 'mediasfu-reactnative-expo';
function MyCustomInterface({ parameters }) {
return (
<View>
{/* Button to show participants */}
<TouchableOpacity
onPress={() => parameters.updateIsParticipantsModalVisible(true)}
>
<Text>View Participants ({parameters.participants.length})</Text>
</TouchableOpacity>
{/* Button to show chat */}
<TouchableOpacity
onPress={() => parameters.updateIsMessagesModalVisible(true)}
>
<Text>Open Chat</Text>
</TouchableOpacity>
{/* Button to start recording */}
<TouchableOpacity
onPress={() => parameters.updateIsRecordingModalVisible(true)}
>
<Text>Start Recording</Text>
</TouchableOpacity>
{/* Button to create poll */}
<TouchableOpacity
onPress={() => parameters.updateIsPollModalVisible(true)}
>
<Text>Create Poll</Text>
</TouchableOpacity>
{/* Show custom alert */}
<TouchableOpacity
onPress={() => parameters.showAlert({
message: 'This is a custom alert!',
type: 'success',
duration: 3000
})}
>
<Text>Show Alert</Text>
</TouchableOpacity>
</View>
);
}Media Cards
Individual participant media display components.
1. VideoCard - Individual participant video
import { VideoCard } from 'mediasfu-reactnative-expo';
<VideoCard
videoStream={participantStream}
remoteProducerId="producer-id"
eventType="conference"
forceFullDisplay={false}
participant={participantObject}
backgroundColor="black"
showControls={true}
showInfo={true}
name="John Doe"
barColor="red"
textColor="white"
nameTagColor="blue"
overlayPosition="topLeft"
controlsPosition="topRight"
infoPosition="topLeft"
videoInfo={{}}
parameters={parameters}
/>2. AudioCard - Individual audio-only participant
import { AudioCard } from 'mediasfu-reactnative-expo';
<AudioCard
name="Jane Smith"
barColor="blue"
textColor="white"
customStyle={{}}
controlsPosition="topLeft"
infoPosition="topRight"
roundedImage={true}
imageSource="https://example.com/avatar.jpg"
showControls={true}
showWaveform={true}
participant={participantObject}
backgroundColor="rgba(0,0,0,0.5)"
parameters={parameters}
/>3. MiniCard - Compact participant display
import { MiniCard } from 'mediasfu-reactnative-expo';
<MiniCard
participant={participantObject}
showControls={false}
showInfo={true}
videoInfo={{}}
roundedImage={true}
backgroundColor="transparent"
parameters={parameters}
/>Working with Participants
Understanding participant objects is crucial for custom UI development.
Participant Object Structure:
{
id: "unique-id", // Unique identifier
name: "John Doe", // Display name
muted: false, // Audio state
videoOn: true, // Video state
audioID: "audio-producer-id", // Audio producer ID
videoID: "video-producer-id", // Video producer ID
islevel: "2", // Privilege level (2=host, 1=co-host, 0=participant)
isBanned: false, // Ban status
isSuspended: false, // Suspension status
stream: [streamObject], // Media streams
// ...more properties
}Common Operations:
// Get all participants
const participants = parameters.participants;
// Filter video participants
const videoParticipants = participants.filter(p => p.videoOn);
// Filter audio-only participants
const audioOnlyParticipants = participants.filter(p => !p.videoOn && !p.muted);
// Find specific participant
const participant = participants.find(p => p.id === 'participant-id');
// Get participant count
const count = parameters.participantsCounter;
// Get current user info
const currentUser = {
name: parameters.member,
level: parameters.islevel,
videoOn: parameters.videoAlreadyOn,
audioOn: parameters.audioAlreadyOn,
};
// Check if user is host
const isHost = parameters.islevel === '2';
// Check if user is co-host
const isCoHost = parameters.islevel === '1';Stream Management
Working with media streams for advanced use cases.
Stream Object Structure:
{
producerId: "producer-123", // Producer identifier
stream: MediaStream, // Actual media stream
socket_: Socket, // Associated socket
name: "Participant Name", // Participant name
kind: "video", // 'video' or 'audio'
videoID: "video-id", // Video producer ID
audioID: "audio-id", // Audio producer ID
// ...more properties
}Common Stream Operations:
// Get all video streams
const videoStreams = parameters.allVideoStreams;
// Get all audio streams
const audioStreams = parameters.allAudioStreams;
// Find stream by producer ID
const stream = videoStreams.find(s => s.producerId === 'producer-id');
// Get participant's video stream
function getParticipantVideoStream(participantId) {
const participant = parameters.participants.find(p => p.id === participantId);
if (!participant || !participant.videoID) return null;
return parameters.allVideoStreams.find(
s => s.producerId === participant.videoID
);
}
// Get participant's audio stream
function getParticipantAudioStream(participantId) {
const participant = parameters.participants.find(p => p.id === participantId);
if (!participant || !participant.audioID) return null;
return parameters.allAudioStreams.find(
s => s.producerId === participant.audioID
);
}
// Check if main screen is sharing
const isScreenSharing = parameters.screenAlreadyOn;
// Get screen share stream
const screenStream = parameters.screenAlreadyOn
? parameters.screenProducerId
: null;Using the new utility methods:
import { getMediaDevicesList, getParticipantMedia } from 'mediasfu-reactnative-expo';
// Get specific participant's video stream by ID
const videoStream = getParticipantMedia({
participantId: 'producer-123',
mediaType: 'video',
parameters: sourceParameters,
});
// Get specific participant's audio stream by name
const audioStream = getParticipantMedia({
participantName: 'John Doe',
mediaType: 'audio',
parameters: sourceParameters,
});
// Enumerate available cameras
const cameras = await parameters.getMediaDevicesList('videoinput');
cameras.forEach(camera => {
console.log(`Camera: ${camera.label} (${camera.deviceId})`);
});
// Enumerate available microphones
const microphones = await parameters.getMediaDevicesList('audioinput');
microphones.forEach(mic => {
console.log(`Microphone: ${mic.label} (${mic.deviceId})`);
});Programmatically Fetching Tokens
If you prefer to fetch the required tokens programmatically without visiting MediaSFU's website, you can use the PreJoinPage component and pass your credentials as props:
import { MediasfuGeneric, PreJoinPage } from 'mediasfu-reactnative-expo';
const App = () => {
const credentials = { apiUserName: "yourAPIUserName", apiKey: "yourAPIKey" };
return (
<MediasfuGeneric PrejoinPage={PreJoinPage} credentials={credentials} />
);
}
export default App;Preview of Welcome Page
Preview of Prejoin Page
Custom Welcome/Prejoin Page
Alternatively, you can design your own welcome/prejoin page. The core function of this page is to fetch user tokens from MediaSFU's API and establish a connection with the returned link if valid.
Parameters Passed to Custom Page
MediaSFU passes relevant parameters to the custom welcome/prejoin page:
let { showAlert, updateIsLoadingModalVisible, connectSocket, updateSocket, updateValidated,
updateApiUserName, updateApiToken, updateLink, updateRoomName, updateMember } = parameters;Ensure that your custom page implements the following updates:
updateSocket(socket);
updateApiUserName(