@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
96 lines (85 loc) • 2.48 kB
text/typescript
import { useCallback } from 'react';
import type { VideoAd } from '../../store/videoPlayer.type';
import type { ExtendedWatchProgress } from '../player/useWatchReporter';
import type { MediaEpisode } from '../../store/videoPlayer.type';
interface UseAdEventHandlerParams {
resumeVideoFromAd: (resumeTime: number | null) => void;
resumeTime: number | null;
playerEvents: {
onEnd: (params: {
reportProgress: (event: ExtendedWatchProgress['event']) => void;
onPressEpisode: ({
episode,
}: {
episode: MediaEpisode;
}) => Promise<boolean>;
autoNext: boolean;
}) => void;
};
reportProgress: (event: ExtendedWatchProgress['event']) => void;
onPressEpisode?: ({ episode }: { episode: MediaEpisode }) => Promise<boolean>;
autoNext: boolean;
onAdEnd?: (ad: VideoAd) => void;
onAdError?: (error: Error, ad: VideoAd) => void;
}
/**
* Reusable hook for handling ad events (end, skip, error)
* Consolidates duplicate logic from handleAdEnd, handleAdSkip, and handleAdError
*/
export const useAdEventHandler = ({
resumeVideoFromAd,
resumeTime,
playerEvents,
reportProgress,
onPressEpisode,
autoNext,
onAdEnd,
onAdError,
}: UseAdEventHandlerParams) => {
const handlePostRollAd = useCallback(() => {
playerEvents.onEnd({
reportProgress,
onPressEpisode: onPressEpisode ?? (async () => true),
autoNext,
});
}, [playerEvents, reportProgress, onPressEpisode, autoNext]);
const handleNonPostRollAd = useCallback(() => {
resumeVideoFromAd(resumeTime);
}, [resumeVideoFromAd, resumeTime]);
const handleAdEnd = useCallback(
(endedAd: VideoAd) => {
onAdEnd?.(endedAd);
if (endedAd.position === 'post') {
handlePostRollAd();
} else {
handleNonPostRollAd();
}
},
[onAdEnd, handlePostRollAd, handleNonPostRollAd]
);
const handleAdSkip = useCallback(
(skippedAd: VideoAd) => {
onAdEnd?.(skippedAd);
if (skippedAd.position !== 'post') {
handleNonPostRollAd();
}
},
[onAdEnd, handleNonPostRollAd]
);
const handleAdError = useCallback(
(error: Error, errorAd: VideoAd) => {
onAdError?.(error, errorAd);
if (errorAd.position !== 'post') {
handleNonPostRollAd();
} else {
handlePostRollAd();
}
},
[onAdError, handleNonPostRollAd, handlePostRollAd]
);
return {
handleAdEnd,
handleAdSkip,
handleAdError,
};
};