Skip to main content

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:

SDKRendering surface
ReactJSMeasured renderContent/renderContainer, card option types, mainAspect/subAspect, grids, pagination, and headless stream resolvers
AngularExported VideoCard, AudioCard, MiniCard, component override types, mainAspect/subAspect, grids, pagination, and Angular templates/components
VueExported VideoCard, AudioCard, MiniCard, grids, pagination, and override map; MainScreenComponent provides a VNodeChild render-container contract with measured dimensions
React Native / ExpoMeasured native card/aspect render hooks, custom cards, grids, pagination, and native stream views
FlutterWidget builders, current room parameters, explicit/measured Flutter constraints, page and consumer controls
Android / KotlinCompose state and renderer ownership; do not substitute React hook signatures
SwiftHosted room rendering boundary in the current public Apple package
UnityScene-owned renderers and explicit consumer controls
Shared coreState 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.