@zezosoft/zezo-ott-react-native-video-player 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +308 -0
  3. package/lib/module/VideoPlayer/MediaControls/BottomControls.js +156 -0
  4. package/lib/module/VideoPlayer/MediaControls/BottomControls.js.map +1 -0
  5. package/lib/module/VideoPlayer/MediaControls/MediaControls.js +27 -0
  6. package/lib/module/VideoPlayer/MediaControls/MediaControls.js.map +1 -0
  7. package/lib/module/VideoPlayer/MediaControls/MediaControlsProvider.js +85 -0
  8. package/lib/module/VideoPlayer/MediaControls/MediaControlsProvider.js.map +1 -0
  9. package/lib/module/VideoPlayer/MediaControls/MiddleControls.js +208 -0
  10. package/lib/module/VideoPlayer/MediaControls/MiddleControls.js.map +1 -0
  11. package/lib/module/VideoPlayer/MediaControls/TopControls.js +94 -0
  12. package/lib/module/VideoPlayer/MediaControls/TopControls.js.map +1 -0
  13. package/lib/module/VideoPlayer/Styles/fonts.js +58 -0
  14. package/lib/module/VideoPlayer/Styles/fonts.js.map +1 -0
  15. package/lib/module/VideoPlayer/Styles/globalStyles.js +75 -0
  16. package/lib/module/VideoPlayer/Styles/globalStyles.js.map +1 -0
  17. package/lib/module/VideoPlayer/VideoPlayer.js +180 -0
  18. package/lib/module/VideoPlayer/VideoPlayer.js.map +1 -0
  19. package/lib/module/VideoPlayer/components/ProgressBar.js +84 -0
  20. package/lib/module/VideoPlayer/components/ProgressBar.js.map +1 -0
  21. package/lib/module/VideoPlayer/components/SkipAndNextControls.js +154 -0
  22. package/lib/module/VideoPlayer/components/SkipAndNextControls.js.map +1 -0
  23. package/lib/module/VideoPlayer/components/SubtitleView.js +57 -0
  24. package/lib/module/VideoPlayer/components/SubtitleView.js.map +1 -0
  25. package/lib/module/VideoPlayer/context/VideoPlayerConfig.js +47 -0
  26. package/lib/module/VideoPlayer/context/VideoPlayerConfig.js.map +1 -0
  27. package/lib/module/VideoPlayer/context/index.js +4 -0
  28. package/lib/module/VideoPlayer/context/index.js.map +1 -0
  29. package/lib/module/VideoPlayer/index.js +7 -0
  30. package/lib/module/VideoPlayer/index.js.map +1 -0
  31. package/lib/module/VideoPlayer/model/AudioAndSubtitles.js +257 -0
  32. package/lib/module/VideoPlayer/model/AudioAndSubtitles.js.map +1 -0
  33. package/lib/module/VideoPlayer/model/Episodes.js +272 -0
  34. package/lib/module/VideoPlayer/model/Episodes.js.map +1 -0
  35. package/lib/module/VideoPlayer/model/SettingModal.js +115 -0
  36. package/lib/module/VideoPlayer/model/SettingModal.js.map +1 -0
  37. package/lib/module/VideoPlayer/model/SpeedControls.js +140 -0
  38. package/lib/module/VideoPlayer/model/SpeedControls.js.map +1 -0
  39. package/lib/module/VideoPlayer/model/VideoPlayerSettings.js +113 -0
  40. package/lib/module/VideoPlayer/model/VideoPlayerSettings.js.map +1 -0
  41. package/lib/module/VideoPlayer/store/index.js +5 -0
  42. package/lib/module/VideoPlayer/store/index.js.map +1 -0
  43. package/lib/module/VideoPlayer/store/videoPlayer.type.js +4 -0
  44. package/lib/module/VideoPlayer/store/videoPlayer.type.js.map +1 -0
  45. package/lib/module/VideoPlayer/store/videoPlayerStore.js +147 -0
  46. package/lib/module/VideoPlayer/store/videoPlayerStore.js.map +1 -0
  47. package/lib/module/VideoPlayer/utils/Display.js +22 -0
  48. package/lib/module/VideoPlayer/utils/Display.js.map +1 -0
  49. package/lib/module/VideoPlayer/utils/PlatformSelector.js +18 -0
  50. package/lib/module/VideoPlayer/utils/PlatformSelector.js.map +1 -0
  51. package/lib/module/VideoPlayer/utils/hooks/index.js +5 -0
  52. package/lib/module/VideoPlayer/utils/hooks/index.js.map +1 -0
  53. package/lib/module/VideoPlayer/utils/hooks/useVideoPlayerBack.js +48 -0
  54. package/lib/module/VideoPlayer/utils/hooks/useVideoPlayerBack.js.map +1 -0
  55. package/lib/module/VideoPlayer/utils/hooks/useVideoResolutions.js +88 -0
  56. package/lib/module/VideoPlayer/utils/hooks/useVideoResolutions.js.map +1 -0
  57. package/lib/module/VideoPlayer/utils/index.js +10 -0
  58. package/lib/module/VideoPlayer/utils/index.js.map +1 -0
  59. package/lib/module/VideoPlayer/utils/lockOrientation.js +31 -0
  60. package/lib/module/VideoPlayer/utils/lockOrientation.js.map +1 -0
  61. package/lib/module/VideoPlayer/utils/playerEvents.js +79 -0
  62. package/lib/module/VideoPlayer/utils/playerEvents.js.map +1 -0
  63. package/lib/module/VideoPlayer/utils/timeFormatter.js +35 -0
  64. package/lib/module/VideoPlayer/utils/timeFormatter.js.map +1 -0
  65. package/lib/module/VideoPlayer/utils/useWatchReporter.js +68 -0
  66. package/lib/module/VideoPlayer/utils/useWatchReporter.js.map +1 -0
  67. package/lib/module/VideoPlayer/utils/videoControl.js +166 -0
  68. package/lib/module/VideoPlayer/utils/videoControl.js.map +1 -0
  69. package/lib/module/VideoPlayer/utils/videoRef.js +5 -0
  70. package/lib/module/VideoPlayer/utils/videoRef.js.map +1 -0
  71. package/lib/module/VideoPlayer/utils/videoSource.js +17 -0
  72. package/lib/module/VideoPlayer/utils/videoSource.js.map +1 -0
  73. package/lib/module/index.js +4 -0
  74. package/lib/module/index.js.map +1 -0
  75. package/lib/module/package.json +1 -0
  76. package/lib/typescript/package.json +1 -0
  77. package/lib/typescript/src/VideoPlayer/MediaControls/BottomControls.d.ts +3 -0
  78. package/lib/typescript/src/VideoPlayer/MediaControls/BottomControls.d.ts.map +1 -0
  79. package/lib/typescript/src/VideoPlayer/MediaControls/MediaControls.d.ts +6 -0
  80. package/lib/typescript/src/VideoPlayer/MediaControls/MediaControls.d.ts.map +1 -0
  81. package/lib/typescript/src/VideoPlayer/MediaControls/MediaControlsProvider.d.ts +14 -0
  82. package/lib/typescript/src/VideoPlayer/MediaControls/MediaControlsProvider.d.ts.map +1 -0
  83. package/lib/typescript/src/VideoPlayer/MediaControls/MiddleControls.d.ts +3 -0
  84. package/lib/typescript/src/VideoPlayer/MediaControls/MiddleControls.d.ts.map +1 -0
  85. package/lib/typescript/src/VideoPlayer/MediaControls/TopControls.d.ts +7 -0
  86. package/lib/typescript/src/VideoPlayer/MediaControls/TopControls.d.ts.map +1 -0
  87. package/lib/typescript/src/VideoPlayer/Styles/fonts.d.ts +54 -0
  88. package/lib/typescript/src/VideoPlayer/Styles/fonts.d.ts.map +1 -0
  89. package/lib/typescript/src/VideoPlayer/Styles/globalStyles.d.ts +70 -0
  90. package/lib/typescript/src/VideoPlayer/Styles/globalStyles.d.ts.map +1 -0
  91. package/lib/typescript/src/VideoPlayer/VideoPlayer.d.ts +22 -0
  92. package/lib/typescript/src/VideoPlayer/VideoPlayer.d.ts.map +1 -0
  93. package/lib/typescript/src/VideoPlayer/components/ProgressBar.d.ts +12 -0
  94. package/lib/typescript/src/VideoPlayer/components/ProgressBar.d.ts.map +1 -0
  95. package/lib/typescript/src/VideoPlayer/components/SkipAndNextControls.d.ts +12 -0
  96. package/lib/typescript/src/VideoPlayer/components/SkipAndNextControls.d.ts.map +1 -0
  97. package/lib/typescript/src/VideoPlayer/components/SubtitleView.d.ts +3 -0
  98. package/lib/typescript/src/VideoPlayer/components/SubtitleView.d.ts.map +1 -0
  99. package/lib/typescript/src/VideoPlayer/context/VideoPlayerConfig.d.ts +25 -0
  100. package/lib/typescript/src/VideoPlayer/context/VideoPlayerConfig.d.ts.map +1 -0
  101. package/lib/typescript/src/VideoPlayer/context/index.d.ts +3 -0
  102. package/lib/typescript/src/VideoPlayer/context/index.d.ts.map +1 -0
  103. package/lib/typescript/src/VideoPlayer/index.d.ts +5 -0
  104. package/lib/typescript/src/VideoPlayer/index.d.ts.map +1 -0
  105. package/lib/typescript/src/VideoPlayer/model/AudioAndSubtitles.d.ts +4 -0
  106. package/lib/typescript/src/VideoPlayer/model/AudioAndSubtitles.d.ts.map +1 -0
  107. package/lib/typescript/src/VideoPlayer/model/Episodes.d.ts +12 -0
  108. package/lib/typescript/src/VideoPlayer/model/Episodes.d.ts.map +1 -0
  109. package/lib/typescript/src/VideoPlayer/model/SettingModal.d.ts +12 -0
  110. package/lib/typescript/src/VideoPlayer/model/SettingModal.d.ts.map +1 -0
  111. package/lib/typescript/src/VideoPlayer/model/SpeedControls.d.ts +4 -0
  112. package/lib/typescript/src/VideoPlayer/model/SpeedControls.d.ts.map +1 -0
  113. package/lib/typescript/src/VideoPlayer/model/VideoPlayerSettings.d.ts +7 -0
  114. package/lib/typescript/src/VideoPlayer/model/VideoPlayerSettings.d.ts.map +1 -0
  115. package/lib/typescript/src/VideoPlayer/store/index.d.ts +3 -0
  116. package/lib/typescript/src/VideoPlayer/store/index.d.ts.map +1 -0
  117. package/lib/typescript/src/VideoPlayer/store/videoPlayer.type.d.ts +144 -0
  118. package/lib/typescript/src/VideoPlayer/store/videoPlayer.type.d.ts.map +1 -0
  119. package/lib/typescript/src/VideoPlayer/store/videoPlayerStore.d.ts +20 -0
  120. package/lib/typescript/src/VideoPlayer/store/videoPlayerStore.d.ts.map +1 -0
  121. package/lib/typescript/src/VideoPlayer/utils/Display.d.ts +8 -0
  122. package/lib/typescript/src/VideoPlayer/utils/Display.d.ts.map +1 -0
  123. package/lib/typescript/src/VideoPlayer/utils/PlatformSelector.d.ts +11 -0
  124. package/lib/typescript/src/VideoPlayer/utils/PlatformSelector.d.ts.map +1 -0
  125. package/lib/typescript/src/VideoPlayer/utils/hooks/index.d.ts +3 -0
  126. package/lib/typescript/src/VideoPlayer/utils/hooks/index.d.ts.map +1 -0
  127. package/lib/typescript/src/VideoPlayer/utils/hooks/useVideoPlayerBack.d.ts +6 -0
  128. package/lib/typescript/src/VideoPlayer/utils/hooks/useVideoPlayerBack.d.ts.map +1 -0
  129. package/lib/typescript/src/VideoPlayer/utils/hooks/useVideoResolutions.d.ts +12 -0
  130. package/lib/typescript/src/VideoPlayer/utils/hooks/useVideoResolutions.d.ts.map +1 -0
  131. package/lib/typescript/src/VideoPlayer/utils/index.d.ts +8 -0
  132. package/lib/typescript/src/VideoPlayer/utils/index.d.ts.map +1 -0
  133. package/lib/typescript/src/VideoPlayer/utils/lockOrientation.d.ts +3 -0
  134. package/lib/typescript/src/VideoPlayer/utils/lockOrientation.d.ts.map +1 -0
  135. package/lib/typescript/src/VideoPlayer/utils/playerEvents.d.ts +18 -0
  136. package/lib/typescript/src/VideoPlayer/utils/playerEvents.d.ts.map +1 -0
  137. package/lib/typescript/src/VideoPlayer/utils/timeFormatter.d.ts +9 -0
  138. package/lib/typescript/src/VideoPlayer/utils/timeFormatter.d.ts.map +1 -0
  139. package/lib/typescript/src/VideoPlayer/utils/useWatchReporter.d.ts +26 -0
  140. package/lib/typescript/src/VideoPlayer/utils/useWatchReporter.d.ts.map +1 -0
  141. package/lib/typescript/src/VideoPlayer/utils/videoControl.d.ts +17 -0
  142. package/lib/typescript/src/VideoPlayer/utils/videoControl.d.ts.map +1 -0
  143. package/lib/typescript/src/VideoPlayer/utils/videoRef.d.ts +3 -0
  144. package/lib/typescript/src/VideoPlayer/utils/videoRef.d.ts.map +1 -0
  145. package/lib/typescript/src/VideoPlayer/utils/videoSource.d.ts +10 -0
  146. package/lib/typescript/src/VideoPlayer/utils/videoSource.d.ts.map +1 -0
  147. package/lib/typescript/src/index.d.ts +2 -0
  148. package/lib/typescript/src/index.d.ts.map +1 -0
  149. package/package.json +191 -0
  150. package/src/VideoPlayer/MediaControls/BottomControls.tsx +185 -0
  151. package/src/VideoPlayer/MediaControls/MediaControls.tsx +29 -0
  152. package/src/VideoPlayer/MediaControls/MediaControlsProvider.tsx +99 -0
  153. package/src/VideoPlayer/MediaControls/MiddleControls.tsx +232 -0
  154. package/src/VideoPlayer/MediaControls/TopControls.tsx +92 -0
  155. package/src/VideoPlayer/Styles/fonts.ts +106 -0
  156. package/src/VideoPlayer/Styles/globalStyles.ts +74 -0
  157. package/src/VideoPlayer/VideoPlayer.tsx +217 -0
  158. package/src/VideoPlayer/components/ProgressBar.tsx +98 -0
  159. package/src/VideoPlayer/components/SkipAndNextControls.tsx +195 -0
  160. package/src/VideoPlayer/components/SubtitleView.tsx +53 -0
  161. package/src/VideoPlayer/context/VideoPlayerConfig.tsx +65 -0
  162. package/src/VideoPlayer/context/index.ts +5 -0
  163. package/src/VideoPlayer/index.ts +4 -0
  164. package/src/VideoPlayer/model/AudioAndSubtitles.tsx +302 -0
  165. package/src/VideoPlayer/model/Episodes.tsx +294 -0
  166. package/src/VideoPlayer/model/SettingModal.tsx +128 -0
  167. package/src/VideoPlayer/model/SpeedControls.tsx +134 -0
  168. package/src/VideoPlayer/model/VideoPlayerSettings.tsx +141 -0
  169. package/src/VideoPlayer/store/index.ts +2 -0
  170. package/src/VideoPlayer/store/videoPlayer.type.ts +192 -0
  171. package/src/VideoPlayer/store/videoPlayerStore.ts +101 -0
  172. package/src/VideoPlayer/utils/Display.ts +14 -0
  173. package/src/VideoPlayer/utils/PlatformSelector.ts +18 -0
  174. package/src/VideoPlayer/utils/hooks/index.ts +2 -0
  175. package/src/VideoPlayer/utils/hooks/useVideoPlayerBack.ts +66 -0
  176. package/src/VideoPlayer/utils/hooks/useVideoResolutions.ts +119 -0
  177. package/src/VideoPlayer/utils/index.ts +7 -0
  178. package/src/VideoPlayer/utils/lockOrientation.ts +34 -0
  179. package/src/VideoPlayer/utils/playerEvents.ts +97 -0
  180. package/src/VideoPlayer/utils/timeFormatter.ts +47 -0
  181. package/src/VideoPlayer/utils/useWatchReporter.ts +104 -0
  182. package/src/VideoPlayer/utils/videoControl.ts +192 -0
  183. package/src/VideoPlayer/utils/videoRef.ts +4 -0
  184. package/src/VideoPlayer/utils/videoSource.ts +23 -0
  185. package/src/index.tsx +1 -0
