Skip to content

Plugin System Overview

The player is split into plugins for everything that most players you find out there just come bundled with, whether you need them or not. The idea is that you can make your player as lean as you want, anywhere from just getting an audio tag to play so you can listen for events and control it, all the way up to the full setup of a streaming platform like NoMercy TV. Splitting it up this way also lets your bundler strip out all the unused code, so you ship the smallest build you can.

It keeps a clean line between the generic stuff and your stuff too. The plugins that ship in the packages know how to do their job and nothing about your app, so they work for anyone. Your own plugins are where the app-specific things live, like your server URLs or auth, and they can reach for whatever they need. Keeping those two apart is most of what keeps things sane as the app grows, and it really comes down to one thing: what a plugin is allowed to import is what decides where it belongs. The Architecture page has the full picture, and Plugins and adapters covers how a plugin differs from an adapter.

What a plugin is

A plugin is a class that extends Plugin<P, O, E>:

  • P: the player type it targets (IPlayer<BaseEventMap> for core-level plugins, NMVideoPlayer or NMMusicPlayer for library-specific plugins)
  • O: the options the plugin accepts
  • E: the typed events the plugin emits

The base class provides managed resources: this.on, this.timeout, this.interval, this.frame, this.mount, this.fetch, this.storage. All of these auto-dispose when the plugin is disposed, so no manual cleanup is needed for resources acquired through these methods.

Layer placement

The five-layer model determines where a plugin belongs:

LayerTypeRule
4Built-in pluginShips in a package. Generic behavior: no server URLs, no app tokens. Works for any consumer.
5Consumer pluginYour app. Can import from anywhere. Contains NoMercy server endpoints, SignalR, auth tokens.

Both layers use the same Plugin<P, O, E> base class. The distinction is purely what they import and what goes in their options.

Plugin scopes

Plugins live at three different scopes:

Core plugins

Shipped inside @nomercy-entertainment/nomercy-player-core. These are generic audio, visualization, DOM, and coordination plugins that work with any player built on the core. Most are in the main barrel export; a few use subpath exports.

See Built-in Core Plugins for the full catalogue.

Library plugins

Shipped inside the video or music player packages. These are domain-specific to their media type, and each library documents its own. See the Video Player and Music Player sections for their plugin pages.

Consumer plugins

Written by you. Named with a vendor prefix ('nomercy:sync', 'myapp:scrobble'). These live in your application codebase at layer 5.

See Plugin Authoring for how to write one.

Registration and lookup

TypeScript
import { EqualizerPlugin } from '@nomercy-entertainment/nomercy-player-core';

// Register:
player.addPlugin(EqualizerPlugin);

// Look up by class (preferred, fully typed):
const eq = player.getPlugin(EqualizerPlugin);
eq?.band(0, 3.0);

// Look up by string id (use when class is not in scope):
const eq = player.getPluginById('equalizer');

For the full registration API see Plugin Registration.

Plugin contract

Every plugin must satisfy the conformance checklist in the Plugin Standard. The standard is enforced by lint rules in the core.

Built-in core plugin catalog

These plugins ship in @nomercy-entertainment/nomercy-player-core. None are registered automatically.

PluginWhat it doesImport
AudioGraphPluginCreates and owns the AudioContext + signal chain. Required by all other audio plugins.@nomercy-entertainment/nomercy-player-core
CanvasPluginMounts a shared <canvas> and runs the RAF render loop. Required by visualization plugins.@nomercy-entertainment/nomercy-player-core
CastSenderPluginChromecast Web Sender SDK bridge. Forwards player state to a Cast receiver and mirrors it back. Base class, consumers import the video or music player’s own subclass.@nomercy-entertainment/nomercy-player-core
EqualizerPlugin10-band parametric EQ with pre-gain, named presets, and persistence. Requires AudioGraphPlugin.@nomercy-entertainment/nomercy-player-core
MixerPluginMaster gain (GainNode) + stereo pan (StereoPannerNode) with persistence. Requires AudioGraphPlugin.@nomercy-entertainment/nomercy-player-core
SpectrumPluginFFT analyser. Emits frame events with frequency, waveform, and band-energy data. Requires AudioGraphPlugin.@nomercy-entertainment/nomercy-player-core
VisualizationPluginAbstract base class for canvas visualizations. Subclass and override render(ctx, frame). Requires CanvasPlugin + SpectrumPlugin.@nomercy-entertainment/nomercy-player-core
EmbedPluginpostMessage bridge between a host page and a player running inside an <iframe>.@nomercy-entertainment/nomercy-player-core
KeyHandlerPluginKeyboard binding router. Default bindings: Space, Arrow keys, m. Configurable scope and cooldown.@nomercy-entertainment/nomercy-player-core/plugins/key-handler
MediaSessionPluginWires navigator.mediaSession for OS lock-screen controls, hardware media keys, and Now Playing artwork.@nomercy-entertainment/nomercy-player-core/plugins/media-session
MessagePluginToast notification overlay with transient, persistent, and queued modes.@nomercy-entertainment/nomercy-player-core/plugins/message
TabLeaderPluginWeb Locks–based cross-tab election so only one tab plays at a time.@nomercy-entertainment/nomercy-player-core/plugins/tab-leader

Plugin or adapter?

Quick rule: adding something new the player does is a plugin; changing how it already does something is an adapter (a port swap). They pair up nicely too, like a plugin that reads from a storage port you swapped. Plugins and adapters walks through the boundary and when to reach for each.

Where to go next

GoalPage
Register, look up, or remove a pluginPlugin Registration
Browse all core-shipped pluginsBuilt-in Core Plugins
Write your own pluginPlugin Authoring
Read the locked conformance standardPlugin Standard
Browse adapter portsAdapter Ports
Browse video-player pluginsVideo Player section
Browse music-player pluginsMusic Player section