diff --git a/types/cld-video-player-tests.ts b/types/cld-video-player-tests.ts index 85ea2af6..05f3b409 100644 --- a/types/cld-video-player-tests.ts +++ b/types/cld-video-player-tests.ts @@ -27,3 +27,28 @@ async () => { profile: 'default' }); }; + +// Event methods and the video.js handle. +player.on('ready', () => {}); +player.on('play', (event) => { + const emitter: VideoPlayer = event.Player; + emitter.pause(); +}); +player.on('percentsplayed', (event) => { + const percent: number = event.eventData.percent; + void percent; +}); +player.on('timeplayed', (event) => { + const time: number = event.eventData.time; + void time; +}); +player.one('seek', (event) => { + const from: number = event.eventData.seekStart; + const to: number = event.eventData.seekEnd; + void from; + void to; +}); +player.off('play'); + +const bigPlayButton = player.videojs.el().querySelector('.vjs-big-play-button'); +void bigPlayButton; diff --git a/types/cld-video-player.d.ts b/types/cld-video-player.d.ts index 68b2e87a..8452090c 100644 --- a/types/cld-video-player.d.ts +++ b/types/cld-video-player.d.ts @@ -19,12 +19,63 @@ export interface Cloudinary { players: AsyncPlayersFunction; } +declare const cloudinary: Cloudinary; +export default cloudinary; + declare global { interface Window { cloudinary: Cloudinary; } } +/** + * Event object passed to handlers registered through {@link VideoPlayer.on} / + * {@link VideoPlayer.one}. The player attaches a `Player` reference to every + * forwarded (cloudinary/video.js) event; `eventData` is present on the + * extended events (see {@link PercentsPlayedEvent}, {@link TimePlayedEvent}, + * {@link SeekEvent}). + */ +export interface VideoPlayerEvent { + type: string; + /** The VideoPlayer instance that emitted the event. */ + Player: VideoPlayer; + /** Extra payload attached to forwarded extended events. */ + eventData?: Record; + [key: string]: unknown; +} + +/** `percentsplayed` — fired as playback crosses each configured percentage. */ +export interface PercentsPlayedEvent extends VideoPlayerEvent { + eventData: { percent: number }; +} + +/** `timeplayed` — fired as playback crosses each configured time (seconds). */ +export interface TimePlayedEvent extends VideoPlayerEvent { + eventData: { time: number }; +} + +/** `seek` — fired when the user seeks. */ +export interface SeekEvent extends VideoPlayerEvent { + eventData: { seekStart: number; seekEnd: number }; +} + +export type VideoPlayerEventHandler = + (event: E, ...args: unknown[]) => void; + +/** + * The underlying video.js player instance (`player.videojs`). Only the members + * commonly reached for from application code are typed; the index signature is + * an escape hatch for the rest of the video.js API. + */ +export interface VideoJsPlayer { + el(): Element; + on(event: string, handler: (...args: any[]) => void): void; + one(event: string, handler: (...args: any[]) => void): void; + off(event: string, handler?: (...args: any[]) => void): void; + trigger(event: string | { type: string; [key: string]: unknown }): void; + [key: string]: any; +} + export class VideoPlayer { cloudinaryConfig(config: object): VideoPlayer; currentPublicId(): string; @@ -62,5 +113,25 @@ export class VideoPlayer { ima(): object; loop(bool?: boolean): VideoPlayer|boolean; el(): Element; + + // Event methods — installed at runtime by the player (see setupEventMethods). + // Known extended events are typed with their payload; the trailing string + // overload covers every other (video.js / cloudinary) event. on/one/off + // return the underlying video.js player (what videojsInstance.on returns); + // trigger returns nothing. + on(event: 'percentsplayed', handler: VideoPlayerEventHandler): VideoJsPlayer; + on(event: 'timeplayed', handler: VideoPlayerEventHandler): VideoJsPlayer; + on(event: 'seek', handler: VideoPlayerEventHandler): VideoJsPlayer; + on(event: string, handler: VideoPlayerEventHandler): VideoJsPlayer; + one(event: 'percentsplayed', handler: VideoPlayerEventHandler): VideoJsPlayer; + one(event: 'timeplayed', handler: VideoPlayerEventHandler): VideoJsPlayer; + one(event: 'seek', handler: VideoPlayerEventHandler): VideoJsPlayer; + one(event: string, handler: VideoPlayerEventHandler): VideoJsPlayer; + off(event: string, handler?: VideoPlayerEventHandler): VideoJsPlayer; + trigger(event: string | { type: string; [key: string]: unknown }): void; + + /** Underlying video.js player instance. */ + videojs: VideoJsPlayer; + static all(selector: string, ...args: any): VideoPlayer[]; }