Angular Implementation - Storm JavaScript Player
Below you'll find a short tutorial on how to implement Storm Player using your own custom component in Angular.
Requirements
- Node: 16.14+
- Angular: 16.0.0+
- @stormstreaming/player-ui: 1.x
Installation
npm install @stormstreaming/player-ui
yarn add @stormstreaming/player-ui
Sample Code
import {
StormPlayerUI as StormPlayerUIClass,
StormPlayerUIConfig,
StormStreamConfig,
StormPlayerUIEvent
} from "@stormstreaming/player-ui";
import {
Component,
Input,
OnDestroy,
OnInit
} from '@angular/core';
@Component({
selector: 'app-storm-player',
template: `<div id="{{containerID}}"></div>`
})
export class StormPlayerUI implements OnInit, OnDestroy {
@Input({ required: true }) streamData!: {
serverURL: string;
applicationName: string;
streamKey: string;
};
@Input({ required: true }) playerSettings!: {
width: number;
height: number;
title: string;
subtitle: string;
};
/**
* Player ID
*/
containerID: string = "stormContainer_" + crypto.randomUUID();
/**
* Storm Player Configuration Object
*/
playerConfig?: StormPlayerUIConfig;
/**
* Storm Player Core Configuration Object
*/
streamConfig?: StormStreamConfig;
/**
* Player itself
*/
player?: StormPlayerUIClass;
ngOnInit() {
this.streamConfig = {
stream: {
serverList: [{
host: this.streamData.serverURL,
application: this.streamData.applicationName,
port: 443,
ssl: true
}],
streamKey: this.streamData.streamKey,
},
settings: {
autoStart: true,
debug: {
console: {
enabled: true,
logTypes: ["INFO", "ERROR", "TRACE", "WARNING", "SUCCESS"],
monoColor: false,
},
},
},
};
this.playerConfig = {
containerID: this.containerID,
width: this.playerSettings.width,
height: this.playerSettings.height,
title: this.playerSettings.title,
subtitle: this.playerSettings.subtitle,
}
// start Storm Player
this.player = new StormPlayerUIClass(this.playerConfig, this.streamConfig, true);
this.player.addEventListener("playbackProgress", this.onPlaybackProgress);
this.player.initialize();
}
onPlaybackProgress = (event: StormPlayerUIEvent["playbackProgress"]) => {
console.log(`Player ID: ${event.ref.getInstanceID()} - Playback Progress Update`);
console.log(`-- >: streamStartTime (source): ${event.streamStartTime}`);
console.log(`-- >: streamDuration (source): ${event.streamDuration}`);
console.log(`-- >: playbackStartTime (this stream): ${event.playbackStartTime}`);
console.log(`-- >: playbackDuration (this stream): ${event.playbackDuration}`);
};
ngOnDestroy() {
// destroy Storm Player
if (this.player) {
this.player.removeEventListener("playbackProgress", this.onPlaybackProgress);
this.player.destroy();
}
}
}
Code Explanation
Imports:
Importstypescript
import { StormPlayerUI as StormPlayerUIClass, StormPlayerUIConfig, StormStreamConfig, StormPlayerUIEvent } from "@stormstreaming/player-ui"; import { Component, Input, OnDestroy, OnInit } from '@angular/core';These are the required imports that include Storm Player into your class, along with the required Angular classes.
Player & Stream Input Objects:
Input objectstypescript
@Input({ required: true }) streamData!: { serverURL: string; applicationName: string; streamKey: string; }; @Input({ required: true }) playerSettings!: { width: number; height: number; title: string; subtitle: string; };These simplified parameters will be used to provide all required data to the player. The
required: trueoption ensures that Angular will throw an error if the component is used without providing these inputs. Most settings will remain in this class however.Component template with container:
Component templatetypescript
@Component({ selector: 'app-storm-player', template: `<div id="{{containerID}}"></div>` })The component template contains a
divelement with a dynamically assigned ID. Storm Player uses this container to render the player UI inside it.Player & Stream Config Objects:
Configuration objectstypescript
this.streamConfig = { stream: { serverList: [{ host: this.streamData.serverURL, application: this.streamData.applicationName, port: 443, ssl: true }], streamKey: this.streamData.streamKey, }, settings: { autoStart: true, debug: { console: { enabled: true, logTypes: ["INFO", "ERROR", "TRACE", "WARNING", "SUCCESS"], monoColor: false, }, }, }, }; this.playerConfig = { containerID: this.containerID, width: this.playerSettings.width, height: this.playerSettings.height, title: this.playerSettings.title, subtitle: this.playerSettings.subtitle, };These are core Storm Player & Storm Stream configuration objects. You can learn more about configuring this section from the Storm JS Player Core - Stream & Server Configuration guide.
Player object creation, event registration & initialization:
Player initializationtypescript
// start Storm Player this.player = new StormPlayerUIClass(this.playerConfig, this.streamConfig, true); this.player.addEventListener("playbackProgress", this.onPlaybackProgress); this.player.initialize();In the first line we create new player instance. The last parameter forces the player to wait for
initialize()method before starting its code. Between those two methods we can register events to interact with the player. The lists of supported events can be found in the Storm JS Player Core - Stream & Server Configuration section. For a comprehensive description of the API, please refer to the API Methods section.Sample event-listener callback method:
Event callbacktypescript
onPlaybackProgress = (event: StormPlayerUIEvent["playbackProgress"]) => { console.log(`Player ID: ${event.ref.getInstanceID()} - Playback Progress Update`); console.log(`-- >: streamStartTime (source): ${event.streamStartTime}`); console.log(`-- >: streamDuration (source): ${event.streamDuration}`); console.log(`-- >: playbackStartTime (this stream): ${event.playbackStartTime}`); console.log(`-- >: playbackDuration (this stream): ${event.playbackDuration}`); };A sample callback method for
playbackProgressevent. Note the arrow function syntax which preserves the correctthiscontext when the callback is invoked by the player.
Embedding the Player
Module-based approach (NgModule)
In order to embed our component in Angular using the traditional module-based approach, we need to register our component within the module declarations section.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { StormPlayerUI } from "./StormPlayerUI";
@NgModule({
...
declarations: [
...
StormPlayerUI
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
Standalone approach (Angular 16+)
If your project uses standalone components (default for new Angular 16+ projects), simply add the standalone: true flag to the component decorator:
@Component({
selector: 'app-storm-player',
standalone: true,
template: `<div id="{{containerID}}"></div>`
})
export class StormPlayerUI implements OnInit, OnDestroy {
// ... rest of the component code remains the same
}
Then import it directly in the parent component:
import { StormPlayerUI } from "./StormPlayerUI";
@Component({
selector: 'app-root',
standalone: true,
imports: [StormPlayerUI],
template: `
<app-storm-player
[streamData]="{serverURL: 'sub1.example.com', applicationName: 'live', streamKey:'test'}"
[playerSettings]="{ title:'Title goes here', subtitle:'Subtitle', width:640, height:320}"
></app-storm-player>
`
})
export class AppComponent { }
Component usage
Once registered, you can use the following code to embed the player into a page:
<!-- Replace serverURL with your Storm Streaming Server or Cloud host address -->
<app-storm-player
[streamData]="{serverURL: 'sub1.example.com', applicationName: 'live', streamKey:'test'}"
[playerSettings]="{ title:'Title goes here', subtitle:'Subtitle', width:640, height:320}"
>
</app-storm-player>
For the next step please check our Storm JS Player UI - Stream & Server guide where you'll learn how to connect the player with Storm Streaming Cloud or Server instance.