Skip to content

TV Key Handler

TvKeyHandlerPlugin gives you the remote-control binding layer for TV environments. Use it alongside (or instead of) DesktopUiPlugin on Android TV, smart TV, or any deployment where an IR remote or D-pad is the primary input. It subclasses KeyHandlerPlugin to inherit the full default video keyboard binding set, then overrides only the groups that work differently on a TV and adds two TV-only keys.

Plugin id

'tv-key-handler'

Import

TypeScript
import { TvKeyHandlerPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins';
import type { TvKeyHandlerOptions } from '@nomercy-entertainment/nomercy-video-player/plugins';

What it does

TvKeyHandlerPlugin extends KeyHandlerPlugin and changes these bindings:

Binding groupTV-specific behaviour
Arrow keysSeek directly. On a TV the host page removes focus from interactive elements before mounting the player, so arrows are free to drive playback.
Volume arrowsEnabled. The base plugin disables them on TV; this plugin re-enables them so a web TV shell can forward volume events correctly.
Aspect ratioa and BrowserFavorites cycle aspect ratio and show an OSD message confirming the change, since there is no visible control bar.
Info keyShows an OSD with title, chapter, current time, and time remaining. Also emits 'plugin:tv-key-handler:info' for an external TV shell overlay.
MediaRecordEmits 'plugin:tv-key-handler:bookmark' with the current time. The player does not store bookmarks itself.
Help key (?)Emits 'plugin:tv-key-handler:shortcuts-toggle' instead of 'plugin:desktop-ui:shortcuts-toggle' so a TV shortcuts overlay can be wired independently.

All Color-button (F0 through F3), BrowserFavorites, universal media key, modifier-seek, chapter, speed, frame-advance, subtitle-size, and stop bindings are inherited from KeyHandlerPlugin unchanged.

Options

OptionTypeDefaultDescription
arrowSeekSecondsnumber5Seconds to seek when ArrowLeft or ArrowRight is pressed. Color-button seeks are fixed at 30/60/90/120 s and are not affected by this option.
infoDisplayMsnumber5000Milliseconds the Info OSD stays visible before it auto-dismisses.

Events

EventPayloadDescription
'plugin:tv-key-handler:info'{ title: string, currentTime: number, duration: number, remaining: number, chapterLabel: string }Info key pressed. Fired before the built-in OSD message so a TV shell can render its own overlay.
'plugin:tv-key-handler:bookmark'{ time: number }MediaRecord key pressed. Consumer should persist the bookmark; the player does not.
'plugin:tv-key-handler:shortcuts-toggle'voidHelp key pressed. For a TV shortcuts overlay registered independently from the desktop-ui overlay.

Methods

TvKeyHandlerPlugin exposes no additional public methods beyond those inherited from KeyHandlerPlugin.

Registration

TypeScript
import nmplayer from '@nomercy-entertainment/nomercy-video-player';
import { TvKeyHandlerPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins';
import type { TvKeyHandlerOptions } from '@nomercy-entertainment/nomercy-video-player/plugins';

const player = nmplayer('player')
.addPlugin(TvKeyHandlerPlugin, {
arrowSeekSeconds: 5,
infoDisplayMs: 4000,
} as TvKeyHandlerOptions)
.setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Films',
playlist: [
{
id: 1,
title: 'Tears of Steel',
url: '/Tears.of.Steel.(2012)/Tears.of.Steel.(2012).NoMercy.m3u8',
chapters: [{ index: 0, title: 'Opening', start: 0, end: 120 }],
},
],
});

player.on('plugin:tv-key-handler:bookmark', ({ time }) => {
saveBookmark(time);
});

Info OSD content

When the Info key is pressed the OSD message is built from three parts. First, the item title from player.item()?.title. Second, the chapter label: chapter number plus title from the active chapter at the current time, or chapter number alone if the chapter has no title. Third, currentTime / -remaining formatted as M:SS or H:MM:SS (minutes are not zero-padded; 65 seconds renders as 1:05). The parts are joined with a · separator and sent as a single OSD message. The full payload is also emitted as 'plugin:tv-key-handler:info' so an external shell can render its own overlay.

When a MessagePlugin is mounted the OSD routes through it; the plugin also emits display-message for consumers that prefer the event surface.

NoMercy Connect routing

All bindings call local player methods directly. A consumer-side NoMercy Connect plugin can call keyHandler.replace(combo, fn) to route specific commands through a sync socket instead.

See also