Adapter: Transition Strategy
Where Preload Strategy decides when and what to prefetch, ITransitionStrategy decides how the player crosses from the outgoing item to the incoming one.
The interface
interface ITransitionStrategy {
shouldTransition(context: PreloadContext): boolean;
tick(context: TransitionContext, backend: ITransitionBackend | null): void;
start(outgoing: BasePlaylistItem, incoming: BasePlaylistItem, backend: ITransitionBackend | null): void;
complete(from: BasePlaylistItem, to: BasePlaylistItem): void;
cancel(reason: string): void;
}
start() fires once when shouldTransition first returns true, tick() runs every animation frame during the transition window (apply volume ramps or curves here, keep it fast and non-blocking), complete() fires once the incoming item is fully primary, and cancel(reason) fires if the transition is aborted early (a manual next(), a dispose).
ITransitionBackend is the narrow six-method surface (supportsCrossfade, loadSecondary, primeSecondary, crossfade, disposeSecondary, secondaryGain) a backend needs to host dual-playback, deliberately smaller than the full backend contract so the transition engine works across audio and video without importing per-library types.
Shipped implementations
| Class | Default for | Behavior |
|---|---|---|
CrossfadeTransitionStrategy | Music | Linear or equal-power volume fade over leadSeconds (default 3s) before end + tailSeconds (default 3s) after the incoming item starts. curve: 'equal-power' avoids the perceptual volume dip a linear fade has at the midpoint. |
GaplessTransitionStrategy | Video | Hard-cut at the natural end, no overlap. The incoming item is already warm from preloading, so buffering is near-zero. |
Rules & restrictions
- Audio crossfade on a video player is technically possible (duck outgoing, raise incoming) but needs two simultaneously active
<video>elements, which browsers handle inconsistently. Opt in explicitly withCrossfadeTransitionStrategyif you want it, it isn’t the video default for that reason. tick()receivingbackend === nullmeans noITransitionBackend-capable backend is registered, implementations should no-op rather than throw.
How to extend it
import nmplayer from '@nomercy-entertainment/nomercy-video-player'; // nomercy-music-player's factory works identically
import { CrossfadeTransitionStrategy } from '@nomercy-entertainment/nomercy-player-core';
const player = nmplayer('player');
player.setup({
transitionStrategy: new CrossfadeTransitionStrategy({ leadSeconds: 5, curve: 'equal-power' }),
});
Next steps
- Adapter: Shuffle Strategy: the permutation the queue applies when shuffled.