mirror of
https://github.com/zoriya/react-native-video.git
synced 2026-08-16 02:56:22 +00:00
refactor(web): split events by platform and isolate DOM types
This commit is contained in:
+1
-1
@@ -84,4 +84,4 @@ android/keystores/debug.keystore
|
||||
lib/
|
||||
|
||||
# TypeScript
|
||||
tsconfig.tsbuildinfo
|
||||
*.tsbuildinfo
|
||||
@@ -16,7 +16,7 @@
|
||||
"allowUnusedLabels": false,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["ESNext", "dom"],
|
||||
"lib": ["ESNext"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"noEmit": true,
|
||||
|
||||
@@ -18,8 +18,6 @@ import { WebEventEmitter } from "./web/WebEventEmitter";
|
||||
import type { VideoTrack } from "./types/VideoTrack";
|
||||
import type { QualityLevel } from "./types/QualityLevel";
|
||||
import type { SupportedFeatures } from "./types/SupportedFeatures";
|
||||
import type { ListenerSubscription } from "./types/EventEmitter";
|
||||
import type { AllPlayerEvents as PlayerEvents } from "./types/Events";
|
||||
import {
|
||||
mapVideoJsTracks,
|
||||
type VideoJsPlayer,
|
||||
@@ -409,27 +407,6 @@ class VideoPlayer extends VideoPlayerEvents implements VideoPlayerBase {
|
||||
};
|
||||
}
|
||||
|
||||
addEventListener<Event extends keyof PlayerEvents>(
|
||||
event: Event,
|
||||
callback: PlayerEvents[Event],
|
||||
): ListenerSubscription {
|
||||
switch (event) {
|
||||
case "onAudioTrackChange":
|
||||
return (this.eventEmitter as WebEventEmitter).addOnAudioTrackChangeListener(
|
||||
callback as PlayerEvents["onAudioTrackChange"],
|
||||
);
|
||||
case "onVideoTrackChange":
|
||||
return (this.eventEmitter as WebEventEmitter).addOnVideoTrackChangeListener(
|
||||
callback as PlayerEvents["onVideoTrackChange"],
|
||||
);
|
||||
case "onQualityChange":
|
||||
return (this.eventEmitter as WebEventEmitter).addOnQualityChangeListener(
|
||||
callback as PlayerEvents["onQualityChange"],
|
||||
);
|
||||
default:
|
||||
return super.addEventListener(event, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { VideoPlayer };
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { AllPlayerEvents as PlayerEvents } from "./types/Events";
|
||||
import type { ListenerSubscription } from "./types/EventEmitter";
|
||||
import { VideoPlayerEventsBase } from "./VideoPlayerEventsBase";
|
||||
|
||||
export class VideoPlayerEvents extends VideoPlayerEventsBase {
|
||||
addEventListener<Event extends keyof PlayerEvents>(
|
||||
event: Event,
|
||||
callback: PlayerEvents[Event],
|
||||
): ListenerSubscription {
|
||||
switch (event) {
|
||||
// ----------------- Native-only Events -----------------
|
||||
case 'onAudioBecomingNoisy':
|
||||
return this.eventEmitter.addOnAudioBecomingNoisyListener(
|
||||
callback as PlayerEvents['onAudioBecomingNoisy']
|
||||
);
|
||||
case 'onAudioFocusChange':
|
||||
return this.eventEmitter.addOnAudioFocusChangeListener(
|
||||
callback as PlayerEvents['onAudioFocusChange']
|
||||
);
|
||||
case 'onBandwidthUpdate':
|
||||
return this.eventEmitter.addOnBandwidthUpdateListener(
|
||||
callback as PlayerEvents['onBandwidthUpdate']
|
||||
);
|
||||
case 'onControlsVisibleChange':
|
||||
return this.eventEmitter.addOnControlsVisibleChangeListener(
|
||||
callback as PlayerEvents['onControlsVisibleChange']
|
||||
);
|
||||
case 'onExternalPlaybackChange':
|
||||
return this.eventEmitter.addOnExternalPlaybackChangeListener(
|
||||
callback as PlayerEvents['onExternalPlaybackChange']
|
||||
);
|
||||
case 'onTimedMetadata':
|
||||
return this.eventEmitter.addOnTimedMetadataListener(
|
||||
callback as PlayerEvents['onTimedMetadata']
|
||||
);
|
||||
case 'onTextTrackDataChanged':
|
||||
return this.eventEmitter.addOnTextTrackDataChangedListener(
|
||||
callback as PlayerEvents['onTextTrackDataChanged']
|
||||
);
|
||||
default:
|
||||
return super.addEventListener(event, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,146 +1,3 @@
|
||||
import {
|
||||
ALL_PLAYER_EVENTS,
|
||||
type JSVideoPlayerEvents,
|
||||
type AllPlayerEvents as PlayerEvents,
|
||||
} from "./types/Events";
|
||||
import type {
|
||||
ListenerSubscription,
|
||||
VideoPlayerEventEmitterBase,
|
||||
} from "./types/EventEmitter";
|
||||
|
||||
export class VideoPlayerEvents {
|
||||
protected eventEmitter: VideoPlayerEventEmitterBase;
|
||||
protected jsEventListeners: Partial<
|
||||
Record<keyof PlayerEvents, Set<(...params: any[]) => void>>
|
||||
> = {};
|
||||
|
||||
protected readonly supportedEvents: (keyof PlayerEvents)[] =
|
||||
ALL_PLAYER_EVENTS;
|
||||
|
||||
constructor(eventEmitter: VideoPlayerEventEmitterBase) {
|
||||
this.eventEmitter = eventEmitter;
|
||||
}
|
||||
|
||||
protected triggerJSEvent<Event extends keyof JSVideoPlayerEvents>(
|
||||
event: Event,
|
||||
...params: Parameters<JSVideoPlayerEvents[Event]>
|
||||
): boolean {
|
||||
if (!this.jsEventListeners[event]) return false;
|
||||
this.jsEventListeners[event]?.forEach((fn) => fn(...params));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for a player event.
|
||||
* @throw Error if the event is not supported.
|
||||
* @param event - The event to add a listener for.
|
||||
* @param callback - The callback to call when the event is triggered.
|
||||
* @returns A subscription object that can be used to remove the listener.
|
||||
*/
|
||||
addEventListener<Event extends keyof PlayerEvents>(
|
||||
event: Event,
|
||||
callback: PlayerEvents[Event]
|
||||
): ListenerSubscription {
|
||||
switch (event) {
|
||||
// ----------------- JS Events -----------------
|
||||
case 'onError':
|
||||
this.jsEventListeners.onError ??= new Set();
|
||||
this.jsEventListeners.onError.add(
|
||||
callback as JSVideoPlayerEvents['onError']
|
||||
);
|
||||
return {
|
||||
remove: () =>
|
||||
this.jsEventListeners.onError?.delete(
|
||||
callback as JSVideoPlayerEvents['onError']
|
||||
),
|
||||
};
|
||||
// ----------------- Native Events -----------------
|
||||
case 'onAudioBecomingNoisy':
|
||||
return this.eventEmitter.addOnAudioBecomingNoisyListener(
|
||||
callback as PlayerEvents['onAudioBecomingNoisy']
|
||||
);
|
||||
case 'onAudioFocusChange':
|
||||
return this.eventEmitter.addOnAudioFocusChangeListener(
|
||||
callback as PlayerEvents['onAudioFocusChange']
|
||||
);
|
||||
case 'onBandwidthUpdate':
|
||||
return this.eventEmitter.addOnBandwidthUpdateListener(
|
||||
callback as PlayerEvents['onBandwidthUpdate']
|
||||
);
|
||||
case 'onBuffer':
|
||||
return this.eventEmitter.addOnBufferListener(
|
||||
callback as PlayerEvents['onBuffer']
|
||||
);
|
||||
case 'onControlsVisibleChange':
|
||||
return this.eventEmitter.addOnControlsVisibleChangeListener(
|
||||
callback as PlayerEvents['onControlsVisibleChange']
|
||||
);
|
||||
case 'onEnd':
|
||||
return this.eventEmitter.addOnEndListener(
|
||||
callback as PlayerEvents['onEnd']
|
||||
);
|
||||
case 'onExternalPlaybackChange':
|
||||
return this.eventEmitter.addOnExternalPlaybackChangeListener(
|
||||
callback as PlayerEvents['onExternalPlaybackChange']
|
||||
);
|
||||
case 'onLoad':
|
||||
return this.eventEmitter.addOnLoadListener(
|
||||
callback as PlayerEvents['onLoad']
|
||||
);
|
||||
case 'onLoadStart':
|
||||
return this.eventEmitter.addOnLoadStartListener(
|
||||
callback as PlayerEvents['onLoadStart']
|
||||
);
|
||||
case 'onPlaybackStateChange':
|
||||
return this.eventEmitter.addOnPlaybackStateChangeListener(
|
||||
callback as PlayerEvents['onPlaybackStateChange']
|
||||
);
|
||||
case 'onPlaybackRateChange':
|
||||
return this.eventEmitter.addOnPlaybackRateChangeListener(
|
||||
callback as PlayerEvents['onPlaybackRateChange']
|
||||
);
|
||||
case 'onProgress':
|
||||
return this.eventEmitter.addOnProgressListener(
|
||||
callback as PlayerEvents['onProgress']
|
||||
);
|
||||
case 'onReadyToDisplay':
|
||||
return this.eventEmitter.addOnReadyToDisplayListener(
|
||||
callback as PlayerEvents['onReadyToDisplay']
|
||||
);
|
||||
case 'onSeek':
|
||||
return this.eventEmitter.addOnSeekListener(
|
||||
callback as PlayerEvents['onSeek']
|
||||
);
|
||||
case 'onTimedMetadata':
|
||||
return this.eventEmitter.addOnTimedMetadataListener(
|
||||
callback as PlayerEvents['onTimedMetadata']
|
||||
);
|
||||
case 'onTextTrackDataChanged':
|
||||
return this.eventEmitter.addOnTextTrackDataChangedListener(
|
||||
callback as PlayerEvents['onTextTrackDataChanged']
|
||||
);
|
||||
case 'onTrackChange':
|
||||
return this.eventEmitter.addOnTrackChangeListener(
|
||||
callback as PlayerEvents['onTrackChange']
|
||||
);
|
||||
case 'onVolumeChange':
|
||||
return this.eventEmitter.addOnVolumeChangeListener(
|
||||
callback as PlayerEvents['onVolumeChange']
|
||||
);
|
||||
case 'onStatusChange':
|
||||
return this.eventEmitter.addOnStatusChangeListener(
|
||||
callback as PlayerEvents['onStatusChange']
|
||||
);
|
||||
default:
|
||||
throw new Error(`[React Native Video] Unsupported event: ${event}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all events from the event emitter.
|
||||
*/
|
||||
clearAllEvents() {
|
||||
this.jsEventListeners = {};
|
||||
this.eventEmitter.clearAllListeners();
|
||||
}
|
||||
}
|
||||
// Platform-specific versions: VideoPlayerEvents.native.ts, VideoPlayerEvents.web.ts
|
||||
// This file is the default fallback for TypeScript resolution.
|
||||
export { VideoPlayerEvents } from "./VideoPlayerEvents.native";
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { AllPlayerEvents as PlayerEvents } from "./types/Events";
|
||||
import type { ListenerSubscription } from "./types/EventEmitter";
|
||||
import { VideoPlayerEventsBase } from "./VideoPlayerEventsBase";
|
||||
import type { WebEventEmitter } from "./web/WebEventEmitter";
|
||||
|
||||
export class VideoPlayerEvents extends VideoPlayerEventsBase {
|
||||
addEventListener<Event extends keyof PlayerEvents>(
|
||||
event: Event,
|
||||
callback: PlayerEvents[Event],
|
||||
): ListenerSubscription {
|
||||
switch (event) {
|
||||
// ----------------- Web-only Events -----------------
|
||||
case 'onAudioTrackChange':
|
||||
return (this.eventEmitter as WebEventEmitter).addOnAudioTrackChangeListener(
|
||||
callback as PlayerEvents['onAudioTrackChange']
|
||||
);
|
||||
case 'onVideoTrackChange':
|
||||
return (this.eventEmitter as WebEventEmitter).addOnVideoTrackChangeListener(
|
||||
callback as PlayerEvents['onVideoTrackChange']
|
||||
);
|
||||
case 'onQualityChange':
|
||||
return (this.eventEmitter as WebEventEmitter).addOnQualityChangeListener(
|
||||
callback as PlayerEvents['onQualityChange']
|
||||
);
|
||||
default:
|
||||
return super.addEventListener(event, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import {
|
||||
ALL_PLAYER_EVENTS,
|
||||
type JSVideoPlayerEvents,
|
||||
type AllPlayerEvents as PlayerEvents,
|
||||
} from "./types/Events";
|
||||
import type {
|
||||
ListenerSubscription,
|
||||
VideoPlayerEventEmitterBase,
|
||||
} from "./types/EventEmitter";
|
||||
|
||||
export class VideoPlayerEventsBase {
|
||||
protected eventEmitter: VideoPlayerEventEmitterBase;
|
||||
protected jsEventListeners: Partial<
|
||||
Record<keyof PlayerEvents, Set<(...params: any[]) => void>>
|
||||
> = {};
|
||||
|
||||
protected readonly supportedEvents: (keyof PlayerEvents)[] =
|
||||
ALL_PLAYER_EVENTS;
|
||||
|
||||
constructor(eventEmitter: VideoPlayerEventEmitterBase) {
|
||||
this.eventEmitter = eventEmitter;
|
||||
}
|
||||
|
||||
protected triggerJSEvent<Event extends keyof JSVideoPlayerEvents>(
|
||||
event: Event,
|
||||
...params: Parameters<JSVideoPlayerEvents[Event]>
|
||||
): boolean {
|
||||
if (!this.jsEventListeners[event]) return false;
|
||||
this.jsEventListeners[event]?.forEach((fn) => fn(...params));
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener<Event extends keyof PlayerEvents>(
|
||||
event: Event,
|
||||
callback: PlayerEvents[Event]
|
||||
): ListenerSubscription {
|
||||
switch (event) {
|
||||
// ----------------- JS Events -----------------
|
||||
case 'onError':
|
||||
this.jsEventListeners.onError ??= new Set();
|
||||
this.jsEventListeners.onError.add(
|
||||
callback as JSVideoPlayerEvents['onError']
|
||||
);
|
||||
return {
|
||||
remove: () =>
|
||||
this.jsEventListeners.onError?.delete(
|
||||
callback as JSVideoPlayerEvents['onError']
|
||||
),
|
||||
};
|
||||
// ----------------- Shared Events -----------------
|
||||
case 'onBuffer':
|
||||
return this.eventEmitter.addOnBufferListener(
|
||||
callback as PlayerEvents['onBuffer']
|
||||
);
|
||||
case 'onEnd':
|
||||
return this.eventEmitter.addOnEndListener(
|
||||
callback as PlayerEvents['onEnd']
|
||||
);
|
||||
case 'onLoad':
|
||||
return this.eventEmitter.addOnLoadListener(
|
||||
callback as PlayerEvents['onLoad']
|
||||
);
|
||||
case 'onLoadStart':
|
||||
return this.eventEmitter.addOnLoadStartListener(
|
||||
callback as PlayerEvents['onLoadStart']
|
||||
);
|
||||
case 'onPlaybackStateChange':
|
||||
return this.eventEmitter.addOnPlaybackStateChangeListener(
|
||||
callback as PlayerEvents['onPlaybackStateChange']
|
||||
);
|
||||
case 'onPlaybackRateChange':
|
||||
return this.eventEmitter.addOnPlaybackRateChangeListener(
|
||||
callback as PlayerEvents['onPlaybackRateChange']
|
||||
);
|
||||
case 'onProgress':
|
||||
return this.eventEmitter.addOnProgressListener(
|
||||
callback as PlayerEvents['onProgress']
|
||||
);
|
||||
case 'onReadyToDisplay':
|
||||
return this.eventEmitter.addOnReadyToDisplayListener(
|
||||
callback as PlayerEvents['onReadyToDisplay']
|
||||
);
|
||||
case 'onSeek':
|
||||
return this.eventEmitter.addOnSeekListener(
|
||||
callback as PlayerEvents['onSeek']
|
||||
);
|
||||
case 'onTrackChange':
|
||||
return this.eventEmitter.addOnTrackChangeListener(
|
||||
callback as PlayerEvents['onTrackChange']
|
||||
);
|
||||
case 'onVolumeChange':
|
||||
return this.eventEmitter.addOnVolumeChangeListener(
|
||||
callback as PlayerEvents['onVolumeChange']
|
||||
);
|
||||
case 'onStatusChange':
|
||||
return this.eventEmitter.addOnStatusChangeListener(
|
||||
callback as PlayerEvents['onStatusChange']
|
||||
);
|
||||
default:
|
||||
throw new Error(`[React Native Video] Unsupported event: ${event}`);
|
||||
}
|
||||
}
|
||||
|
||||
clearAllEvents() {
|
||||
this.jsEventListeners = {};
|
||||
this.eventEmitter.clearAllListeners();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user