Show Cameras, Screen Shares, and Boards by SDK
Show people, their cameras, their shared screens, and the sound of a shared tab in your room. Start with the supplied room and its rendered cards or grid. Use the lower-level controls only when you are already keeping one complete live room state in your application.
A rendered component is a ready-made visual part of the room: it decides where video, audio, screen share, labels, and pagination appear. A raw stream is not a ready-made screen. Do not treat a stream as a UI, and do not call a media control with a partly reconstructed room object.
For rooms larger than one display page, consumer pause/resume behavior, panelists, permissions, and breakouts, continue with large rooms and moderation by SDK.
Before you start
- Join the room and wait until its current media state is ready.
- Ask for camera, microphone, or screen-capture permission only when the person starts that action.
- Keep the supplied room mounted while media is active.
- Treat a cancelled screen picker, missing permission, and a stopped share as ordinary states with clear next actions.
Measured cards, render hooks, and embedded sizing
Use the dimensions measured by the component that owns the media card. Do not recalculate a second viewport size inside a card override: nested layouts, sidebars, and embedded rooms may be smaller than the browser window.
React exports these hook shapes on MainAspectComponent:
renderContent?: (options: {
defaultContent: React.ReactNode;
dimensions: {width: number; height: number};
}) => React.ReactNode;
renderContainer?: (options: {
defaultContainer: React.ReactNode;
dimensions: {width: number; height: number};
}) => React.ReactNode;
VideoCardOptions uses the same measured dimensions pair with
React.JSX.Element; React Native and Expo expose the corresponding
VideoCardOptions hooks with JSX.Element and native StyleProp<ViewStyle>.
ReactJS also exports AudioCard, MiniCard, and their option types. Use
customVideoCard, customAudioCard, and customMiniCard for complete card
replacement, or uiOverrides.videoCard, .audioCard, and .miniCard for the
typed override map.
React's MainAspectComponentOptions and SubAspectComponentOptions accept
containerWidthFraction and containerHeightFraction. The main aspect
subtracts its control-aware fraction; the sub aspect uses
defaultFractionSub. Both account for embedded containers, but the host must
still give the room a real bounded parent. Use
the embedded room layout guide for
mainAspect/subAspect override examples.
What you render with differs by package:
| SDK | Rendering surface |
|---|---|
| ReactJS | Measured renderContent/renderContainer, card option types, mainAspect/subAspect, grids, pagination, and headless stream resolvers |
| Angular | Exported VideoCard, AudioCard, MiniCard, component override types, mainAspect/subAspect, grids, pagination, and Angular templates/components |
| Vue | Exported VideoCard, AudioCard, MiniCard, grids, pagination, and override map; MainScreenComponent provides a VNodeChild render-container contract with measured dimensions |
| React Native / Expo | Measured native card/aspect render hooks, custom cards, grids, pagination, and native stream views |
| Flutter | Widget builders, current room parameters, explicit/measured Flutter constraints, page and consumer controls |
| Android / Kotlin | Compose state and renderer ownership; do not substitute React hook signatures |
| Swift | Hosted room rendering boundary in the current public Apple package |
| Unity | Scene-owned renderers and explicit consumer controls |
| Shared core | State and media helpers only; no rendered cards or container hooks |
For a custom self view with a saved background, select
keepBackground && virtualStream ? virtualStream : localStreamVideo, or use
React's getLocalVideoStream. See the
complete virtual-background guide.
Share the sound of a tab or screen
The browser packages and Flutter web can publish the sound of a shared tab or screen alongside the picture. When someone starts a share in a desktop Chromium browser (Chrome, Edge, Opera, or Brave), the room asks whether to share Screen + audio or Screen only. The audio travels as its own track: it pauses and stops with the share, never mixes into the microphone, and never marks the sharer as speaking. Listeners hear it through a "name · Screen audio" card that each person can mute for themselves.
The screen-audio mode sets the behavior: ask (the default) shows the choice,
always shares audio without asking, and never shares video only. Firefox,
Safari, mobile browsers, and native mobile apps share video only, though
native apps still play screen audio from others. Screen audio also needs a
media server that supports it; otherwise sharing stays video-only. Each SDK
section below names its setting.
ReactJS 4.4.2
Use ModernMediasfuGeneric or a supplied room first. The package also supplies
FlexibleGrid, FlexibleVideo, VideoCard, AudioCard, Pagination,
Screenboard, ScreenboardModal, Whiteboard, and
ConfigureWhiteboardModal for a custom room surface.
For an existing live room, clickScreenShare is the screen-share control.
streamSuccessVideo, streamSuccessAudio, and streamSuccessScreen are the
matching media pipeline functions; resumePauseStreams is for active-stream
state. They need the full live room dependencies, so keep them behind the room
runtime rather than calling them from a page with guessed state.
import { clickScreenShare } from 'mediasfu-reactjs';
export type ScreenShareRequest = Parameters<typeof clickScreenShare>[0];
export const toggleScreenShare = (request: ScreenShareRequest) =>
clickScreenShare(request);
Screen audio follows the room's screenAudioMode; change it with
updateScreenAudioMode('ask' | 'always' | 'never') or turn it off with
updateScreenAudioEnabled on the room parameters. toggleScreenAudio lets the
sharer mute only the shared sound, and ScreenAudioPrompt and
ScreenAudioPlayer are exported if you build your own prompt or listener card.
Screenboard and whiteboard are separate experiences. Do not label a whiteboard as screen capture, or claim that an arbitrary canvas is automatically shared.
Angular 2.5.0
Use the supplied MediaSFU room component and its rendered display components.
Angular publishes Screenboard, ScreenboardModal, Whiteboard,
ConfigureWhiteboardModal, FlexibleGrid, FlexibleVideo, and Pagination.
The public API also includes the screen-share and consumer services used by the
room.
Inject the screen-share action once and pass it the complete parameter object owned by the mounted room. This avoids rebuilding socket, permission, and producer state in the button component:
import {Injectable} from '@angular/core';
import {
ClickScreenShare,
type ClickScreenShareOptions,
} from 'mediasfu-angular';
@Injectable({providedIn: 'root'})
export class RoomScreenShare {
constructor(private readonly action: ClickScreenShare) {}
toggle(
parameters: ClickScreenShareOptions['parameters'],
): Promise<void> {
return this.action.clickScreenShare({parameters});
}
}
Every Angular room component accepts screenAudioMode (ask, always, or
never), screenAudioEnabled, and screenAudioPrompt inputs for screen-share
audio. ScreenAudioPromptComponent, ScreenAudioPlayer, and
toggleScreenAudio are exported for custom surfaces.
Keep those services attached to the same current room parameters the supplied room uses. Do not build a raw-stream renderer from partial transport state. Test screen capture on every browser your Angular app supports: picker behavior and system permission prompts are browser-owned.
Vue 1.3.0
Use the supplied Vue room for rendered media. Vue publishes clickScreenShare
for the active-room share action, and FlexibleGrid, FlexibleVideo,
VideoCard, AudioCard, MiniCard, Pagination, Screenboard,
ScreenboardModal, and ConfigureWhiteboardModal for a custom surface. The
whiteboard canvas itself is part of the supplied room rather than a separate
export.
import { clickScreenShare } from 'mediasfu-vue';
export type ScreenShareRequest = Parameters<typeof clickScreenShare>[0];
export const toggleScreenShare = (request: ScreenShareRequest) =>
clickScreenShare(request);
The room components accept screenAudioMode, screenAudioEnabled, and
screenAudioPrompt props for screen-share audio; ScreenAudioPrompt,
ScreenAudioPlayer, and toggleScreenAudio are exported for custom surfaces.
React Native 2.5.0
Use a supplied room or ModernMediasfuGeneric to render media. The package
also publishes FlexibleGrid, FlexibleVideo, VideoCard, AudioCard,
Pagination, Screenboard, ScreenboardModal, Whiteboard, and
ConfigureWhiteboardModal.
clickScreenShare controls the active-room screen share. streamSuccessVideo,
streamSuccessAudio, streamSuccessScreen, and resumePauseStreams are
available for the same complete room runtime.
import { clickScreenShare } from 'mediasfu-reactnative';
export type ScreenShareRequest = Parameters<typeof clickScreenShare>[0];
export const toggleScreenShare = (request: ScreenShareRequest) =>
clickScreenShare(request);
Screen capture availability differs across Android and iOS. Test the native permission prompt, picker cancellation, app backgrounding, and stop flow on physical devices before release.
Android and iOS apps play the screen audio others share but cannot share their
own. A React Native web build in a desktop Chromium browser can share it,
controlled with updateScreenAudioMode and updateScreenAudioEnabled on the
room parameters.
Expo 2.6.0
Use a supplied room or ModernMediasfuGeneric for rendered media. Expo
publishes the same named rendered media, board, and pagination components as
the React Native package, including FlexibleGrid, Pagination, Screenboard,
and Whiteboard.
clickScreenShare, streamSuccessVideo, streamSuccessAudio,
streamSuccessScreen, and resumePauseStreams are public active-room tools.
import { clickScreenShare } from 'mediasfu-reactnative-expo';
export type ScreenShareRequest = Parameters<typeof clickScreenShare>[0];
export const toggleScreenShare = (request: ScreenShareRequest) =>
clickScreenShare(request);
Expo screen capture and rendering must be tested separately on Android, iOS,
and web. Do not promise identical capture behavior across those targets. Only
Expo web in a desktop Chromium browser can share screen audio (set with
updateScreenAudioMode and updateScreenAudioEnabled); Android and iOS
apps play it but cannot share it.
Flutter 2.4.1
Use MediasfuGeneric for the complete rendered room. The package exports
clickScreenShare for the active room and supplies Screenboard,
ScreenboardModal, Whiteboard, and ConfigureWhiteboardModal as separate
board experiences.
import 'package:mediasfu_sdk/mediasfu_sdk.dart';
Future<void> toggleRoomScreenShare(ClickScreenShareOptions options) {
return clickScreenShare(options);
}
Pass the options from the current room runtime; do not construct a partial room/media state. Flutter screen capture differs by target platform. Test the picker, permission denial, application backgrounding, and stop flow on every mobile, web, or desktop target you release.
On Flutter web in a desktop Chromium browser, a share can carry screen audio.
Configure it with MediasfuScreenAudio.mode, MediasfuScreenAudio.enabled,
and MediasfuScreenAudio.prompt; the sharer can mute it with
MediasfuScreenAudio.toggle. Every Flutter platform plays screen audio from
others; native apps share video only.
The supplied screenboard and whiteboard support board drawing. They do not turn every captured screen into an annotatable surface.
Android 1.0.8
The Android artifact supplies the Compose room shapes through its own Android
publication. MediasfuGeneric renders participants and room controls;
MediasfuGenericState.toggleScreenShare() starts or stops the Android capture
flow after permission is granted.
Button(onClick = state::toggleScreenShare) {
Text("Share screen")
}
Use the supplied screenboard or whiteboard for drawing. They are collaborative board surfaces, not an annotation layer over every shared screen. Test capture permission, system stop, backgrounding, and rotation on real Android devices.
Kotlin Multiplatform 1.0.8
Use the Compose MediasfuGeneric workspace to keep room state, rendered media,
and controls together. clickScreenShare operates on the current room
parameters. The supplied whiteboard UI is a separate collaborative surface.
import com.mediasfu.sdk.methods.stream_methods.ClickScreenShareOptions
import com.mediasfu.sdk.methods.stream_methods.clickScreenShare
suspend fun toggleRoomScreenShare(options: ClickScreenShareOptions) {
clickScreenShare(options)
}
Android and iOS capture implementations have different permission and background behavior. Test both targets independently. Keep board permissions and screen-capture permissions separate in your product UI.
Swift and Apple platforms 0.1.3
MediaSFUIosHostBridge presents the hosted participant and media UI. Call
triggerToggleScreenShare() from an app-owned control after the ReplayKit
broadcast extension is configured.
if !bridge.triggerToggleScreenShare() {
showMessage("Open the room before sharing your screen.")
}
The hosted room renders local and remote media. The shared board remains a separate collaboration surface; it is not an automatic drawing layer over a ReplayKit broadcast. Test start, system stop, interruption, and cleanup on the Apple devices you ship.
Unity 0.1.0-preview.2
Unity is an application-owned renderer. Use SetScreenShareEnabledAsync for
screen share and render the resulting room/media state in your scene. Unity
also publishes whiteboard lifecycle and action methods, including
StartOrUpdateWhiteboardAsync, SendWhiteboardActionAsync,
UpdateWhiteboardShapesAsync, ClearWhiteboardAsync, and
StopWhiteboardAsync.
using System.Threading.Tasks;
using MediaSFU.Unity;
using UnityEngine;
static async Task EnableScreenShare(MediaSfuClient client)
{
var result = await client.SetScreenShareEnabledAsync(true);
if (!result.Success)
{
Debug.LogError(result.Error);
}
}
The whiteboard is not a drawing overlay for a captured desktop. Your scene owns how whiteboard shapes are rendered and how pointer coordinates map to the board. Stop the whiteboard and screen share through their separate controls.
Shared core 1.3.1
The shared core provides low-level media functions, not a rendered room. It
publishes clickScreenShare, streamSuccessVideo, streamSuccessAudio,
streamSuccessScreen, resumePauseStreams, handleStartWhiteboard,
handleStopWhiteboard, and launchConfigureWhiteboard.
import { clickScreenShare, handleStartWhiteboard } from 'mediasfu-shared';
export type ScreenShareRequest = Parameters<typeof clickScreenShare>[0];
export type StartWhiteboardRequest = Parameters<typeof handleStartWhiteboard>[0];
For screen-share audio, the shared core exports connectSendTransportScreenAudio,
toggleScreenAudio, setScreenAudioVolume, isScreenAudioProducer, and
canCaptureDisplayAudio; your framework renders the prompt and the listener's
audio card.
Your framework owns the visible video cards, audio output, pagination, board canvas, accessibility labels, and cleanup. A shared-core helper does not create a player or grant a browser/native capture permission.
When a share stops or a stream is paused
Keep the room UI alive long enough to show the new state. Remove the stopped screen from the rendered layout, retain cameras that are still active, and let the person start sharing again. Never silently restart screen capture after a picker cancellation, a permission denial, backgrounding, or a disconnect.
For pagination, keep the participant list separate from the current display
page. A page change must update the visible names and then reconcile consumers.
Do not infer success from the new page number: wait until each newly visible
consumer is active, and release renderers and unneeded consumers that left the
page. The SDK's autoAdjust helper chooses a layout split; it does not create
pages or acknowledge remote media.
Release checklist
- The room shows rendered cards or grids rather than an unrendered stream.
- Screen-share start, cancel, stop, and lost-permission states each have a clear message.
- A stopped screen disappears without stopping unrelated camera or audio.
- Pagination is tested with more people than fit on one page.
- Board and screen-share labels are distinct in the product UI.
- Custom UI owns its own renderers, listeners, and app-created tracks.
- Browser and native targets are tested separately where applicable.