UNPKG

mediasfu-angular

Version:

mediasfu-angular - Angular 17/18/19 WebRTC SDK for video conferencing, webinars, broadcasts, live streaming, chat, recording, whiteboard, and AI agents. Prebuilt rooms and fully custom UIs.

1,240 lines (994 loc) β€’ 204 kB
# MediaSFU Angular SDK Β· [mediasfu-angular on npm](https://www.npmjs.com/package/mediasfu-angular) **mediasfu-angular** is the Angular 17/18/19 WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms β€” powered by MediaSFU Cloud or your self-hosted MediaSFU Open server. Install with `npm install mediasfu-angular`. --- <p align="center"> <img src="https://www.mediasfu.com/logo192.png" width="100" alt="MediaSFU Logo"> </p> <p align="center"> <a href="https://twitter.com/media_sfu"> <img src="https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white" alt="Twitter" /> </a> <a href="https://www.mediasfu.com/forums"> <img src="https://img.shields.io/badge/Community-Forum-blue?style=for-the-badge&logo=discourse&logoColor=white" alt="Community Forum" /> </a> <a href="https://github.com/MediaSFU"> <img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="Github" /> </a> <a href="https://www.mediasfu.com/"> <img src="https://img.shields.io/badge/Website-4285F4?style=for-the-badge&logo=google-chrome&logoColor=white" alt="Website" /> </a> <a href="https://www.youtube.com/channel/UCELghZRPKMgjih5qrmXLtqw"> <img src="https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white" alt="Youtube" /> </a> </p> <p align="center"> <a href="https://opensource.org/licenses/MIT"> <img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" alt="License: MIT" /> </a> <a href="https://mediasfu.com"> <img src="https://img.shields.io/badge/Built%20with-MediaSFU-blue?style=flat-square" alt="Built with MediaSFU" /> </a> <a href="https://angular.io"> <img src="https://img.shields.io/badge/Angular-DD0031?style=flat-square&logo=angular&logoColor=white" alt="Angular" /> </a> <a href="https://www.typescriptlang.org"> <img src="https://img.shields.io/badge/TypeScript-007ACC?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" /> </a> </p> --- ## Build real-time communication into Angular **A production-oriented Angular WebRTC SDK for video meetings, voice and video calls, webinars, interactive livestreams, chat, screen sharing, recording, breakout rooms, whiteboards, polls, live captions, translation, and AI-assisted communication.** MediaSFU Angular is an Angular video conferencing SDK with prebuilt room components for meetings, webinars, livestream-style broadcasts, and chat-first rooms. It gives you production-ready room UI plus the lower-level helpers needed to move from a full prebuilt experience to a deeply customized Angular app without rewriting the media stack. ## Quick Start: First Working Room ```bash npm install mediasfu-angular ``` ```typescript credentials = { apiUserName: 'your-user', apiKey: 'your-key', }; ``` ```html <app-mediasfu-generic [credentials]="credentials" [connectMediaSFU]="true" ></app-mediasfu-generic> ``` That is the fastest path to a working Angular video conferencing room. Once the secure create/join path works, layer in branding, overrides, or a fully custom shell. ## Pick the Right Angular Room Component Use this table to match each Angular room component to the product shape you are building. | Component | Best for | What users get | When to choose it | | --- | --- | --- | --- | | `app-mediasfu-generic` | General meetings, team calls, product defaults | Balanced room layout with the broadest starter path | Start here if you are unsure which room type fits best. | | `app-mediasfu-webinar` | Host-led presentations, audience participation, stage-centric events | Webinar-style room flow with participant management and moderation surfaces | Choose this when one or a few presenters lead a larger audience. | | `app-mediasfu-broadcast` | Livestream-style shows, creator dashboards, host-first production flows | Broadcast-oriented shell with invite/share and host control emphasis | Choose this when the host workflow matters more than equal participant presence. | | `app-mediasfu-chat` | Text-first support rooms, low-bandwidth collaboration, chat-centric experiences | Message-forward room UI with the same create/join/runtime foundation | Choose this when conversation is the product and audio/video are secondary. | | `app-mediasfu-conference` | Collaborative multi-speaker events, panels, classes, workshops | Multi-participant conference layout with richer shared-presence expectations | Choose this when many participants are expected to be visibly active. | ## Least Confusing Start Path 1. Start with `app-mediasfu-generic` and validate one successful create/join flow. 2. Decide backend mode early: MediaSFU Cloud or self-hosted MediaSFU Open. 3. Move to `app-mediasfu-webinar`, `app-mediasfu-broadcast`, or `app-mediasfu-chat` only after the base room flow is working. 4. Use `uiOverrides`, custom cards, and `customMainComponent` before going fully headless. 5. Switch to `returnUI="false"` only when you already know which MediaSFU runtime helpers your product needs. ## Common Angular Product Shapes Use MediaSFU Angular when you need one of these product patterns: - Angular video meeting UI with secure create/join flow. - Angular webinar UI with host, audience, and moderation surfaces. - Angular broadcast UI for livestream or creator-style host workflows. - Angular chat room UI with MediaSFU room orchestration behind it. - Angular collaboration rooms with recording, screen share, whiteboard, polls, captions, and translation in one SDK. ## Why teams use MediaSFU Angular - **Start fast** with prebuilt room components such as `MediasfuGeneric`, `MediasfuConference`, `MediasfuWebinar`, `MediasfuBroadcast`, and `MediasfuChat`. - **Customize progressively** with `uiOverrides`, custom cards, custom layouts, and shared room helper state. - **Go headless when needed** by setting `returnUI="false"` and wiring MediaSFU runtime helpers into your own Angular workspace. - **Ship collaboration features together**: voice, video, screen share, recording, whiteboard, breakout rooms, chat, polls, and translation in one SDK. ## Choose Your Path - **Beginner**: install the package, render a prebuilt room, and connect to MediaSFU Cloud or your self-hosted server. - **Intermediate**: override cards, modals, and layout surfaces while keeping MediaSFU's room orchestration and transports. - **Advanced**: run the runtime headless, consume `sourceParameters`, and build a fully custom Angular UI on top of the same media/session core. ## Important: Backend Required MediaSFU Angular is a frontend SDK. You still need a MediaSFU-compatible backend for signaling, media routing, and room lifecycle. | Option | Best for | Link | | --- | --- | --- | | **MediaSFU Cloud** | Managed production deployments, faster onboarding, less infrastructure work | [MediaSFU Cloud docs](https://www.mediasfu.com/documentation#rooms) | | **MediaSFU Open** | Self-hosting, local control, private infrastructure | [MediaSFU Open](https://github.com/MediaSFU/MediaSFUOpen) | ## Common questions ### Is MediaSFU Angular only a collection of UI components? No. The package includes prebuilt Angular room UI and the browser-side WebRTC/session runtime. A MediaSFU-compatible backend still provides signaling, room lifecycle, and SFU media routing. ### Can I preserve my Angular design system? Yes. Replace targeted surfaces through `uiOverrides`, custom cards, and `customMainComponent`. Set `[returnUI]="false"` when your Angular application should own the complete visual shell. ### Can I run MediaSFU on my own infrastructure? Yes. Pass `localLink` to connect the Angular SDK to MediaSFU Open, or use MediaSFU Cloud for managed room and media infrastructure. ### Which room and collaboration workflows are supported? The SDK covers meetings, conferences, webinars, broadcasts, and chat-first rooms with screen sharing and annotation, recording, whiteboards, polls, breakout rooms, live captions, translation, and extensible AI-agent workflows. ## Start Here - Want the fastest path to a running room? Jump to [Quick Start](#quick-start-5-minutes). - Want copy-paste recipes for different integration levels? Use the [Usage Cookbook](#usage-cookbook) section just below. - Want to understand the Angular surface area first? Read [Quick Reference: Component Props & UI Overrides](#quick-reference-component-props--ui-overrides). - Want architecture and customization depth? Continue with the [Angular SDK Guide](#angular-sdk-guide). - Want self-hosted deployment context? Review [MediaSFU Open](https://github.com/MediaSFU/MediaSFUOpen) alongside this SDK guide. ## Usage Cookbook Need recipe-style Angular guidance instead of reading the full guide front to back? Use this quick picker: | Goal | Recommended setup | | --- | --- | | Ship the bundled room fast | Render `app-mediasfu-generic` with `credentials` and `connectMediaSFU="true"`. | | Use MediaSFU Open | Keep the same component and pass `localLink` to your self-hosted server. | | Run the runtime headless | Set `returnUI="false"`, pass `noUIPreJoinOptions`, and capture helpers through `updateSourceParameters`. | | Replace the main room shell | Keep MediaSFU's transports and room lifecycle, but pass `customMainComponent`. | | Override selected surfaces | Keep the default shell and layer `uiOverrides`, `customVideoCard`, `customAudioCard`, `customMiniCard`, and `containerStyle`. | Source-repo readers can also use the standalone `USAGE_COOKBOOK.md` file for copy-paste examples. --- ## Angular SDK Guide MediaSFU Community Edition remains available if you want to self-host the backend and keep full infrastructure control. If you want managed infrastructure, use MediaSFU Cloud with the same Angular SDK surface. --- ## Table of Contents - [Why teams use MediaSFU Angular](#why-teams-use-mediasfu-angular) - [Choose Your Path](#choose-your-path) - [Important: Backend Required](#important-backend-required) - [Start Here](#start-here) - [Usage Cookbook](#usage-cookbook) - [Quick Reference: Component Props & UI Overrides](#quick-reference-component-props--ui-overrides) - [Features](#features) - [Getting Started](#getting-started) - [πŸ“˜ Angular SDK Guide](#angular-sdk-guide) - [Quick Start](#quick-start-5-minutes) - [Understanding the Architecture](#understanding-mediasfu-architecture) - [Core Concepts & Components](#core-concepts--components) - [Working with Methods](#working-with-methods) - [Media Streams & Participants](#media-streams--participants) - [Customization & Styling](#customization--styling) - [API Reference](#api-reference) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) --- ## 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` input, so you can bend the bundled experience to match your product without losing MediaSFU's hardened real-time logic. ### Shared component inputs (applies to every MediaSFU UI component) | Input | Type | Default | What it does | | --- | --- | --- | --- | | `PrejoinPage` | `ComponentType` | `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>` | `{}` | Shared helper bag (media devices, participant helpers, layout handlers). Pair with `updateSourceParameters` to mirror the SDK's internal utilities. | | `updateSourceParameters` | `(data: Record<string, unknown>) => void` | `() => {}` | 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` | `Function` | `undefined` | Inject your own networking layers for joining or creating rooms. | | `canUsePersonalTranslation`, `personalTranslationUsername` | `boolean`, `string` | `false`, `undefined` | Seed translation-aware entry flows when you want personal translation defaults available at startup. | | `customMainComponent` | `ComponentType` | `undefined` | Replace the main UI shell while retaining MediaSFU transports, sockets, and room helpers. | | `customVideoCard`, `customAudioCard`, `customMiniCard` | `ComponentType` | `undefined` | Override participant card renders to add metadata, CTAs, or badges. | | `[containerStyle]` | `Record<string, any>` | `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 via `updateSourceParameters` output, and selectively bring UI pieces back with `uiOverrides`. That gives you progressive migration with minimal code churn. ```typescript import type { MediasfuUICustomOverrides } from 'mediasfu-angular'; 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 `customMainComponent`. #### What the playbook demonstrates - **Connection presets**: toggle `connectionScenario` between `cloud`, `hybrid`, or `ce` to swap credentials, local links, and connection modes in one place. - **Experience selector**: the `selectedExperience` switch renders `MediasfuGeneric`, `MediasfuBroadcast`, `MediasfuWebinar`, `MediasfuConference`, or `MediasfuChat` without touching the rest of your stack. - **UI strategy flags**: booleans like `showPrebuiltUI`, `enableFullCustomUI`, and `enableNoUIPreJoin` demonstrate how to run the MediaSFU logic with or without the bundled UI. - **Layered overrides**: toggles enable the custom video/audio/mini cards, drop-in `uiOverrides` for layout and modal surfaces, container styling, and backend proxy helpers. - **Custom workspace demo**: a `customMainComponent` receives live MediaSFU helpers so you can build dashboards, CRM surfaces, or any bespoke host interface. - **Debug panel & helpers**: optional JSON panel exposes the `updateSourceParameters` payload so you can see exactly what to wire into your own components. #### Try it quickly ```typescript @Component({ selector: 'app-custom-ui-playbook', template: ` <ng-container [ngSwitch]="selectedExperience"> <app-mediasfu-generic *ngSwitchCase="'generic'" [credentials]="currentPreset.credentials" [localLink]="currentPreset.localLink" [connectMediaSFU]="currentPreset.connectMediaSFU" [returnUI]="showPrebuiltUI" [uiOverrides]="overrides" [containerStyle]="containerStyle"> </app-mediasfu-generic> <app-mediasfu-broadcast *ngSwitchCase="'broadcast'" [credentials]="currentPreset.credentials" [localLink]="currentPreset.localLink" [connectMediaSFU]="currentPreset.connectMediaSFU" [returnUI]="showPrebuiltUI" [uiOverrides]="overrides"> </app-mediasfu-broadcast> <!-- Similar for webinar, conference, chat --> </ng-container> ` }) export class CustomUIPlaybookComponent { connectionScenario: 'cloud' | 'hybrid' | 'ce' = 'cloud'; selectedExperience: 'generic' | 'broadcast' | 'webinar' | 'conference' | 'chat' = 'generic'; showPrebuiltUI = true; enableFullCustomUI = false; 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 }, }; get currentPreset() { return this.connectionPresets[this.connectionScenario]; } overrides: MediasfuUICustomOverrides = { mainContainer: this.enableFullCustomUI ? { component: CustomMainContainerComponent } : undefined, }; containerStyle = { background: 'linear-gradient(135deg, #0f172a, #1e3a8a)', minHeight: '100vh' }; } ``` 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: ```typescript @Component({ selector: 'app-advanced-playbook', template: ` <app-mediasfu-generic [credentials]="credentials" [customVideoCard]="videoCard" [customAudioCard]="audioCard" [customMiniCard]="miniCard" [customMainComponent]="enableFullCustomUI ? customWorkspace : undefined" [containerStyle]="containerStyle" [uiOverrides]="uiOverrides"> </app-mediasfu-generic> ` }) export class AdvancedPlaybookComponent { credentials = { apiUserName: 'demo', apiKey: 'demo' }; enableFullCustomUI = false; // Custom card components with themed styling videoCard = VideoCardComponent; // Pass component class audioCard = AudioCardComponent; miniCard = MiniCardComponent; customWorkspace = CustomWorkspaceComponent; containerStyle = { background: '#0f172a', borderRadius: '32px', overflow: 'hidden' }; uiOverrides: MediasfuUICustomOverrides = { mainContainer: { component: CustomMainContainerComponent }, menuModal: { component: CustomMenuModalComponent }, consumerResume: { wrap: (original) => async (params) => { const startedAt = performance.now(); const result = await original(params); console.log('consumer_resume', { durationMs: performance.now() - startedAt, consumerId: params?.consumer?.id, }); return result; }, }, }; } ``` 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` input β€” override keys at a glance Each key accepts a `CustomComponentOverride<Props>` or `CustomFunctionOverride<Fn>` object with optional `component` and `wrap` 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. | | `translationSettingsModal` | `TranslationSettingsModal` | Customize spoken-language, subtitle, and listening-preference controls. | | `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` | `Menu button group renderer` | Supply a bespoke renderer for grouped menu actions without overriding each button one by one. | #### 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. | | `prepopulateUserMedia` | `prepopulateUserMedia` | Customize initial media setup with custom video/audio/mini cards. | > Function overrides support `{ implementation, wrap }`. Provide `implementation` for a full replacement, or `wrap` to intercept the default behavior before/after it runs. ### Example: swap the chat modal and theme the controls ```typescript import { Component } from '@angular/core'; import { MediasfuGeneric } from 'mediasfu-angular'; import { MyChatModalComponent } from './ui/my-chat-modal.component'; import { MyControlsComponent } from './ui/my-controls.component'; @Component({ selector: 'app-my-meeting', template: ` <app-mediasfu-generic [credentials]="credentials" [uiOverrides]="uiOverrides"> </app-mediasfu-generic> ` }) export class MyMeetingComponent { credentials = { apiUserName: 'your-api-user', apiKey: 'your-api-key' }; uiOverrides = { messagesModal: { component: MyChatModalComponent, }, controlButtons: { component: MyControlsComponent, }, }; } ``` ### Example: wrap a MediaSFU helper instead of replacing it ```typescript import { Component } from '@angular/core'; import { MediasfuConference } from 'mediasfu-angular'; @Component({ selector: 'app-analytics-meeting', template: ` <app-mediasfu-conference [credentials]="credentials" [uiOverrides]="uiOverrides"> </app-mediasfu-conference> ` }) export class AnalyticsMeetingComponent { credentials = { apiUserName: 'your-api-user', apiKey: 'your-api-key' }; uiOverrides = { consumerResume: { wrap: (original) => async (params) => { const startedAt = performance.now(); const result = await original(params); // Send analytics this.analytics.track('consumer_resume', { durationMs: performance.now() - startedAt, consumerId: params?.consumer?.id, }); return result; }, }, }; constructor(private analytics: AnalyticsService) {} } ``` --- # Features <a name="features"></a> MediaSFU's Angular SDK comes with a host of powerful features out of the box: 1. **Screen Sharing with Annotation Support**: Share your screen with participants and annotate in real-time for enhanced presentations and collaborations. 2. **Collaborative Whiteboards**: Create and share whiteboards for real-time collaborative drawing and brainstorming sessions. 3. **Breakout Rooms**: Create multiple sub-meetings within a single session to enhance collaboration and focus. 4. **Pagination**: Efficiently handle large participant lists with seamless pagination. 5. **Polls**: Conduct real-time polls to gather instant feedback from participants. 6. **Media Access Requests Management**: Manage media access requests with ease to ensure smooth operations. 7. **Video Effects**: Apply various video effects, including virtual backgrounds, to enhance the visual experience. 8. **Chat (Direct & Group)**: Facilitate communication with direct and group chat options. 9. **Cloud Recording (track-based)**: Customize recordings with track-based options, including watermarks, name tags, background colors, and more. 10. **Managed Events**: Manage events with features to handle abandoned and inactive participants, as well as enforce time and capacity limits. ## πŸ†• **New Advanced Media Access** The Angular SDK now includes powerful utility methods for fine-grained control over media devices and participant streams: ### **`getMediaDevicesList`** - Device Enumeration Enumerate available cameras and microphones with automatic permission handling: ```typescript // Get all available cameras const cameras = await sourceParameters.getMediaDevicesList('videoinput'); cameras.forEach(camera => { console.log(`Camera: ${camera.label} (${camera.deviceId})`); }); // Get all available microphones const microphones = await sourceParameters.getMediaDevicesList('audioinput'); microphones.forEach(mic => { console.log(`Microphone: ${mic.label} (${mic.deviceId})`); }); ``` **Use Cases:** - Build custom device selection interfaces - Detect available media hardware - Switch between multiple cameras/microphones - Pre-flight device checks before joining [See full documentation and examples β†’](#media-device-and-stream-utility-methods) --- ### **`getParticipantMedia`** - Stream Access Retrieve specific participant's video or audio streams by ID or name: ```typescript // Get participant video stream by producer ID const videoStream = await sourceParameters.getParticipantMedia({ id: 'producer-123', kind: 'video' }); // Get participant audio stream by name const audioStream = await sourceParameters.getParticipantMedia({ name: 'John Doe', kind: 'audio' }); // Use the stream (e.g., attach to video element) if (videoStream) { videoElement.srcObject = videoStream; } ``` **Use Cases:** - Monitor specific participant streams - Create custom video layouts with individual control - Build stream recording features - Implement advanced audio/video processing - Create picture-in-picture views for specific users [See full documentation and examples β†’](#media-device-and-stream-utility-methods) --- These utilities enable advanced features like custom device selection interfaces, participant stream monitoring, and dynamic media routing. Both methods are fully integrated with Angular's reactive patterns using RxJS. # Getting Started <a name="getting-started"></a> This section will guide users through the initial setup and installation of the npm module. ### Documentation Reference For comprehensive documentation on the available methods, components, and functions, please visit [mediasfu.com](https://www.mediasfu.com/angular/). 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** ```bash npm install mediasfu-angular bootstrap ngx-cookie-service socket.io-client mediasoup-client @fortawesome/angular-fontawesome @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-brands-svg-icons # Optional but recommended for virtual backgrounds and scanner-based flows npm install @mediapipe/selfie_segmentation @zxing/ngx-scanner ``` ### 2. **Bootstrap Integration** The `mediasfu-angular` package expects Bootstrap as a peer dependency. If your Angular app does not already ship with Bootstrap, install it and ensure Bootstrap's CSS is added to your project's styles. 1. **Check `angular.json`:** Ensure that `node_modules/bootstrap/dist/css/bootstrap.min.css` is listed in the `styles` array of your Angular application's build options. ```json { "projects": { "your-app-name": { "architect": { "build": { "options": { "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css" ], // ... other configurations } } } } } } ``` **Note:** `mediasfu-angular` does not bundle Bootstrap for you. Keep the CSS import explicit so your app and the SDK agree on styling. ### 3. **Configure MediaSFU's PreJoinPage Requirements** If you intend to use MediaSFU's `PreJoinPage` component, additional configuration is required. Provide `HttpClient` and `CookieService` in your application's configuration, and make sure `ngx-cookie-service` is installed in your Angular app. #### Update `app.config.ts` Add the necessary providers to your `app.config.ts` file. Below is an example configuration: ```typescript // app.config.ts import { ApplicationConfig } from '@angular/core'; import { provideZoneChangeDetection } from '@angular/core'; import { provideClientHydration } from '@angular/platform-browser'; import { provideHttpClient } from '@angular/common/http'; import { CookieService } from 'ngx-cookie-service'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideClientHydration(), provideHttpClient(), CookieService ], }; ``` ### 4. Obtain an API Key (If Required) You can get your API key by signing up or logging into your account at [mediasfu.com](https://www.mediasfu.com/). <div style="background-color:#f0f0f0; padding: 10px; border-radius: 5px;"> <h4 style="color:#d9534f;">Important:</h4> <p style="font-size: 1.2em; color: black;">You must obtain an API key from <a href="https://www.mediasfu.com/">mediasfu.com</a> to use this package with MediaSFU Cloud. You do not need the API Key if self-hosting.</p> </div> ## **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](https://github.com/MediaSFU/MediaSFUOpen). This setup allows full flexibility and customization while bypassing the need for cloud-dependent credentials. # πŸ“˜ Angular SDK Guide <a name="angular-sdk-guide"></a> This comprehensive guide will walk you through everything you need to know about building real-time communication apps with MediaSFU's Angular SDK. Whether you're a beginner or an experienced developer, you'll find clear explanations, practical examples, and best practices. --- ## Quick Start (5 Minutes) <a name="quick-start-5-minutes"></a> Get your first MediaSFU app running in just a few minutes. ### Step 1: Install the Package ```bash npm install mediasfu-angular ``` ### Step 2: Import and Use ```typescript // app.component.ts import { Component } from '@angular/core'; import { MediasfuGeneric } from 'mediasfu-angular'; @Component({ selector: 'app-root', standalone: true, imports: [MediasfuGeneric], template: `<app-mediasfu-generic></app-mediasfu-generic>`, }) export class AppComponent { } ``` **Alternative with Credentials:** ```typescript import { Component } from '@angular/core'; import { MediasfuGeneric, PreJoinPage } from 'mediasfu-angular'; @Component({ selector: 'app-root', standalone: true, imports: [MediasfuGeneric], template: ` <app-mediasfu-generic [PrejoinPage]="PreJoinPage" [credentials]="credentials"> </app-mediasfu-generic> `, }) export class AppComponent { PreJoinPage = PreJoinPage; credentials = { apiUserName: 'your_username', apiKey: 'your_api_key', }; } ``` ### Step 3: Run Your App ```bash ng serve ``` **That'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 and whiteboards --- ## Understanding MediaSFU Architecture <a name="understanding-mediasfu-architecture"></a> Before diving deeper, let's understand how MediaSFU is structured. ### The Three-Layer Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Your Angular Application β”‚ β”‚ (components, services, business logic) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MediaSFU Components Layer β”‚ β”‚ (MediasfuGeneric, MediasfuBroadcast, etc.) β”‚ β”‚ - Pre-built UI components β”‚ β”‚ - Event handling β”‚ β”‚ - State management (RxJS) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MediaSFU Core Methods Layer β”‚ β”‚ (Stream control, room management, β”‚ β”‚ WebRTC handling, socket communication) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MediaSFU Backend Services β”‚ β”‚ (MediaSFU Cloud or Community Edition) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Key Concepts #### 1. **Event Room Types** MediaSFU provides 5 specialized room types, each optimized for specific use cases: | Room Type | Best For | Key Features | |-----------|----------|--------------| | **MediasfuGeneric** | General purpose meetings | Flexible layout, all features enabled | | **MediasfuBroadcast** | Live streaming events | Optimized for one-to-many communication | | **MediasfuWebinar** | Educational sessions | Presenter focus, Q&A features | | **MediasfuConference** | Business meetings | Equal participant layout, collaboration tools | | **MediasfuChat** | Interactive discussions | Chat-first interface, quick connections | ```typescript // Choose the right room type for your use case import { MediasfuWebinar, MediasfuBroadcast, MediasfuConference } from 'mediasfu-angular'; @Component({ // For a webinar template: `<app-mediasfu-webinar [credentials]="credentials"></app-mediasfu-webinar>`, // For a broadcast // template: `<app-mediasfu-broadcast [credentials]="credentials"></app-mediasfu-broadcast>`, // For a conference // template: `<app-mediasfu-conference [credentials]="credentials"></app-mediasfu-conference>`, }) ``` #### 2. **The Three Usage Modes** MediaSFU offers three progressive levels of customization: ##### Mode 1: Default UI (Beginner / Fastest Path) Use MediaSFU's complete pre-built interface - perfect for rapid development. ```typescript import { Component } from '@angular/core'; import { MediasfuGeneric } from 'mediasfu-angular'; @Component({ selector: 'app-root', standalone: true, imports: [MediasfuGeneric], template: `<app-mediasfu-generic [credentials]="credentials"></app-mediasfu-generic>`, }) export class AppComponent { credentials = { apiUserName: 'username', apiKey: 'key' }; } ``` **When to use:** - βœ… Prototyping or MVP development - βœ… Need a production-ready UI quickly - βœ… Standard video conferencing features are sufficient ##### Mode 2: Headless Runtime + Custom UI (Intermediate) Build your own UI while using MediaSFU's powerful backend infrastructure. ```typescript import { Component, OnInit } from '@angular/core'; import { MediasfuGeneric } from 'mediasfu-angular'; @Component({ selector: 'app-root', standalone: true, imports: [MediasfuGeneric, CommonModule], template: ` <app-mediasfu-generic [returnUI]="false" [sourceParameters]="sourceParameters" [updateSourceParameters]="updateSourceParameters.bind(this)" [credentials]="credentials" [noUIPreJoinOptions]="preJoinOptions"> </app-mediasfu-generic> <!-- Your custom UI --> @if (sourceParameters) { <div class="custom-controls"> <button (click)="toggleVideo()"> {{ sourceParameters.videoAlreadyOn ? 'Stop Video' : 'Start Video' }} </button> <button (click)="toggleAudio()"> {{ sourceParameters.audioAlreadyOn ? 'Mute' : 'Unmute' }} </button> <button (click)="toggleScreenShare()"> {{ sourceParameters.screenAlreadyOn ? 'Stop Sharing' : 'Share Screen' }} </button> </div> } `, }) export class AppComponent implements OnInit { sourceParameters: any = null; credentials = { apiUserName: 'username', apiKey: 'key' }; preJoinOptions = { action: 'create', userName: 'Your Name', capacity: 50, duration: 30, eventType: 'conference' }; updateSourceParameters(params: any) { this.sourceParameters = params; } toggleVideo() { this.sourceParameters?.clickVideo({ parameters: this.sourceParameters }); } toggleAudio() { this.sourceParameters?.clickAudio({ parameters: this.sourceParameters }); } toggleScreenShare() { this.sourceParameters?.clickScreenShare({ parameters: this.sourceParameters }); } } ``` **When to use:** - βœ… Need complete control over UI/UX - βœ… Building a custom branded experience - βœ… Integrating into existing app design ##### Mode 3: Custom Main Shell (Advanced) Replace specific MediaSFU components while keeping the rest of the infrastructure. ```typescript import { Component } from '@angular/core'; import { MediasfuGeneric, PreJoinPage, FlexibleVideo, FlexibleGrid } from 'mediasfu-angular'; @Component({ selector: 'app-custom-main', standalone: true, imports: [FlexibleVideo, FlexibleGrid, CommonModule], template: ` <div class="custom-layout"> <!-- Custom header --> <div class="custom-header"> <h1>{{ parameters.roomName }}</h1> <span>{{ parameters.participants.length }} participants</span> </div> <!-- Use MediaSFU's components in your layout --> <app-flexible-video [customWidth]="windowWidth" [customHeight]="600" [parameters]="parameters"> </app-flexible-video> <app-flexible-grid [customWidth]="windowWidth" [customHeight]="400" [parameters]="parameters"> </app-flexible-grid> <!-- Custom footer --> <div class="custom-footer"> <button (click)="toggleVideo()"> {{ parameters.videoAlreadyOn ? 'Stop Video' : 'Start Video' }} </button> </div> </div> `, styles: [` .custom-layout { display: flex; flex-direction: column; height: 100vh; } .custom-header { padding: 20px; background: #1976d2; color: white; } `] }) export class CustomMainComponent { parameters: any; windowWidth = window.innerWidth; toggleVideo() { this.parameters?.clickVideo({ parameters: this.parameters }); } } @Component({ selector: 'app-root', standalone: true, imports: [MediasfuGeneric], template: ` <app-mediasfu-generic [credentials]="credentials" [PrejoinPage]="PreJoinPage" [customMainComponent]="CustomMainComponent"> </app-mediasfu-generic> `, }) export class AppComponent { PreJoinPage = PreJoinPage; CustomMainComponent = CustomMainComponent; credentials = { apiUserName: 'username', apiKey: 'key' }; } ``` **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 #### 3. **Parameters: Your Control Center** The `sourceParameters` object (or `parameters` in custom components) is your gateway to all MediaSFU functionality. It's powered by RxJS BehaviorSubjects for reactive state management: ```typescript // Available in sourceParameters or parameters object { // Media Controls (Methods) clickVideo: (options) => {}, clickAudio: (options) => {}, clickScreenShare: (options) => {}, // Room State (BehaviorSubject values) roomName: 'meeting-123', participants: [...], allVideoStreams: [...], allAudioStreams: [...], // UI State (BehaviorSubject values) videoAlreadyOn: false, audioAlreadyOn: false, screenAlreadyOn: false, // Update Functions (BehaviorSubject next()) updateVideoAlreadyOn: (value) => {}, updateAudioAlreadyOn: (value) => {}, // And 200+ more properties and methods... } ``` **Access patterns:** ```typescript // In Mode 1 (Default UI): Parameters are managed internally // You don't need to access them directly // In Mode 2 (Custom UI): Access via sourceParameters sourceParameters?.clickVideo({ parameters: sourceParameters }); // In Mode 3 (Custom Main Shell): Passed to your custom main component @Component({ template: `<button (click)="toggleVideo()">Toggle</button>` }) export class CustomRoomShellComponent { @Input() parameters: any; toggleVideo() { this.parameters.clickVideo({ parameters: this.parameters }); } } // Subscribing to reactive state changes sourceParameters.participants.subscribe((participants) => { console.log('Participants updated:', participants); }); ``` --- ## Core Concepts & Components <a name="core-concepts--components"></a> Now that you understand the architecture, let's explore the building blocks. ### 1. Display Components: Building Your Video Layout MediaSFU provides powerful components for organizing and displaying media streams. #### Primary Layout Components **FlexibleVideo** - Main video display area ```typescript import { FlexibleVideo } from 'mediasfu-angular'; @Component({ template: ` <app-flexible-video [customWidth]="windowWidth" [customHeight]="600" [parameters]="parameters"> </app-flexible-video> ` }) ``` - Automatically handles main presenter or screen share - Smooth transitions between different video sources - Responsive sizing **FlexibleGrid** - Participant grid layout ```typescript import { FlexibleGrid } from 'mediasfu-angular'; @Component({ template: ` <app-flexible-grid [customWidth]="windowWidth" [customHeight]="800" [parameters]="parameters"> </app-flexible-grid> ` }) ``` - Intelligent grid sizing (2x2, 3x3, 4x4, etc.) - Pagination for large participant lists - Automatic reflow on window resize **AudioGrid** - Audio-only participants ```typescript import { AudioGrid } from 'mediasfu-angular'; @Component({ template: `<app-audio-grid [parameters]="parameters"></app-audio-grid>` }) ``` - Displays participants without video - Audio level indicators - Compact layout for efficiency #### Container Components | Component | Purpose | Use Case | |-----------|---------|----------| | **MainContainerComponent** | Primary content wrapper | Wraps all main content areas | | **MainAspectComponent** | Aspect ratio container | Maintains proper video proportions | | **MainScreenComponent** | Screen layout manager | Organizes screen regions | | **SubAspectComponent** | Secondary content container | For picture-in-picture, sidebars | **Example: Building a custom layout** ```typescript import { Component } from '@angular/core'; import { MainContainerComponent, FlexibleVideo, FlexibleGrid, AudioGrid } from 'mediasfu-angular'; @Component({ selector: 'app-custom-layout', standalone: true, imports: [ MainContainerComponent, FlexibleVideo, FlexibleGrid, AudioGrid, CommonModule ], template: ` <app-main-container-component> <div class="layout-container"> <!-- Main video area --> <div class="main-video"> <app-flexible-video [customWidth]="windowWidth" [customHeight]="windowHeight * 0.6" [parameters]="parameters"> </app-flexible-video> </div> <!-- Participant grid --> <div class="participant-grid"> <app-flexible-grid [customWidth]="windowWidth" [customHeight]="windowHeight * 0.3" [parameters]="parameters"> </app-flexible-grid> </div> <!-- Audio-only participants --> <div class="audio-participants"> <app-audio-grid [parameters]="parameters"></app-audio-grid> </div> </div> </app-main-container-component> `, styles: [` .layout-container { display: flex; flex-direction: column; height: 100vh; } .main-video { flex: 3; } .participant-grid { flex: 2; } .audio-participants { height: 80px; } `] }) export class CustomLayoutComponent { @Input() parameters: any; windowWidth = window.innerWidth; windowHeight = window.innerHeight; } ``` ### 2. Control Components: User Interactions **ControlButtonsComponent** - Standard control bar ```typescript import { ControlButtonsComponent } from 'mediasfu-angular'; @Component({ template: ` <