Skip to content

KeyHandlerPlugin

Every music player benefits from keyboard shortcuts, and most of the plumbing already lives in the player core. This music-specific subclass extends those defaults with four bindings that only make sense for a track-list player: next, previous, repeat cycle, and shuffle toggle. Register it whenever you want keyboard control without wiring each key yourself.

TypeScript
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';
import { KeyHandlerPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

Plugin id: 'key-handler'

What it does

The plugin attaches a single keydown listener to the configured scope target and routes events to combo-keyed callbacks. The base class installs six playback and volume shortcuts plus the full set of W3C hardware media keys. This subclass layers on top by calling super.addMediaKeys() first, then binding n, p, r, and s. Keys silently no-op when the event target is an <input>, <textarea>, <select>, or any contenteditable element, and when opts.when returns false.

Options

OptionTypeDefaultDescription
scope'document' | 'container' | HTMLElement'document'Where the keydown listener is attached. 'document' listens globally. 'container' listens only when the player container or a child has focus. Pass an HTMLElement to attach to a custom target.
bindingsRecord<string, (player) => void>undefinedExtra bindings merged on top of the defaults. Key is a combo string such as ' ', 'ctrl+k', or 'shift+ArrowLeft'. When the same combo appears in defaults and here, this map wins.
extendbooleantrueWhen false, all default bindings are cleared before bindings is applied. Use this to build a fully custom binding set from scratch.
when(e: KeyboardEvent) => booleanundefinedGate predicate. Return false to suppress all key handling for that event, useful during modals or chat overlays.
cooldownMsnumber300Minimum milliseconds between consecutive fires of the same key. Prevents rapid-fire seeks from a held key. Set to 0 to disable throttling.
disableMediaControlsbooleanfalseWhen true, all eight W3C hardware media keys (MediaPlay, MediaPause, MediaPlayPause, MediaStop, MediaRewind, MediaFastForward, MediaTrackNext, MediaTrackPrevious) are silently ignored.

Key bindings

Core defaults (inherited)

KeyKeyboardEvent.keyAction
Space' 'Toggle play/pause
Arrow right'ArrowRight'Forward 5 seconds
Arrow left'ArrowLeft'Rewind 5 seconds
Arrow up'ArrowUp'Volume up
Arrow down'ArrowDown'Volume down
M'm'Toggle mute

Hardware media keys (MediaPlay, MediaPause, MediaPlayPause, MediaStop, MediaRewind, MediaFastForward, MediaTrackNext, MediaTrackPrevious) are also installed by the player core and fire from physical media keys, Bluetooth headphone controls, and most TV remotes. They silently no-op when disableMediaControls is true.

Music-specific bindings (added by this subclass)

KeyKeyboardEvent.keyAction
N'n'Next track
P'p'Previous track
R'r'Cycle repeat (off, all, one, off)
S's'Toggle shuffle on/off

Methods

These methods are available on the plugin instance after registration.

MethodSignatureDescription
bind(combo: string, fn: (player) => void) => voidRegister or replace a handler for a combo string. Registering the same combo again replaces the previous handler.
unbind(combo: string) => voidRemove the handler for a combo. No-ops when the combo is not registered.
replace(combo: string, fn: (player) => void) => voidSemantic alias for bind(), communicates intent to swap rather than add.
bindings() => ReadonlyMap<string, (player) => void>Returns a read-only snapshot of the active binding map.
scope() => EventTargetReturns the EventTarget the keydown listener is attached to.

Combo strings are normalized before storage. 'Shift+arrowleft' and 'shift+ArrowLeft' resolve to the same entry. Single-character key names are lowercased, so 'P' and 'p' are the same binding. The play/pause binding uses the literal space character ' ', not the string 'Space'.

Registration

TypeScript
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';
import { KeyHandlerPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

const player = nmMPlayer('main')
.addPlugin(KeyHandlerPlugin)
.setup({ playlist: myTracks });

With options:

TypeScript
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';
import { KeyHandlerPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

const player = nmMPlayer('main')
.addPlugin(KeyHandlerPlugin, {
scope: 'container',
cooldownMs: 300,
bindings: {
// ' ' is the KeyboardEvent.key value for the spacebar.
// Use the literal space character, not the string 'Space'.
'l': (musicPlayer) => { musicPlayer.forward(30); },
'j': (musicPlayer) => { musicPlayer.rewind(10); },
},
})
.setup({ playlist: myTracks });

Runtime access after setup:

TypeScript
import { KeyHandlerPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

const keyHandler = player.getPlugin(KeyHandlerPlugin)!;

keyHandler.bind('f', (musicPlayer) => {
musicPlayer.forward(30);
});

keyHandler.unbind('r');

See also