@@ -0,0 +1,104 @@
1
+ import { useCallback } from 'react';
2
+ import { useVideoPlayerStore, mmkvStorage } from '../store/videoPlayerStore';
3
+ import type { MediaTrack } from '../store/videoPlayer.type';
4
+
5
+ export type WatchEventType =
6
+ | 'VIEW_COUNT'
7
+ | 'COMPLETED'
8
+ | 'PROGRESS'
9
+ | 'EPISODE_CHANGE'
10
+ | 'VIDEO_CLOSE';
11
+
12
+ export interface WatchProgressDetails {
13
+ contentId: string | null;
14
+ episodeId?: string | null;
15
+ contentType?: MediaTrack['type'];
16
+ currentTime: number;
17
+ totalWatchTime: number;
18
+ duration: number;
19
+ isVideoCompleted: boolean;
20
+ activeTrack: MediaTrack | null;
21
+ }
22
+
23
+ export interface ExtendedWatchProgress extends WatchProgressDetails {
24
+ event?: WatchEventType;
25
+ }
26
+
27
+ export const countWatchTime = (
28
+ forceFlush = false
29
+ ): {
30
+ totalWatchTime: number;
31
+ completed: boolean;
32
+ currentTime: number;
33
+ } => {
34
+ const { duration, setStartWatchTime, startWatchTime } =
35
+ useVideoPlayerStore.getState();
36
+
37
+ const currentTimeFromStorage = Number(
38
+ mmkvStorage.getItem('currentTime') || 0
39
+ );
40
+ const prevWatchTime = Number(mmkvStorage.getItem('current_watch_time') || 0);
41
+
42
+ const completed =
43
+ duration > 0 && Math.round(currentTimeFromStorage / duration) >= 0.95;
44
+
45
+ let totalTimeWatched = prevWatchTime;
46
+
47
+ if (startWatchTime) {
48
+ const elapsedTime = (Date.now() - startWatchTime) / 1000;
49
+ totalTimeWatched = prevWatchTime + elapsedTime;
50
+ mmkvStorage.setItem('current_watch_time', totalTimeWatched.toString());
51
+
52
+ setStartWatchTime(null);
53
+ }
54
+
55
+ if (forceFlush) {
56
+ const latest = Number(mmkvStorage.getItem('current_watch_time') || '0');
57
+ return {
58
+ totalWatchTime: latest,
59
+ completed,
60
+ currentTime: currentTimeFromStorage,
61
+ };
62
+ }
63
+
64
+ return {
65
+ totalWatchTime: totalTimeWatched,
66
+ completed,
67
+ currentTime: currentTimeFromStorage,
68
+ };
69
+ };
70
+
71
+ export const useWatchReporter = ({
72
+ onWatchProgress,
73
+ }: {
74
+ onWatchProgress?: (progress: ExtendedWatchProgress) => void;
75
+ }) => {
76
+ const reportProgress = useCallback(
77
+ (event: WatchEventType = 'PROGRESS', forcedCurrentTime?: number) => {
78
+ const { activeTrack, duration } = useVideoPlayerStore.getState();
79
+ if (!activeTrack) return;
80
+
81
+ const { totalWatchTime, completed, currentTime } = countWatchTime(
82
+ event === 'VIDEO_CLOSE' ||
83
+ event === 'EPISODE_CHANGE' ||
84
+ event === 'COMPLETED'
85
+ );
86
+
87
+ const progress: WatchProgressDetails = {
88
+ contentId: activeTrack?.contentId || null,
89
+ episodeId: activeTrack?.episodeId || null,
90
+ contentType: activeTrack?.type,
91
+ currentTime: forcedCurrentTime ?? currentTime,
92
+ totalWatchTime,
93
+ duration: duration || 0,
94
+ isVideoCompleted: completed,
95
+ activeTrack,
96
+ };
97
+
98
+ onWatchProgress?.({ ...progress, event });
99
+ },
100
+ [onWatchProgress]
101
+ );
102
+
103
+ return { reportProgress };
104
+ };
@@ -0,0 +1,192 @@
1
+ import { mmkvStorage, useVideoPlayerStore } from '../store/videoPlayerStore';
2
+ import type { MediaEpisode } from '../store/videoPlayer.type';
3
+
4
+ export const handlePause = () => {
5
+ const { setIsPaused, startWatchTime, setStartWatchTime } =
6
+ useVideoPlayerStore.getState();
7
+
8
+ setIsPaused(true);
9
+
10
+ if (!startWatchTime) return;
11
+
12
+ const elapsedTime = (Date.now() - startWatchTime) / 1000;
13
+ const storedTime = Number(mmkvStorage.getItem('current_watch_time') ?? 0);
14
+
15
+ mmkvStorage.setItem(
16
+ 'current_watch_time',
17
+ (storedTime + elapsedTime).toString()
18
+ );
19
+
20
+ setStartWatchTime(null);
21
+ };
22
+
23
+ interface HandleNextOptions {
24
+ onPressEpisode: ({ episode }: { episode: MediaEpisode }) => Promise<boolean>;
25
+ autoNext?: boolean;
26
+ }
27
+ export const handleNext = async ({
28
+ onPressEpisode,
29
+ autoNext,
30
+ }: HandleNextOptions): Promise<number | null> => {
31
+ const {
32
+ playList: playlist,
33
+ currentTrackIndex,
34
+ setCurrentTrackIndex,
35
+ setActiveTrack,
36
+ setCurrentTime,
37
+ setIsPaused,
38
+ setActiveSubtitle,
39
+ setPlayBackRate,
40
+ contentSeasons,
41
+ setActiveSeason,
42
+ setControlsVisible,
43
+ setSelectedSubtitleTrack,
44
+ setSelectedVideoTrack,
45
+ setMaxBitRate,
46
+ setDuration,
47
+ } = useVideoPlayerStore.getState();
48
+
49
+ if (!playlist?.length) return null;
50
+
51
+ // 👉 Check autoNext
52
+ if (!autoNext) {
53
+ // Just pause at the end, don’t go next
54
+ setIsPaused(true);
55
+ setControlsVisible(true);
56
+ return currentTrackIndex;
57
+ }
58
+
59
+ let nextIndex = currentTrackIndex + 1;
60
+
61
+ // 👉 No next episode? stop here
62
+ if (nextIndex >= playlist.length) {
63
+ setIsPaused(true);
64
+ setControlsVisible(true);
65
+ return currentTrackIndex;
66
+ }
67
+
68
+ const nextTrack = playlist[nextIndex];
69
+ if (!nextTrack) return currentTrackIndex;
70
+
71
+ // 👉 Trigger hook
72
+ let isSuccess = true;
73
+ if (onPressEpisode) {
74
+ isSuccess = await onPressEpisode({
75
+ episode: {
76
+ id: nextTrack.episodeId || '',
77
+ title: nextTrack.episodeName ?? '',
78
+ contentId: nextTrack.contentId || '',
79
+ sourceLink: nextTrack.sourceLink,
80
+ thumbnail: nextTrack.thumbnail,
81
+ nextEpisodeAt: nextTrack.nextEpisodeAt,
82
+ publishDate: nextTrack.publishDate,
83
+ skipIntro: nextTrack.skipIntro,
84
+ description: nextTrack?.description || '',
85
+ duration: nextTrack?.duration || 0,
86
+ sourceType: nextTrack?.sourceType || 'HLS',
87
+ episodeNumber: nextTrack?.episodeNumber || 0,
88
+ subtitles: nextTrack?.subtitles ?? [],
89
+ },
90
+ });
91
+ }
92
+
93
+ if (!isSuccess) {
94
+ setIsPaused(true);
95
+ setControlsVisible(true);
96
+ return currentTrackIndex;
97
+ }
98
+
99
+ // 👉 Play next episode
100
+ setIsPaused(false);
101
+ setCurrentTime(0);
102
+ setDuration(0);
103
+ setCurrentTrackIndex(nextIndex);
104
+ setActiveTrack(nextTrack);
105
+ setActiveSubtitle(null);
106
+ setSelectedVideoTrack(null);
107
+ setMaxBitRate(null);
108
+ setPlayBackRate(1, 'Normal');
109
+ setSelectedSubtitleTrack(null);
110
+
111
+ if (nextTrack.seasonId) {
112
+ const activeSeason = contentSeasons?.find(
113
+ (s) => s.id === nextTrack.seasonId
114
+ );
115
+ if (activeSeason) {
116
+ setActiveSeason(activeSeason);
117
+ }
118
+ }
119
+
120
+ return nextIndex;
121
+ };
122
+
123
+ export const viewCount = (): boolean => {
124
+ const { isViewCounted, setIsViewCounted, activeTrack } =
125
+ useVideoPlayerStore.getState();
126
+ if (!isViewCounted) {
127
+ if (activeTrack?.id) {
128
+ setIsViewCounted(true);
129
+ return true;
130
+ }
131
+ } else {
132
+ return false;
133
+ }
134
+ return false;
135
+ };
136
+
137
+ export const countWatchTime = (): {
138
+ totalWatchTime: number;
139
+ completed: boolean;
140
+ currentTime: number;
141
+ } => {
142
+ const { activeTrack, duration, setStartWatchTime, startWatchTime } =
143
+ useVideoPlayerStore.getState();
144
+
145
+ const currentTimeFromStorage = Number(
146
+ mmkvStorage.getItem('currentTime') || 0
147
+ );
148
+ const prevWatchTime = Number(mmkvStorage.getItem('current_watch_time') || 0);
149
+
150
+ // ✅ Completed check (>= 95%)
151
+ const completed =
152
+ duration > 0 && Math.round(currentTimeFromStorage / duration) >= 0.95;
153
+
154
+ // ⏱ If no start time (pause/close before resuming)
155
+ if (!startWatchTime) {
156
+ return {
157
+ totalWatchTime: prevWatchTime,
158
+ completed,
159
+ currentTime: currentTimeFromStorage,
160
+ };
161
+ }
162
+
163
+ const elapsedTime = (Date.now() - startWatchTime) / 1000;
164
+
165
+ const totalTimeWatched = prevWatchTime + elapsedTime;
166
+ mmkvStorage.setItem('current_watch_time', totalTimeWatched.toString());
167
+
168
+ setStartWatchTime(null);
169
+
170
+ if (totalTimeWatched < 30) {
171
+ return {
172
+ totalWatchTime: 0,
173
+ completed: false,
174
+ currentTime: currentTimeFromStorage,
175
+ };
176
+ }
177
+
178
+ if (activeTrack?.id) {
179
+ return {
180
+ totalWatchTime: totalTimeWatched,
181
+ completed,
182
+ currentTime: currentTimeFromStorage,
183
+ };
184
+ }
185
+
186
+ mmkvStorage.setItem('current_watch_time', '0');
187
+ return {
188
+ totalWatchTime: 0,
189
+ completed: false,
190
+ currentTime: 0,
191
+ };
192
+ };
@@ -0,0 +1,4 @@
1
+ import { createRef } from 'react';
2
+ import type { VideoRef } from 'react-native-video';
3
+
4
+ export const videoRef = createRef<VideoRef>();
@@ -0,0 +1,23 @@
1
+ import type { MediaTrack } from '../store/videoPlayer.type';
2
+ import type { ReactVideoSource } from 'react-native-video';
3
+
4
+ interface UrlHandlerProps {
5
+ playList: MediaTrack[];
6
+ currentTrackIndex: number;
7
+ }
8
+
9
+ export const getVideoSource = ({
10
+ playList,
11
+ currentTrackIndex,
12
+ }: UrlHandlerProps): ReactVideoSource => {
13
+ const track = playList?.[currentTrackIndex];
14
+ if (!track) return { uri: '' };
15
+
16
+ const uri = track.isTrailer ? track.trailerSource : track.sourceLink;
17
+ return { uri: encodeURI(uri?.trim() || '') ?? '' };
18
+ };
19
+
20
+ export const getEpisodeIndex = (
21
+ playList: MediaTrack[],
22
+ episodeId: string
23
+ ): number => playList.findIndex((item) => item.episodeId === episodeId);
package/src/index.tsx ADDED
@@ -0,0 +1 @@
1
+ export * from './VideoPlayer';