mediasfu-angular 2.1.6 β 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +447 -0
- package/dist/README.md +447 -0
- package/dist/fesm2022/mediasfu-angular.mjs +1736 -1079
- package/dist/fesm2022/mediasfu-angular.mjs.map +1 -1
- package/dist/lib/@types/custom-component.types.d.ts +130 -0
- package/dist/lib/@types/types.d.ts +5 -0
- package/dist/lib/components/mediasfu-components/mediasfu-broadcast.component.d.ts +47 -17
- package/dist/lib/components/mediasfu-components/mediasfu-chat.component.d.ts +47 -17
- package/dist/lib/components/mediasfu-components/mediasfu-conference.component.d.ts +57 -21
- package/dist/lib/components/mediasfu-components/mediasfu-generic.component.d.ts +57 -21
- package/dist/lib/components/mediasfu-components/mediasfu-webinar.component.d.ts +57 -21
- package/dist/lib/consumers/add-videos-grid.service.d.ts +3 -0
- package/dist/lib/consumers/prepopulate-user-media.service.d.ts +3 -0
- package/dist/lib/methods/utils/create-room-on-media-sfu.service.d.ts +10 -8
- package/dist/lib/services/custom-component-injection.service.d.ts +86 -0
- package/dist/public-api.d.ts +1 -0
- package/package.json +15 -15
package/dist/README.md
CHANGED
|
@@ -20,6 +20,26 @@
|
|
|
20
20
|
</a>
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## π¨ **BREAKING: AI Phone Agents at $0.10 per 1,000 minutes**
|
|
26
|
+
|
|
27
|
+
π **Call our live AI demos right now:**
|
|
28
|
+
- πΊπΈ **+1 (785) 369-1724** - Mixed Support Demo
|
|
29
|
+
- π¬π§ **+44 7445 146575** - AI Conversation Demo
|
|
30
|
+
- π¨π¦ **+1 (587) 407-1990** - Technical Support Demo
|
|
31
|
+
- π¨π¦ **+1 (647) 558-6650** - Friendly AI Chat Demo
|
|
32
|
+
|
|
33
|
+
**Traditional providers charge $0.05 per minute. We charge $0.10 per 1,000 minutes. That's 500x cheaper.**
|
|
34
|
+
|
|
35
|
+
β
**Deploy AI phone agents in 30 minutes**
|
|
36
|
+
β
**Works with ANY SIP provider** (Twilio, Telnyx, Zadarma, etc.)
|
|
37
|
+
β
**Seamless AI-to-human handoffs**
|
|
38
|
+
β
**Real-time call analytics & transcription**
|
|
39
|
+
|
|
40
|
+
π **[Complete SIP/PSTN Documentation β](https://mediasfu.com/telephony)**
|
|
41
|
+
|
|
42
|
+
---
|
|
23
43
|
|
|
24
44
|
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.
|
|
25
45
|
|
|
@@ -48,6 +68,7 @@ MediaSFU offers a cutting-edge streaming experience that empowers users to custo
|
|
|
48
68
|
- [Basic Usage Guide](#basic-usage-guide)
|
|
49
69
|
- [Intermediate Usage Guide](#intermediate-usage-guide)
|
|
50
70
|
- [Advanced Usage Guide](#advanced-usage-guide)
|
|
71
|
+
- [Custom Component Injection Service](#custom-component-injection-service)
|
|
51
72
|
- [API Reference](#api-reference)
|
|
52
73
|
- [Troubleshooting](#troubleshooting)
|
|
53
74
|
- [Contributing](#contributing)
|
|
@@ -209,6 +230,103 @@ import { MediasfuGeneric } from 'mediasfu-angular';
|
|
|
209
230
|
export class AppComponent { }
|
|
210
231
|
```
|
|
211
232
|
|
|
233
|
+
That's it! With just 3 lines of code, you have a fully functional video conferencing application with:
|
|
234
|
+
|
|
235
|
+
- π₯ **Video & Audio Streaming** - High-quality real-time communication
|
|
236
|
+
- π₯οΈ **Screen Sharing** - Share your screen with annotation support
|
|
237
|
+
- π¬ **Interactive Chat** - Direct and group messaging
|
|
238
|
+
- π₯ **Participant Management** - Join/leave controls and permissions
|
|
239
|
+
- π¨ **Customizable UI** - Professional, responsive design out of the box
|
|
240
|
+
- π± **Mobile Responsive** - Works seamlessly on all devices
|
|
241
|
+
- π§ **Zero Configuration** - No complex setup required
|
|
242
|
+
|
|
243
|
+
## Why Choose MediaSFU?
|
|
244
|
+
|
|
245
|
+
### β‘ **Lightning Fast Setup**
|
|
246
|
+
From `npm install` to a working video conference in under 2 minutes. No WebRTC knowledge required.
|
|
247
|
+
|
|
248
|
+
### π― **Multiple Event Types Ready**
|
|
249
|
+
Choose from pre-built, production-ready templates:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import {
|
|
253
|
+
MediasfuGeneric, // π All-purpose meetings
|
|
254
|
+
MediasfuBroadcast, // πΊ Live streaming events
|
|
255
|
+
MediasfuWebinar, // π Educational sessions
|
|
256
|
+
MediasfuConference, // πΌ Professional meetings
|
|
257
|
+
MediasfuChat // π¬ Interactive chat rooms
|
|
258
|
+
} from 'mediasfu-angular';
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### π οΈ **Infinitely Customizable**
|
|
262
|
+
|
|
263
|
+
**Replace Any Component:** Don't like our video card? Swap it with yours:
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// Your custom video component
|
|
267
|
+
@Component({
|
|
268
|
+
selector: 'my-video-card',
|
|
269
|
+
template: `<div class="my-custom-video">{{ participant.name }}</div>`
|
|
270
|
+
})
|
|
271
|
+
export class MyVideoCard { }
|
|
272
|
+
|
|
273
|
+
// Use it in MediaSFU
|
|
274
|
+
const customVideoCard = this.customComponentService.createComponentWithInjector(
|
|
275
|
+
MyVideoCard, { participant: participantData }
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
// MediaSFU will use your component instead
|
|
279
|
+
this.mediasfuParameters = { customVideoCard };
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Custom Layouts:** Build your own UI while keeping MediaSFU's powerful backend:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// Your WhatsApp-style video call UI
|
|
286
|
+
@Component({
|
|
287
|
+
template: `
|
|
288
|
+
<div class="whatsapp-style-layout">
|
|
289
|
+
<header>My Custom Header</header>
|
|
290
|
+
<main>Your video layout here</main>
|
|
291
|
+
</div>
|
|
292
|
+
`
|
|
293
|
+
})
|
|
294
|
+
export class MyCustomLayout { }
|
|
295
|
+
|
|
296
|
+
// MediaSFU handles all the complex WebRTC, you handle the UI
|
|
297
|
+
this.mediasfuParameters = {
|
|
298
|
+
customMainComponent: MyCustomLayout,
|
|
299
|
+
returnUI: false // Disable default MediaSFU UI
|
|
300
|
+
};
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### π **Production-Ready Features**
|
|
304
|
+
|
|
305
|
+
- **Cloud Recording** with custom watermarks and layouts
|
|
306
|
+
- **Breakout Rooms** for team collaboration
|
|
307
|
+
- **Polls & Surveys** for audience engagement
|
|
308
|
+
- **Waiting Rooms** with host controls
|
|
309
|
+
- **Advanced Permissions** and moderation tools
|
|
310
|
+
- **Real-time Analytics** and monitoring
|
|
311
|
+
- **Enterprise Security** with end-to-end encryption
|
|
312
|
+
|
|
313
|
+
### π **Flexible Deployment Options**
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// Option 1: MediaSFU Cloud (Fastest setup)
|
|
317
|
+
const credentials = { apiUserName: 'your-key', apiKey: 'your-secret' };
|
|
318
|
+
|
|
319
|
+
// Option 2: Self-hosted Community Edition (Free)
|
|
320
|
+
const localLink = 'http://your-server.com';
|
|
321
|
+
|
|
322
|
+
// Option 3: Hybrid (Best of both worlds)
|
|
323
|
+
const config = {
|
|
324
|
+
localLink: 'http://your-server.com',
|
|
325
|
+
connectMediaSFU: true, // Use cloud for advanced features
|
|
326
|
+
credentials: credentials
|
|
327
|
+
};
|
|
328
|
+
```
|
|
329
|
+
|
|
212
330
|
## Programmatically Fetching Tokens
|
|
213
331
|
|
|
214
332
|
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 inputs.
|
|
@@ -2472,6 +2590,335 @@ Once your custom components are built, modify the imports of `prepopulateUserMed
|
|
|
2472
2590
|
|
|
2473
2591
|
This allows for full flexibility in how media is displayed in both the main and mini grids, giving you the ability to tailor the user experience to your specific needs.
|
|
2474
2592
|
|
|
2593
|
+
## Custom Component Injection Service
|
|
2594
|
+
|
|
2595
|
+
MediaSFU provides a powerful `CustomComponentInjectionService` that enables advanced custom component integration across all MediaSFU components. This service offers a comprehensive set of utilities for managing custom component rendering, validation, and lifecycle management.
|
|
2596
|
+
|
|
2597
|
+
### Features
|
|
2598
|
+
|
|
2599
|
+
- **Type-safe component validation**: Check if components are Angular components, HTML elements, or function components
|
|
2600
|
+
- **Dynamic component injection**: Create components with custom parameters and injectors
|
|
2601
|
+
- **Safe rendering utilities**: Handle different component types with proper error handling and fallbacks
|
|
2602
|
+
- **Component lifecycle management**: Proper cleanup and destruction of custom components
|
|
2603
|
+
- **Template integration helpers**: Utilities for the custom component pattern used throughout MediaSFU
|
|
2604
|
+
|
|
2605
|
+
### Basic Usage
|
|
2606
|
+
|
|
2607
|
+
First, import the service and types:
|
|
2608
|
+
|
|
2609
|
+
```typescript
|
|
2610
|
+
import {
|
|
2611
|
+
CustomComponentInjectionService,
|
|
2612
|
+
CustomComponent,
|
|
2613
|
+
CustomComponentType,
|
|
2614
|
+
CustomComponentParameters,
|
|
2615
|
+
CustomComponentContext
|
|
2616
|
+
} from 'mediasfu-angular';
|
|
2617
|
+
```
|
|
2618
|
+
|
|
2619
|
+
#### Injecting the Service
|
|
2620
|
+
|
|
2621
|
+
```typescript
|
|
2622
|
+
import { Component, inject } from '@angular/core';
|
|
2623
|
+
|
|
2624
|
+
@Component({
|
|
2625
|
+
selector: 'app-my-component',
|
|
2626
|
+
template: `...`
|
|
2627
|
+
})
|
|
2628
|
+
export class MyComponent {
|
|
2629
|
+
private customComponentService = inject(CustomComponentInjectionService);
|
|
2630
|
+
}
|
|
2631
|
+
```
|
|
2632
|
+
|
|
2633
|
+
#### Creating Custom Components with Parameters
|
|
2634
|
+
|
|
2635
|
+
```typescript
|
|
2636
|
+
// Create a custom component with injected parameters
|
|
2637
|
+
const customVideoCard = this.customComponentService.createComponentWithInjector(
|
|
2638
|
+
MyCustomVideoCard,
|
|
2639
|
+
{
|
|
2640
|
+
participant: participantData,
|
|
2641
|
+
options: videoOptions,
|
|
2642
|
+
callbacks: eventHandlers
|
|
2643
|
+
}
|
|
2644
|
+
);
|
|
2645
|
+
|
|
2646
|
+
// Use in MediaSFU component
|
|
2647
|
+
const params = {
|
|
2648
|
+
customVideoCard: customVideoCard,
|
|
2649
|
+
// ... other parameters
|
|
2650
|
+
};
|
|
2651
|
+
```
|
|
2652
|
+
|
|
2653
|
+
#### Component Type Validation
|
|
2654
|
+
|
|
2655
|
+
```typescript
|
|
2656
|
+
// Check component types
|
|
2657
|
+
if (this.customComponentService.isCustomComponent(component)) {
|
|
2658
|
+
// Handle Angular component with injector
|
|
2659
|
+
console.log('Angular component detected');
|
|
2660
|
+
} else if (this.customComponentService.isHTMLElement(component)) {
|
|
2661
|
+
// Handle HTML element
|
|
2662
|
+
console.log('HTML element detected');
|
|
2663
|
+
} else if (this.customComponentService.isFunctionComponent(component)) {
|
|
2664
|
+
// Handle function component
|
|
2665
|
+
console.log('Function component detected');
|
|
2666
|
+
}
|
|
2667
|
+
```
|
|
2668
|
+
|
|
2669
|
+
#### Safe HTML Element Access
|
|
2670
|
+
|
|
2671
|
+
```typescript
|
|
2672
|
+
// Safely get outerHTML from components
|
|
2673
|
+
const htmlContent = this.customComponentService.getHtmlElementOuterHTML(component);
|
|
2674
|
+
if (htmlContent) {
|
|
2675
|
+
// Use the HTML content
|
|
2676
|
+
element.innerHTML = htmlContent;
|
|
2677
|
+
}
|
|
2678
|
+
```
|
|
2679
|
+
|
|
2680
|
+
#### Component Resolution Pattern
|
|
2681
|
+
|
|
2682
|
+
```typescript
|
|
2683
|
+
// Resolve between custom and default components
|
|
2684
|
+
const resolvedComponent = this.customComponentService.resolveComponent(
|
|
2685
|
+
customComponent, // May be undefined
|
|
2686
|
+
defaultComponent // Fallback component
|
|
2687
|
+
);
|
|
2688
|
+
|
|
2689
|
+
// Check if custom main component should be used
|
|
2690
|
+
const useCustomLayout = this.customComponentService.shouldUseCustomMainComponent(
|
|
2691
|
+
customMainComponent
|
|
2692
|
+
);
|
|
2693
|
+
```
|
|
2694
|
+
|
|
2695
|
+
### Advanced Usage Examples
|
|
2696
|
+
|
|
2697
|
+
#### 1. Dynamic Component Rendering
|
|
2698
|
+
|
|
2699
|
+
```typescript
|
|
2700
|
+
@Component({
|
|
2701
|
+
selector: 'app-dynamic-renderer',
|
|
2702
|
+
template: `
|
|
2703
|
+
<ng-container #dynamicContainer></ng-container>
|
|
2704
|
+
`
|
|
2705
|
+
})
|
|
2706
|
+
export class DynamicRenderer {
|
|
2707
|
+
@ViewChild('dynamicContainer', { read: ViewContainerRef })
|
|
2708
|
+
container!: ViewContainerRef;
|
|
2709
|
+
|
|
2710
|
+
private customComponentService = inject(CustomComponentInjectionService);
|
|
2711
|
+
|
|
2712
|
+
renderCustomComponent(customComponent: CustomComponentType<any>) {
|
|
2713
|
+
const context: CustomComponentContext = {
|
|
2714
|
+
parameters: {
|
|
2715
|
+
data: this.componentData,
|
|
2716
|
+
events: this.eventHandlers
|
|
2717
|
+
},
|
|
2718
|
+
injector: this.injector,
|
|
2719
|
+
config: {
|
|
2720
|
+
enabled: true,
|
|
2721
|
+
fallbackToDefault: true
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
|
|
2725
|
+
const componentRef = this.customComponentService.renderCustomComponent(
|
|
2726
|
+
customComponent,
|
|
2727
|
+
this.container,
|
|
2728
|
+
context
|
|
2729
|
+
);
|
|
2730
|
+
|
|
2731
|
+
// Store reference for cleanup
|
|
2732
|
+
this.activeComponents.push(componentRef);
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
ngOnDestroy() {
|
|
2736
|
+
// Clean up all custom components
|
|
2737
|
+
this.activeComponents.forEach(component => {
|
|
2738
|
+
this.customComponentService.destroyCustomComponent(component);
|
|
2739
|
+
});
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
```
|
|
2743
|
+
|
|
2744
|
+
#### 2. Custom Video Card Implementation
|
|
2745
|
+
|
|
2746
|
+
```typescript
|
|
2747
|
+
// Define your custom video card component
|
|
2748
|
+
@Component({
|
|
2749
|
+
selector: 'app-custom-video-card',
|
|
2750
|
+
template: `
|
|
2751
|
+
<div class="custom-video-wrapper">
|
|
2752
|
+
<video [srcObject]="videoStream" autoplay playsinline></video>
|
|
2753
|
+
<div class="custom-controls">
|
|
2754
|
+
<button (click)="toggleAudio()">π€</button>
|
|
2755
|
+
<button (click)="toggleVideo()">πΉ</button>
|
|
2756
|
+
</div>
|
|
2757
|
+
<div class="custom-info">{{ participantName }}</div>
|
|
2758
|
+
</div>
|
|
2759
|
+
`,
|
|
2760
|
+
imports: [CommonModule]
|
|
2761
|
+
})
|
|
2762
|
+
export class CustomVideoCard {
|
|
2763
|
+
@Input() participant!: Participant;
|
|
2764
|
+
@Input() videoStream!: MediaStream;
|
|
2765
|
+
@Input() options!: any;
|
|
2766
|
+
|
|
2767
|
+
get participantName() {
|
|
2768
|
+
return this.participant?.name || 'Unknown';
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
toggleAudio() {
|
|
2772
|
+
// Custom audio toggle logic
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
toggleVideo() {
|
|
2776
|
+
// Custom video toggle logic
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// In your main component
|
|
2781
|
+
export class MyMediaComponent {
|
|
2782
|
+
private customComponentService = inject(CustomComponentInjectionService);
|
|
2783
|
+
|
|
2784
|
+
ngOnInit() {
|
|
2785
|
+
// Create custom video card with parameters
|
|
2786
|
+
const customVideoCard = this.customComponentService.createComponentWithInjector(
|
|
2787
|
+
CustomVideoCard,
|
|
2788
|
+
{
|
|
2789
|
+
participant: this.currentParticipant,
|
|
2790
|
+
options: this.videoOptions
|
|
2791
|
+
}
|
|
2792
|
+
);
|
|
2793
|
+
|
|
2794
|
+
// Use in MediaSFU parameters
|
|
2795
|
+
this.mediasfuParameters = {
|
|
2796
|
+
customVideoCard: customVideoCard,
|
|
2797
|
+
// ... other parameters
|
|
2798
|
+
};
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
```
|
|
2802
|
+
|
|
2803
|
+
#### 3. Custom Main Component with Template Restructuring
|
|
2804
|
+
|
|
2805
|
+
```typescript
|
|
2806
|
+
@Component({
|
|
2807
|
+
selector: 'app-custom-main-layout',
|
|
2808
|
+
template: `
|
|
2809
|
+
<div class="custom-main-layout">
|
|
2810
|
+
<header class="custom-header">
|
|
2811
|
+
<h1>My Custom Stream</h1>
|
|
2812
|
+
<div class="custom-controls">
|
|
2813
|
+
<!-- Custom control buttons -->
|
|
2814
|
+
</div>
|
|
2815
|
+
</header>
|
|
2816
|
+
|
|
2817
|
+
<main class="custom-content">
|
|
2818
|
+
<div class="video-area">
|
|
2819
|
+
<!-- Your custom video layout -->
|
|
2820
|
+
</div>
|
|
2821
|
+
<div class="participant-list">
|
|
2822
|
+
<!-- Custom participant list -->
|
|
2823
|
+
</div>
|
|
2824
|
+
</main>
|
|
2825
|
+
|
|
2826
|
+
<footer class="custom-footer">
|
|
2827
|
+
<!-- Custom footer content -->
|
|
2828
|
+
</footer>
|
|
2829
|
+
</div>
|
|
2830
|
+
`,
|
|
2831
|
+
imports: [CommonModule]
|
|
2832
|
+
})
|
|
2833
|
+
export class CustomMainLayout {
|
|
2834
|
+
@Input() parameters!: any;
|
|
2835
|
+
@Input() credentials!: any;
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
// Usage
|
|
2839
|
+
const customMainComponent = this.customComponentService.createComponentWithInjector(
|
|
2840
|
+
CustomMainLayout,
|
|
2841
|
+
{
|
|
2842
|
+
theme: 'dark',
|
|
2843
|
+
layout: 'grid'
|
|
2844
|
+
}
|
|
2845
|
+
);
|
|
2846
|
+
|
|
2847
|
+
// MediaSFU will use this instead of default layout
|
|
2848
|
+
this.mediasfuParameters = {
|
|
2849
|
+
customMainComponent: customMainComponent,
|
|
2850
|
+
// ... other parameters
|
|
2851
|
+
};
|
|
2852
|
+
```
|
|
2853
|
+
|
|
2854
|
+
### Component Validation and Error Handling
|
|
2855
|
+
|
|
2856
|
+
```typescript
|
|
2857
|
+
// Validate before using
|
|
2858
|
+
if (this.customComponentService.validateCustomComponent(customComponent)) {
|
|
2859
|
+
// Component is valid, proceed with rendering
|
|
2860
|
+
this.renderComponent(customComponent);
|
|
2861
|
+
} else {
|
|
2862
|
+
// Handle invalid component, use fallback
|
|
2863
|
+
console.warn('Invalid custom component, using default');
|
|
2864
|
+
this.renderComponent(this.defaultComponent);
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
// Merge options safely
|
|
2868
|
+
const mergedOptions = this.customComponentService.mergeComponentOptions(
|
|
2869
|
+
customOptions,
|
|
2870
|
+
defaultOptions
|
|
2871
|
+
);
|
|
2872
|
+
```
|
|
2873
|
+
|
|
2874
|
+
### TypeScript Types
|
|
2875
|
+
|
|
2876
|
+
The service works with these main types:
|
|
2877
|
+
|
|
2878
|
+
```typescript
|
|
2879
|
+
// Union type for all supported component types
|
|
2880
|
+
type CustomComponentType<T = any> = CustomComponent<T> | HTMLElement | CustomComponentFunction;
|
|
2881
|
+
|
|
2882
|
+
// Angular component with injector
|
|
2883
|
+
interface CustomComponent<T = any> {
|
|
2884
|
+
component: Type<T>;
|
|
2885
|
+
injector?: Injector;
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
// Function that returns HTMLElement
|
|
2889
|
+
type CustomComponentFunction = () => HTMLElement;
|
|
2890
|
+
|
|
2891
|
+
// Parameters for component injection
|
|
2892
|
+
interface CustomComponentParameters {
|
|
2893
|
+
[key: string]: any;
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
// Context for component rendering
|
|
2897
|
+
interface CustomComponentContext {
|
|
2898
|
+
parameters: CustomComponentParameters;
|
|
2899
|
+
injector?: Injector;
|
|
2900
|
+
config?: ComponentInjectionConfig;
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
// Configuration options
|
|
2904
|
+
interface ComponentInjectionConfig {
|
|
2905
|
+
enabled: boolean;
|
|
2906
|
+
overrideDefaults: boolean;
|
|
2907
|
+
fallbackToDefault: boolean;
|
|
2908
|
+
}
|
|
2909
|
+
```
|
|
2910
|
+
|
|
2911
|
+
### Best Practices
|
|
2912
|
+
|
|
2913
|
+
1. **Always validate components** before rendering
|
|
2914
|
+
2. **Use proper cleanup** to prevent memory leaks
|
|
2915
|
+
3. **Leverage type guards** for safe component handling
|
|
2916
|
+
4. **Provide fallbacks** for failed component rendering
|
|
2917
|
+
5. **Use meaningful parameter names** when creating injectors
|
|
2918
|
+
6. **Test custom components** in isolation before integration
|
|
2919
|
+
|
|
2920
|
+
The `CustomComponentInjectionService` provides a robust foundation for building highly customizable MediaSFU applications while maintaining type safety and proper Angular practices.
|
|
2921
|
+
|
|
2475
2922
|
|
|
2476
2923
|
# API Reference <a name="api-reference"></a>
|
|
2477
2924
|
|