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.
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
| Option | Type | Default | Description |
|---|---|---|---|
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. |
bindings | Record<string, (player) => void> | undefined | Extra 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. |
extend | boolean | true | When false, all default bindings are cleared before bindings is applied. Use this to build a fully custom binding set from scratch. |
when | (e: KeyboardEvent) => boolean | undefined | Gate predicate. Return false to suppress all key handling for that event, useful during modals or chat overlays. |
cooldownMs | number | 300 | Minimum milliseconds between consecutive fires of the same key. Prevents rapid-fire seeks from a held key. Set to 0 to disable throttling. |
disableMediaControls | boolean | false | When true, all eight W3C hardware media keys (MediaPlay, MediaPause, MediaPlayPause, MediaStop, MediaRewind, MediaFastForward, MediaTrackNext, MediaTrackPrevious) are silently ignored. |
Key bindings
Core defaults (inherited)
| Key | KeyboardEvent.key | Action |
|---|---|---|
| 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)
| Key | KeyboardEvent.key | Action |
|---|---|---|
| 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.
| Method | Signature | Description |
|---|---|---|
bind | (combo: string, fn: (player) => void) => void | Register or replace a handler for a combo string. Registering the same combo again replaces the previous handler. |
unbind | (combo: string) => void | Remove the handler for a combo. No-ops when the combo is not registered. |
replace | (combo: string, fn: (player) => void) => void | Semantic 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 | () => EventTarget | Returns 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
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:
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:
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
- Player Core, KeyHandlerPlugin, base binding interface,
bind(), full combo format - MusicUiPlugin, visual transport controls