mirror of
https://github.com/zoriya/react-native-video.git
synced 2026-06-28 20:16:41 +00:00
238 lines
7.1 KiB
JavaScript
238 lines
7.1 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.WebEventEmitter = void 0;
|
|
var _VideoError = require("../types/VideoError.js");
|
|
/**
|
|
* video.js store interface — optional, used for enhanced buffering info when available.
|
|
*/
|
|
|
|
/**
|
|
* WebEventEmitter bridges HTML5 media events to our event system.
|
|
* Works with or without a video.js store — video element events are the primary source.
|
|
* When a video.js store is connected, it provides enhanced buffering info.
|
|
*/
|
|
class WebEventEmitter {
|
|
_listeners = new Map();
|
|
_mediaCleanup = null;
|
|
_storeUnsubscribe = null;
|
|
_store = null;
|
|
_isBuffering = false;
|
|
constructor(store, getMedia) {
|
|
this.getMedia = getMedia;
|
|
// Attach to video element immediately if available
|
|
this._attachMediaListeners();
|
|
if (store) this.setStore(store);
|
|
}
|
|
|
|
/**
|
|
* Connect or disconnect the video.js store (optional enhancement).
|
|
*/
|
|
setStore(store) {
|
|
this._storeUnsubscribe?.();
|
|
this._storeUnsubscribe = null;
|
|
this._store = store;
|
|
}
|
|
destroy() {
|
|
this._storeUnsubscribe?.();
|
|
this._storeUnsubscribe = null;
|
|
this._mediaCleanup?.();
|
|
this._mediaCleanup = null;
|
|
}
|
|
_attachMediaListeners() {
|
|
const video = this.getMedia();
|
|
if (!video) return;
|
|
const on = (event, handler) => {
|
|
video.addEventListener(event, handler);
|
|
return () => video.removeEventListener(event, handler);
|
|
};
|
|
const cleanups = [];
|
|
cleanups.push(on("play", () => {
|
|
this._emit("onPlaybackStateChange", {
|
|
isPlaying: true,
|
|
isBuffering: this._isBuffering
|
|
});
|
|
}));
|
|
cleanups.push(on("pause", () => {
|
|
this._emit("onPlaybackStateChange", {
|
|
isPlaying: false,
|
|
isBuffering: this._isBuffering
|
|
});
|
|
}));
|
|
cleanups.push(on("waiting", () => {
|
|
this._isBuffering = true;
|
|
this._emit("onBuffer", true);
|
|
this._emit("onStatusChange", "loading");
|
|
}));
|
|
cleanups.push(on("canplay", () => {
|
|
this._isBuffering = false;
|
|
this._emit("onBuffer", false);
|
|
this._emit("onStatusChange", "readyToPlay");
|
|
}));
|
|
cleanups.push(on("timeupdate", () => {
|
|
const buffered = video.buffered;
|
|
const lastBuffered = buffered.length > 0 ? buffered.end(buffered.length - 1) : 0;
|
|
this._emit("onProgress", {
|
|
currentTime: video.currentTime,
|
|
bufferDuration: lastBuffered
|
|
});
|
|
}));
|
|
cleanups.push(on("durationchange", () => {
|
|
if (video.duration > 0) {
|
|
this._emit("onLoad", {
|
|
currentTime: video.currentTime,
|
|
duration: video.duration,
|
|
width: video.videoWidth,
|
|
height: video.videoHeight,
|
|
orientation: "unknown"
|
|
});
|
|
}
|
|
}));
|
|
cleanups.push(on("ended", () => {
|
|
this._emit("onEnd");
|
|
this._emit("onStatusChange", "idle");
|
|
}));
|
|
cleanups.push(on("ratechange", () => {
|
|
this._emit("onPlaybackRateChange", video.playbackRate);
|
|
}));
|
|
cleanups.push(on("loadeddata", () => {
|
|
this._emit("onReadyToDisplay");
|
|
}));
|
|
cleanups.push(on("seeked", () => {
|
|
this._emit("onSeek", video.currentTime);
|
|
}));
|
|
cleanups.push(on("volumechange", () => {
|
|
this._emit("onVolumeChange", {
|
|
volume: video.volume,
|
|
muted: video.muted
|
|
});
|
|
}));
|
|
cleanups.push(on("loadstart", () => {
|
|
this._emit("onLoadStart", {
|
|
sourceType: "network",
|
|
source: {
|
|
uri: video.currentSrc || video.src,
|
|
config: {
|
|
uri: video.currentSrc || video.src,
|
|
externalSubtitles: []
|
|
},
|
|
getAssetInformationAsync: async () => ({
|
|
duration: video.duration || NaN,
|
|
width: video.videoWidth,
|
|
height: video.videoHeight,
|
|
orientation: "unknown",
|
|
bitrate: NaN,
|
|
fileSize: -1n,
|
|
isHDR: false,
|
|
isLive: false
|
|
})
|
|
}
|
|
});
|
|
}));
|
|
cleanups.push(on("error", () => {
|
|
this._emit("onStatusChange", "error");
|
|
const err = video.error;
|
|
if (!err) {
|
|
console.error("Unknown error occurred in player");
|
|
return;
|
|
}
|
|
const codeMap = {
|
|
1: "player/asset-not-initialized",
|
|
2: "player/not-initialized",
|
|
3: "player/invalid-source",
|
|
4: "source/unsupported-content-type"
|
|
};
|
|
this._emit("onError", new _VideoError.VideoError(codeMap[err.code] ?? "unknown/unknown", err.message));
|
|
}));
|
|
this._mediaCleanup = () => {
|
|
cleanups.forEach(fn => fn());
|
|
};
|
|
}
|
|
|
|
// --- Listener infrastructure ---
|
|
|
|
_addListener(event, listener) {
|
|
if (!this._listeners.has(event)) {
|
|
this._listeners.set(event, new Set());
|
|
}
|
|
this._listeners.get(event).add(listener);
|
|
return {
|
|
remove: () => {
|
|
this._listeners.get(event)?.delete(listener);
|
|
}
|
|
};
|
|
}
|
|
_emit(event, ...args) {
|
|
this._listeners.get(event)?.forEach(fn => fn(...args));
|
|
}
|
|
|
|
// --- Listener registration (implements VideoPlayerEventEmitterBase) ---
|
|
|
|
addOnAudioBecomingNoisyListener(listener) {
|
|
return this._addListener("onAudioBecomingNoisy", listener);
|
|
}
|
|
addOnAudioFocusChangeListener(listener) {
|
|
return this._addListener("onAudioFocusChange", listener);
|
|
}
|
|
addOnBandwidthUpdateListener(listener) {
|
|
return this._addListener("onBandwidthUpdate", listener);
|
|
}
|
|
addOnBufferListener(listener) {
|
|
return this._addListener("onBuffer", listener);
|
|
}
|
|
addOnControlsVisibleChangeListener(listener) {
|
|
return this._addListener("onControlsVisibleChange", listener);
|
|
}
|
|
addOnEndListener(listener) {
|
|
return this._addListener("onEnd", listener);
|
|
}
|
|
addOnExternalPlaybackChangeListener(listener) {
|
|
return this._addListener("onExternalPlaybackChange", listener);
|
|
}
|
|
addOnLoadListener(listener) {
|
|
return this._addListener("onLoad", listener);
|
|
}
|
|
addOnLoadStartListener(listener) {
|
|
return this._addListener("onLoadStart", listener);
|
|
}
|
|
addOnPlaybackStateChangeListener(listener) {
|
|
return this._addListener("onPlaybackStateChange", listener);
|
|
}
|
|
addOnPlaybackRateChangeListener(listener) {
|
|
return this._addListener("onPlaybackRateChange", listener);
|
|
}
|
|
addOnProgressListener(listener) {
|
|
return this._addListener("onProgress", listener);
|
|
}
|
|
addOnReadyToDisplayListener(listener) {
|
|
return this._addListener("onReadyToDisplay", listener);
|
|
}
|
|
addOnSeekListener(listener) {
|
|
return this._addListener("onSeek", listener);
|
|
}
|
|
addOnStatusChangeListener(listener) {
|
|
return this._addListener("onStatusChange", listener);
|
|
}
|
|
addOnTimedMetadataListener(listener) {
|
|
return this._addListener("onTimedMetadata", listener);
|
|
}
|
|
addOnTextTrackDataChangedListener(listener) {
|
|
return this._addListener("onTextTrackDataChanged", listener);
|
|
}
|
|
addOnTrackChangeListener(listener) {
|
|
return this._addListener("onTrackChange", listener);
|
|
}
|
|
addOnVolumeChangeListener(listener) {
|
|
return this._addListener("onVolumeChange", listener);
|
|
}
|
|
clearAllListeners() {
|
|
this._listeners.clear();
|
|
}
|
|
addOnErrorListener(listener) {
|
|
return this._addListener("onError", listener);
|
|
}
|
|
}
|
|
exports.WebEventEmitter = WebEventEmitter;
|
|
//# sourceMappingURL=WebEventEmitter.js.map
|