Skip to content

Live Transcoding

TypeScript
import { LiveTranscodingPlugin } from '@nomercy-entertainment/nomercy-video-player/plugins';
import type { LiveTranscodingOptions, LiveTranscodingEvents } from '@nomercy-entertainment/nomercy-video-player/plugins';

Plugin id: 'live-transcoding'

LiveTranscodingPlugin is for when your backend encodes video on-demand, segment by segment, and the player needs to know the transcoder’s progress before it seeks or starts loading. It opens a WebSocket to a transcoding control endpoint, and gates beforeLoad and beforeSeek until the server reports that the requested position is already encoded. Without a controlUrl or wsUrl the plugin is entirely inert: no connections are opened and no gates are applied, so it is safe to register in all configurations.

What it does

The plugin connects to your server over WebSocket and listens for job status messages. On beforeLoad it resets progress state and waits for the server to confirm at least position 0 is ready. On beforeSeek it checks whether the seek target is ahead of the transcoder’s write head, and if so it waits up to seekTimeoutMs milliseconds before releasing the player. The current write head position is exposed through the transcodedTo() method, updated live from server progress messages.

Options

OptionTypeDefaultDescription
controlUrlstringnoneWebSocket URL of the transcoding control endpoint.
wsUrlstringnoneAlias for controlUrl. Either one works; wsUrl takes priority.
pollIntervalMsnumbernonePolling fallback interval in milliseconds for environments without WebSocket.
resumeAheadSecondsnumbernoneSeconds of buffer beyond currentTime required before resuming after backpressure.
seekTimeoutMsnumber10000Max milliseconds to wait for the transcoder to reach the seek target before releasing the player.
preferredHeightnumbernonePreferred output height hint sent to the encoder.

Events

EventPayloadDescription
'job:started'{ jobId: string; sourceUrl: string }Transcoding job accepted by the server.
'job:progress'{ jobId: string; transcodedSeconds: number; totalSeconds?: number; variantsReady: string[] }Transcoder write head advanced. Seek gate may release.
'job:ready-to-play'{ jobId: string }Enough segments available to begin playing.
'job:error'{ jobId: string; error: Error }Transcoding error from the server.
'job:complete'{ jobId: string }Transcoding job finished.

Server message protocol

The plugin reads JSON messages from the WebSocket. It recognises these type values:

typeEffect
'started'Emits 'job:started' and records the currentJobId.
'progress'Updates the transcodedTo state. Emits 'job:progress'. Releases any pending seek gate if the target is now reachable.
'ready-to-play'Emits 'job:ready-to-play'.
'complete'Emits 'job:complete'.

WebSocket connection errors emit 'job:error' directly, not through a message type.

Methods

transcodedTo

TypeScript
const liveTranscoding = player.getPlugin(LiveTranscodingPlugin)!;

const seconds: number = liveTranscoding.transcodedTo();

Returns the current transcoder write head in seconds. Updated by 'progress' messages from the server.

Registration

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

const player = nmplayer('player')
.addPlugin(LiveTranscodingPlugin, {
controlUrl: 'wss://your-server.example.com/jobs/sintel',
seekTimeoutMs: 15_000,
})
.setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Films',
playlist: [
{
title: 'Sintel',
url: '/Sintel.(2010)/Sintel.(2010).NoMercy.m3u8',
},
],
});

player.on('plugin:live-transcoding:job:progress', ({ transcodedSeconds }) => {
console.log('Transcoded to:', transcodedSeconds, 's');
});

See also