@zezosoft/zezo-ott-react-native-video-player
Version:
Production-ready React Native OTT video player library for Android & iOS. Features: playlists, seasons, auto-next playback, subtitles (SRT/VTT), custom theming, analytics tracking, fullscreen mode, gesture controls, ads player (pre-roll/mid-roll/post-roll
128 lines (122 loc) • 3.6 kB
JavaScript
"use strict";
import React, { useCallback, useMemo } from 'react';
import { View, StyleSheet } from 'react-native';
import VideoPlayerCore from "./VideoPlayer/VideoPlayerCore.js";
import { AdsPlayer, useAdsManager } from "./AdsPlayer/index.js";
import { useVideoPlayerStore } from "./VideoPlayer/store/videoPlayerStore.js";
import { useAdsPlayerStore } from "./AdsPlayer/store/adsPlayerStore.js";
import { createPlayerEvents, useWatchReporter, adVideoRef, useAdEventHandler, usePauseVideoOnAd, useOrientationLock, resumeVideoFromAd as resumeVideoFromAdUtil } from "./VideoPlayer/utils/index.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const VideoPlayer = ({
onClose,
isFocused = true,
mode = 'fullscreen',
seekTime,
event,
autoNext = true,
theme,
onWatchProgress,
ads = [],
onAdEnd,
onAdError,
onAdTracking,
insets
}) => {
const isPaused = useVideoPlayerStore(state => state.isPaused);
const activeTrack = useVideoPlayerStore(state => state.activeTrack);
const currentAd = useAdsPlayerStore(state => state.currentAd);
const isAdPlaying = useAdsPlayerStore(state => state.isAdPlaying);
const resumeTime = useAdsPlayerStore(state => state.resumeTime);
const playerEvents = useMemo(() => createPlayerEvents(), []);
const {
reportProgress
} = useWatchReporter({
onWatchProgress
});
const {
checkPostRollAds
} = useAdsManager(ads, onAdTracking);
// Handle orientation locking
useOrientationLock({
isFocused,
mode
});
// Pause main video when ads start playing
usePauseVideoOnAd();
const {
handleAdEnd,
handleAdSkip,
handleAdError
} = useAdEventHandler({
resumeVideoFromAd: resumeVideoFromAdUtil,
resumeTime,
playerEvents,
reportProgress,
onPressEpisode: event?.onPressEpisode,
autoNext,
onAdEnd,
onAdError
});
const handleVideoEnd = useCallback(() => {
// Don't show ads if it's a trailer
if (activeTrack?.isTrailer) {
return;
}
if (checkPostRollAds()) {
return;
}
}, [checkPostRollAds, activeTrack?.isTrailer]);
// Handle ad player close - reset both stores
const handleAdClose = useCallback(() => {
// Reset ads store
const {
resetAdsStore
} = useAdsPlayerStore.getState();
resetAdsStore();
// Reset video player store
const {
resetStore
} = useVideoPlayerStore.getState();
resetStore();
// Call the original onClose if provided
onClose?.();
}, [onClose]);
return /*#__PURE__*/_jsxs(View, {
style: styles.container,
children: [/*#__PURE__*/_jsx(VideoPlayerCore, {
onClose: onClose,
isFocused: isFocused,
mode: mode,
seekTime: seekTime,
event: event,
autoNext: autoNext,
theme: theme,
onWatchProgress: onWatchProgress,
insets: insets,
isPausedOverride: isAdPlaying ? true : isPaused,
onVideoEnd: handleVideoEnd
}), ads.length > 0 && isAdPlaying && currentAd && !activeTrack?.isTrailer && /*#__PURE__*/_jsx(View, {
style: styles.adsOverlay,
children: /*#__PURE__*/_jsx(AdsPlayer, {
ref: adVideoRef,
insets: insets,
onAdEnd: handleAdEnd,
onAdSkip: handleAdSkip,
onAdError: handleAdError,
onAdTracking: onAdTracking,
onClose: handleAdClose
})
})]
});
};
const styles = StyleSheet.create({
container: {
flex: 1
},
adsOverlay: {
...StyleSheet.absoluteFillObject,
zIndex: 1000
}
});
export default /*#__PURE__*/React.memo(VideoPlayer);
//# sourceMappingURL=VideoPlayer.js.map