UNPKG

@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

186 lines (157 loc) 4.53 kB
import { mmkvStorage, useVideoPlayerStore } from '../../store/videoPlayerStore'; import type { MediaEpisode } from '../../store/videoPlayer.type'; export const handlePause = () => { const { setIsPaused, startWatchTime, setStartWatchTime } = useVideoPlayerStore.getState(); setIsPaused(true); if (!startWatchTime) return; const elapsedTime = (Date.now() - startWatchTime) / 1000; const storedTime = Number(mmkvStorage.getItem('current_watch_time') ?? 0); mmkvStorage.setItem( 'current_watch_time', (storedTime + elapsedTime).toString() ); setStartWatchTime(null); }; interface HandleNextOptions { onPressEpisode: ({ episode }: { episode: MediaEpisode }) => Promise<boolean>; autoNext?: boolean; } export const handleNext = async ({ onPressEpisode, autoNext, }: HandleNextOptions): Promise<number | null> => { const { playList: playlist, currentTrackIndex, setCurrentTrackIndex, setActiveTrack, setCurrentTime, setIsPaused, setActiveSubtitle, setPlayBackRate, contentSeasons, setActiveSeason, setControlsVisible, setSelectedSubtitleTrack, setSelectedVideoTrack, setMaxBitRate, setDuration, } = useVideoPlayerStore.getState(); if (!playlist?.length) return null; if (!autoNext) { setIsPaused(true); setControlsVisible(true); return currentTrackIndex; } let nextIndex = currentTrackIndex + 1; if (nextIndex >= playlist.length) { setIsPaused(true); setControlsVisible(true); return currentTrackIndex; } const nextTrack = playlist[nextIndex]; if (!nextTrack) return currentTrackIndex; let isSuccess = true; if (onPressEpisode) { isSuccess = await onPressEpisode({ episode: { id: nextTrack.episodeId || '', title: nextTrack.episodeName ?? '', contentId: nextTrack.contentId || '', sourceLink: nextTrack.sourceLink, thumbnail: nextTrack.thumbnail, nextEpisodeAt: nextTrack.nextEpisodeAt, publishDate: nextTrack.publishDate, skipIntro: nextTrack.skipIntro, description: nextTrack?.description || '', duration: nextTrack?.duration || 0, sourceType: nextTrack?.sourceType || 'HLS', episodeNumber: nextTrack?.episodeNumber || 0, subtitles: nextTrack?.subtitles ?? [], }, }); } if (!isSuccess) { setIsPaused(true); setControlsVisible(true); return currentTrackIndex; } setIsPaused(false); setCurrentTime(0); setDuration(0); setCurrentTrackIndex(nextIndex); setActiveTrack(nextTrack); setActiveSubtitle(null); setSelectedVideoTrack(null); setMaxBitRate(null); setPlayBackRate(1, 'Normal'); setSelectedSubtitleTrack(null); if (nextTrack.seasonId) { const activeSeason = contentSeasons?.find( (s) => s.id === nextTrack.seasonId ); if (activeSeason) { setActiveSeason(activeSeason); } } return nextIndex; }; export const viewCount = (): boolean => { const { isViewCounted, setIsViewCounted, activeTrack } = useVideoPlayerStore.getState(); if (!isViewCounted) { if (activeTrack?.id) { setIsViewCounted(true); return true; } } else { return false; } return false; }; export const countWatchTime = (): { totalWatchTime: number; completed: boolean; currentTime: number; } => { const { activeTrack, duration, setStartWatchTime, startWatchTime } = useVideoPlayerStore.getState(); const currentTimeFromStorage = Number( mmkvStorage.getItem('currentTime') || 0 ); const prevWatchTime = Number(mmkvStorage.getItem('current_watch_time') || 0); const completed = duration > 0 && Math.round(currentTimeFromStorage / duration) >= 0.95; if (!startWatchTime) { return { totalWatchTime: prevWatchTime, completed, currentTime: currentTimeFromStorage, }; } const elapsedTime = (Date.now() - startWatchTime) / 1000; const totalTimeWatched = prevWatchTime + elapsedTime; mmkvStorage.setItem('current_watch_time', totalTimeWatched.toString()); setStartWatchTime(null); if (totalTimeWatched < 30) { return { totalWatchTime: 0, completed: false, currentTime: currentTimeFromStorage, }; } if (activeTrack?.id) { return { totalWatchTime: totalTimeWatched, completed, currentTime: currentTimeFromStorage, }; } mmkvStorage.setItem('current_watch_time', '0'); return { totalWatchTime: 0, completed: false, currentTime: 0, }; };