Skip to main content

Angular Remote Podcast Tutorial

Build a local remote-podcast room with mediasfu-angular@2.3.1: host and guest media, participant controls, screen sharing, recording controls when enabled, and individual leave. It runs on a local MediaSFU Community Edition server.

Prerequisites

  • Node.js 18 to 20, a local MediaSFU Community Edition server, and two profiles.
  • HTTPS or localhost; set the server origin in the component.

Project files

package.json
{"private":true,"scripts":{"start":"ng serve"},"dependencies":{"@angular/animations":"19.2.20","@angular/cdk":"19.2.19","@angular/common":"19.2.20","@angular/compiler":"19.2.20","@angular/core":"19.2.20","@angular/forms":"19.2.20","@angular/platform-browser":"19.2.20","@angular/router":"19.2.20","@fortawesome/angular-fontawesome":"1.0.0","@fortawesome/fontawesome-svg-core":"6.7.2","@fortawesome/free-brands-svg-icons":"6.7.2","@fortawesome/free-solid-svg-icons":"6.7.2","@mediapipe/selfie_segmentation":"0.1.1675465747","@zxing/ngx-scanner":"19.0.0","bootstrap":"5.3.8","mediasoup-client":"3.20.0","mediasfu-angular":"2.3.1","ngx-cookie-service":"19.1.2","rxjs":"7.8.0","socket.io-client":"4.8.3","tslib":"2.8.1","zone.js":"0.15.1"},"devDependencies":{"@angular-devkit/build-angular":"19.2.14","@angular/cli":"19.2.14","typescript":"5.5.4"}}
angular.json
{"version":1,"projects":{"podcast":{"projectType":"application","root":"","sourceRoot":"src","architect":{"build":{"builder":"@angular-devkit/build-angular:application","options":{"browser":"src/main.ts","polyfills":["zone.js"],"tsConfig":"tsconfig.app.json","index":"src/index.html","assets":[],"styles":[]}},"serve":{"builder":"@angular-devkit/build-angular:dev-server","configurations":{"development":{"buildTarget":"podcast:build"}},"defaultConfiguration":"development"}}}}}
tsconfig.app.json
{"compilerOptions":{"strict":true,"target":"ES2022","module":"ES2022","moduleResolution":"bundler","lib":["DOM","ES2022"],"skipLibCheck":true},"include":["src/**/*.ts"]}
src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { RemotePodcastComponent } from './remote-podcast.component';
bootstrapApplication(RemotePodcastComponent).catch((error: unknown) => console.error(error));
src/remote-podcast.component.ts
import { Component } from '@angular/core';
import { MediasfuGeneric } from 'mediasfu-angular';
@Component({selector:'app-root',standalone:true,imports:[MediasfuGeneric],template:`
<main><h1>Remote podcast</h1><p>Create a conference, invite a guest, and use supplied media and recording controls.</p>
<app-mediasfu-generic [localLink]="communityServerUrl" [connectMediaSFU]="true" [returnUI]="true" /></main>`})
export class RemotePodcastComponent { readonly communityServerUrl = 'http://localhost:3000'; }
src/index.html
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Remote podcast</title></head><body><app-root></app-root></body></html>

Run

npm install
npm start

Expected result

Create a conference, join from a second profile, and verify two-way microphone, camera, and remote playback. Use recording controls only if the local room enables them and make the recording notice visible to participants.

Recovery

Treat microphone denial, a missing camera, a failed recording start, and a network reconnect as separate states. Do not report a recording as available until your own storage and retrieval workflow confirms it.

Cleanup

Stop an active recording, confirm the result according to your retention policy, then use Leave in each browser. Leaving is not a role-aware host-wide end.

Release boundary

This is the supported local-server route. For a hosted product, put room authority, recording policy, and user authorization behind the authenticated backend. Do not put a Cloud API key in Angular: the supplied Cloud pre-join screen checks browser credentials before callbacks. Use an approved backend room destination or server-issued handoff rather than bypassing that check.