Skip to content

Plugin: Cast Sender

CastSenderPlugin (id 'cast-sender') is a thin, two-method specialization of the kit’s CastSenderPlugin, which owns everything medium-agnostic: SDK probing, session lifecycle, RemotePlayer event mirroring, resume-on-disconnect. This subclass only supplies the two things that differ between video and music: the default MIME type, and how a VideoPlaylistItem becomes Cast metadata.

Options

Same CastSenderOptions the kit plugin defines, chromecastAppId, enableAirPlay, customReceiverNamespace, resumeLocalOnDisconnect, defaultContentType, live, see Plugin: Cast Sender (core) for the full table. defaultContentType defaults to 'video/mp4' here ('audio/mpeg' on the music player’s own subclass) unless you override it explicitly.

Events

Same CastSenderEvents as the base: cast:connected, cast:disconnected, cast:error, cast:remote-state, cast:media-changed, unsupported.

What the video subclass builds

buildMetadata(item, ctors) reads only fields already on the canonical VideoPlaylistItem:

Item has…Metadata built
item.show set (non-empty string)TvShowMediaMetadata (falls back to GenericMediaMetadata if the SDK build lacks the TV-show constructor), seriesTitle from show, season / episode set when present.
item.show unset or emptyPlain GenericMediaMetadata, title only, subtitle is not set on this path.
item.posterResolved through resolveUrl(item.poster, 'poster') (auth-aware, respects baseImageUrl) and set as the metadata’s images.

Rules & restrictions

  • All the base plugin’s restrictions apply unchanged: Chrome/Chromium Web Sender SDK only, requires cast.framework / chrome.cast.media already loaded on the page, volume converted from the player’s 0-100 scale to the SDK’s native 0-1 volumeLevel float (divided by 100 at the boundary, clamped to spec range).
  • Consumers carrying application-specific fields beyond the canonical VideoPlaylistItem (a server-specific name, for instance) should subclass this plugin and override buildMetadata() themselves rather than expecting it to read fields it was never typed against.
  • transferTo('cast') and this plugin are separate, unlinked mechanisms. transferTo('cast') is the kit’s own coarse handoff, it drives the Cast SDK directly and knows nothing about CastSenderPlugin. Adding this plugin does not wire it into transferTo(), and calling transferTo('cast') does not go through this plugin’s connect() / metadata pipeline. Pick one Cast strategy per app.

How to extend it

TypeScript
import nmplayer from '@nomercy-entertainment/nomercy-video-player';
import { CastSenderPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins/cast-sender';

const player = nmplayer('player');

class MyCastSenderPlugin extends CastSenderPlugin {
protected override async buildMetadata(item, ctors) {
const meta = await super.buildMetadata(item, ctors);
// add app-specific fields on top of the canonical set super() already built
return meta;
}
}

player.addPlugin(MyCastSenderPlugin, { chromecastAppId: 'ABCD1234' });
await player.ready();
await player.getPlugin(MyCastSenderPlugin)?.connect();

Next steps

  • Plugin: Media Session: the OS lock-screen equivalent, built on the same title/show/season metadata fields.