@devix-technologies/react-gjirafa-vp-player 1.0.31-beta.19 → 1.0.31-beta.20
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.
- package/README.md +110 -55
- package/dist/index.d.ts +21 -7
- package/dist/react-gjirafa-vp-player.es.js +840 -840
- package/dist/react-gjirafa-vp-player.umd.js +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,20 +53,16 @@ import { VPPlayer } from "@devix-technologies/react-gjirafa-vp-player";
|
|
|
53
53
|
<VPPlayer
|
|
54
54
|
scriptId="ptkzurnx"
|
|
55
55
|
videoId="vjsobqhe"
|
|
56
|
-
onPlay={() => analytics.track(
|
|
57
|
-
onQuartile25={() => analytics.track(
|
|
58
|
-
onProgress20s={() => analytics.track(
|
|
56
|
+
onPlay={() => analytics.track("play")}
|
|
57
|
+
onQuartile25={() => analytics.track("25% watched")}
|
|
58
|
+
onProgress20s={() => analytics.track("20s milestone")}
|
|
59
59
|
/>
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
### Vertical Player
|
|
63
63
|
|
|
64
64
|
```tsx
|
|
65
|
-
<VPPlayer
|
|
66
|
-
scriptId="rbqcdwzlg"
|
|
67
|
-
videoId="vjsobqhe"
|
|
68
|
-
isVertical={true}
|
|
69
|
-
/>
|
|
65
|
+
<VPPlayer scriptId="rbqcdwzlg" videoId="vjsobqhe" isVertical={true} />
|
|
70
66
|
```
|
|
71
67
|
|
|
72
68
|
### Reels Mode (TikTok-style)
|
|
@@ -109,8 +105,8 @@ For vertical player with your own videos array (not using GTech admin playlists)
|
|
|
109
105
|
],
|
|
110
106
|
startIndex: 0,
|
|
111
107
|
}}
|
|
112
|
-
onNext={() => console.log(
|
|
113
|
-
onVideoStarted={(data) => console.log(
|
|
108
|
+
onNext={() => console.log("Next video")}
|
|
109
|
+
onVideoStarted={(data) => console.log("Playing:", data.title)}
|
|
114
110
|
/>
|
|
115
111
|
```
|
|
116
112
|
|
|
@@ -132,59 +128,111 @@ The player fills its container (100% width/height). Control sizing with a wrappe
|
|
|
132
128
|
</div>
|
|
133
129
|
```
|
|
134
130
|
|
|
131
|
+
## Video Locking
|
|
132
|
+
|
|
133
|
+
Video locking lets you lock a portion of each video (e.g. require watching N seconds or N% before skipping). The SDK supports this via a `shouldLockVideo` callback and `removeVideoLock()`. The recommended approach is to set the callback inside `onVideoSwitch` so locking applies after each video switch.
|
|
134
|
+
|
|
135
|
+
### Ref methods
|
|
136
|
+
|
|
137
|
+
- **`shouldLockVideo(callback)`** – Set the callback that returns lock config. Pass a function that returns `{ isEnabled, type, value }`, or `null` to clear. Matches SDK naming.
|
|
138
|
+
- **`removeVideoLock()`** – Clear any active lock.
|
|
139
|
+
|
|
140
|
+
### Lock config shape
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
{ isEnabled: boolean; type: "seconds" | "percentage"; value: number }
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Recommended pattern: lock on video switch
|
|
147
|
+
|
|
148
|
+
Use `onVideoSwitch` to set or clear `shouldLockVideo` after each switch. In the callback you can decide whether to lock (e.g. from app state) and for how long.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
const playerRef = useRef<VPPlayerRef>(null);
|
|
152
|
+
|
|
153
|
+
<VPPlayer
|
|
154
|
+
ref={playerRef}
|
|
155
|
+
scriptId="ptkzurnx"
|
|
156
|
+
videoId="vjsobqhe"
|
|
157
|
+
config={{ /* ... */ }}
|
|
158
|
+
onVideoSwitch={() => {
|
|
159
|
+
const shouldLock = true; // your logic, e.g. from state
|
|
160
|
+
if (shouldLock) {
|
|
161
|
+
playerRef.current?.shouldLockVideo(() => ({
|
|
162
|
+
isEnabled: true,
|
|
163
|
+
type: "seconds",
|
|
164
|
+
value: 20,
|
|
165
|
+
}));
|
|
166
|
+
} else {
|
|
167
|
+
playerRef.current?.removeVideoLock();
|
|
168
|
+
playerRef.current?.shouldLockVideo(() => ({
|
|
169
|
+
isEnabled: false,
|
|
170
|
+
type: "seconds",
|
|
171
|
+
value: 0,
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
To only lock for a period after each switch, enable locking in `onVideoSwitch` with the desired `value` (e.g. 20 seconds). To disable locking for the next video, call `removeVideoLock()` and set `shouldLockVideo` to return `isEnabled: false`.
|
|
179
|
+
|
|
135
180
|
## Props Reference
|
|
136
181
|
|
|
137
182
|
### Identification (one required)
|
|
138
183
|
|
|
139
|
-
| Prop
|
|
140
|
-
|
|
141
|
-
| `scriptId`
|
|
142
|
-
| `videoId`
|
|
143
|
-
| `scriptUrl` | `string` | Full managed script URL
|
|
184
|
+
| Prop | Type | Description |
|
|
185
|
+
| ----------- | -------- | ---------------------------------- |
|
|
186
|
+
| `scriptId` | `string` | GTech script ID (e.g., "ptkzurnx") |
|
|
187
|
+
| `videoId` | `string` | GTech video ID (e.g., "vjsobqhe") |
|
|
188
|
+
| `scriptUrl` | `string` | Full managed script URL |
|
|
144
189
|
|
|
145
190
|
### Optional
|
|
146
191
|
|
|
147
|
-
| Prop
|
|
148
|
-
|
|
149
|
-
| `projectId`
|
|
150
|
-
| `playlist`
|
|
151
|
-
| `playerId`
|
|
152
|
-
| `isVertical`
|
|
153
|
-
| `isReels`
|
|
154
|
-
| `thumbnailUrl`
|
|
155
|
-
| `className`
|
|
156
|
-
| `hiddenClasses` | `string[]`
|
|
192
|
+
| Prop | Type | Description |
|
|
193
|
+
| --------------- | ---------------------- | ---------------------------------------------------- |
|
|
194
|
+
| `projectId` | `string` | GTech project ID (required for manual playlist) |
|
|
195
|
+
| `playlist` | `ManualPlaylistConfig` | Custom videos array for manual playlist mode |
|
|
196
|
+
| `playerId` | `string` | Custom container ID (auto-generated if not provided) |
|
|
197
|
+
| `isVertical` | `boolean` | Force vertical player mode |
|
|
198
|
+
| `isReels` | `boolean` | Enable Reels overlay mode |
|
|
199
|
+
| `thumbnailUrl` | `string` | Thumbnail for Reels mode |
|
|
200
|
+
| `className` | `string` | CSS class for container |
|
|
201
|
+
| `hiddenClasses` | `string[]` | SDK element classes to hide |
|
|
157
202
|
|
|
158
203
|
### Event Callbacks
|
|
159
204
|
|
|
160
|
-
| Prop
|
|
161
|
-
|
|
162
|
-
| `onReady`
|
|
163
|
-
| `onPlay`
|
|
164
|
-
| `onPause`
|
|
165
|
-
| `onResume`
|
|
166
|
-
| `onComplete`
|
|
167
|
-
| `onError`
|
|
168
|
-
| `onVideoStarted` |
|
|
169
|
-
| `onTimeUpdate`
|
|
170
|
-
| `onQuartile25`
|
|
171
|
-
| `onQuartile50`
|
|
172
|
-
| `onQuartile75`
|
|
173
|
-
| `onNext`
|
|
174
|
-
| `onPrevious`
|
|
175
|
-
| `onProgress10s`
|
|
176
|
-
| `onProgress20s`
|
|
177
|
-
| `
|
|
205
|
+
| Prop | Horizontal | Vertical | Description |
|
|
206
|
+
| ---------------- | :--------: | :------: | ----------------------------------------------------- |
|
|
207
|
+
| `onReady` | ✓ | ✓ | Player initialized |
|
|
208
|
+
| `onPlay` | ✓ | ✓ | Playback started (initial play) |
|
|
209
|
+
| `onPause` | ✓ | ✓ | Playback paused (user-initiated) |
|
|
210
|
+
| `onResume` | ✗ | ✓ | Playback resumed after pause (vertical only) |
|
|
211
|
+
| `onComplete` | ✓ | ✗ | Video completed (horizontal only) |
|
|
212
|
+
| `onError` | ✓ | ✓ | Error occurred |
|
|
213
|
+
| `onVideoStarted` | ✓ | ✓ | Video metadata available (returns `CurrentVideoData`) |
|
|
214
|
+
| `onTimeUpdate` | ✓ | ✓ | Continuous time updates (returns seconds) |
|
|
215
|
+
| `onQuartile25` | ✓ | ✓ | 25% watched |
|
|
216
|
+
| `onQuartile50` | ✓ | ✓ | 50% watched |
|
|
217
|
+
| `onQuartile75` | ✓ | ✓ | 75% watched |
|
|
218
|
+
| `onNext` | ✓ | ✓ | Next video in playlist |
|
|
219
|
+
| `onPrevious` | ✗ | ✓ | Previous video (vertical only) |
|
|
220
|
+
| `onProgress10s` | ✓ | ✓ | Every ~10 seconds (returns seconds) |
|
|
221
|
+
| `onProgress20s` | ✓ | ✓ | 20 second milestone (returns seconds) |
|
|
222
|
+
| `onVideoSwitch` | ✓ | ✓ | SDK `vp-video-switch` (use for video locking) |
|
|
223
|
+
| `onClose` | - | - | Reels overlay closed |
|
|
178
224
|
|
|
179
225
|
#### Event Implementation Notes
|
|
180
226
|
|
|
181
227
|
**Horizontal Player** uses standard VP Player SDK events via `.on()` listener:
|
|
228
|
+
|
|
182
229
|
- `ready`, `play`, `pause`, `complete`, `video-started`, `video-state`, `time`, `playlistItem`, `error`
|
|
183
230
|
- Quartiles: `analytics-25%-completed`, `analytics-50%-completed`, `analytics-75%-completed`
|
|
184
231
|
|
|
185
232
|
**Vertical Player** uses a combination of `.on()` listener and the global `vp-event` handler:
|
|
186
233
|
|
|
187
234
|
Standard events via `.on()`:
|
|
235
|
+
|
|
188
236
|
- `vp-first-frame`, `vp-video-started`, `vp-video-state`, `vp-time`, `vp-video-switch`, `error`
|
|
189
237
|
- Quartiles: `analytics-25%-completed`, `analytics-50%-completed`, `analytics-75%-completed`
|
|
190
238
|
|
|
@@ -192,15 +240,16 @@ Standard events via `.on()`:
|
|
|
192
240
|
|
|
193
241
|
The following events are intercepted from the global `vp-event` emission because the VP Vertical Player SDK doesn't expose them via the standard `.on()` listener:
|
|
194
242
|
|
|
195
|
-
| Event
|
|
196
|
-
|
|
197
|
-
| `onPlay`
|
|
198
|
-
| `onPause`
|
|
199
|
-
| `onResume` | `vp-state-playing` | Fires when resuming after **user-initiated** pause
|
|
243
|
+
| Event | SDK Event | Special Logic |
|
|
244
|
+
| ---------- | ------------------ | -------------------------------------------------------------- |
|
|
245
|
+
| `onPlay` | `vp-state-playing` | Fires on initial play (when not resuming from pause) |
|
|
246
|
+
| `onPause` | `vp-state-paused` | Only fires on **user-initiated** pause (not on video loop/end) |
|
|
247
|
+
| `onResume` | `vp-state-playing` | Fires when resuming after **user-initiated** pause |
|
|
200
248
|
|
|
201
249
|
**User Interaction Tracking:**
|
|
202
250
|
|
|
203
251
|
To distinguish between user actions and automatic playback events (like video loops), we track the `vp-user-interaction` event:
|
|
252
|
+
|
|
204
253
|
- When `vp-user-interaction` fires before `vp-state-paused` → user clicked pause → `onPause` fires
|
|
205
254
|
- When `vp-user-interaction` fires before `vp-state-playing` (after pause) → user clicked play → `onResume` fires
|
|
206
255
|
- When `vp-state-paused` fires without prior user interaction → video ended/looped → no `onPause` (silent)
|
|
@@ -209,6 +258,7 @@ To distinguish between user actions and automatic playback events (like video lo
|
|
|
209
258
|
This ensures analytics events like `player_pause` and `player_resume` only fire for actual user actions, not automatic video looping.
|
|
210
259
|
|
|
211
260
|
**Key Differences:**
|
|
261
|
+
|
|
212
262
|
- `onComplete` - Only available on horizontal player (vertical auto-advances to next video)
|
|
213
263
|
- `onResume` - Only available on vertical player (horizontal has no pause/resume distinction)
|
|
214
264
|
- `onPrevious` - Only available on vertical player (horizontal has no direction detection)
|
|
@@ -222,14 +272,14 @@ import {
|
|
|
222
272
|
getFullyManagedPlayerScriptUrl,
|
|
223
273
|
getVerticalPlayerScriptUrl,
|
|
224
274
|
appendDivIdToUrl,
|
|
225
|
-
} from
|
|
275
|
+
} from "@devix-technologies/react-gjirafa-vp-player";
|
|
226
276
|
|
|
227
277
|
// Build managed script URL
|
|
228
|
-
const url = getFullyManagedPlayerScriptUrl(
|
|
278
|
+
const url = getFullyManagedPlayerScriptUrl("ptkzurnx", "vjsobqhe");
|
|
229
279
|
// => "https://host.vpplayer.tech/player/ptkzurnx/vjsobqhe.js"
|
|
230
280
|
|
|
231
281
|
// Build vertical player URL
|
|
232
|
-
const verticalUrl = getVerticalPlayerScriptUrl(
|
|
282
|
+
const verticalUrl = getVerticalPlayerScriptUrl("rbqcdwzlg");
|
|
233
283
|
// => "https://host.vpplayer.tech/vertical-player/rbqcdwzlg.js"
|
|
234
284
|
```
|
|
235
285
|
|
|
@@ -238,13 +288,16 @@ const verticalUrl = getVerticalPlayerScriptUrl('rbqcdwzlg');
|
|
|
238
288
|
For programmatic control, use the hook directly:
|
|
239
289
|
|
|
240
290
|
```tsx
|
|
241
|
-
import {
|
|
291
|
+
import {
|
|
292
|
+
useVPPlayerLogic,
|
|
293
|
+
PlayerContainer,
|
|
294
|
+
} from "@devix-technologies/react-gjirafa-vp-player";
|
|
242
295
|
|
|
243
296
|
function CustomPlayer() {
|
|
244
297
|
const { playerRef, playerInstanceRef, isScriptLoaded, generatedPlayerId } =
|
|
245
298
|
useVPPlayerLogic({
|
|
246
|
-
scriptId:
|
|
247
|
-
videoId:
|
|
299
|
+
scriptId: "ptkzurnx",
|
|
300
|
+
videoId: "vjsobqhe",
|
|
248
301
|
});
|
|
249
302
|
|
|
250
303
|
return (
|
|
@@ -257,7 +310,9 @@ function CustomPlayer() {
|
|
|
257
310
|
$hiddenClasses={[]}
|
|
258
311
|
/>
|
|
259
312
|
<button onClick={() => playerInstanceRef.current?.play?.()}>Play</button>
|
|
260
|
-
<button onClick={() => playerInstanceRef.current?.pause?.()}>
|
|
313
|
+
<button onClick={() => playerInstanceRef.current?.pause?.()}>
|
|
314
|
+
Pause
|
|
315
|
+
</button>
|
|
261
316
|
</div>
|
|
262
317
|
);
|
|
263
318
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { RefAttributes } from 'react';
|
|
|
6
6
|
import { RefObject } from 'react';
|
|
7
7
|
import { StyledComponent } from '@emotion/styled';
|
|
8
8
|
import { Theme } from '@emotion/react';
|
|
9
|
-
import { VideoLockingConfig as VideoLockingConfig_2 } from '../../../../../../../src/interfaces';
|
|
10
9
|
import { VPPlayerInstance as VPPlayerInstance_2 } from '../../../../../../../src/interfaces';
|
|
11
10
|
import { VPPlayerProps as VPPlayerProps_2 } from '../../../../../../../src/interfaces';
|
|
12
11
|
import { VPPlayerRef as VPPlayerRef_2 } from '../../../../../../../src/interfaces';
|
|
@@ -269,6 +268,7 @@ export declare interface EventCallbackRefs {
|
|
|
269
268
|
onProgress10s?: (seconds: number) => void;
|
|
270
269
|
onProgress20s?: (seconds: number) => void;
|
|
271
270
|
onPlaylistItem?: (data: CurrentVideoData_2) => void;
|
|
271
|
+
onVideoSwitch?: (data: VideoSwitchData) => void;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
/**
|
|
@@ -728,15 +728,13 @@ export declare interface TimesliderSkin {
|
|
|
728
728
|
* 1. **Auto-init mode** (default): Load managed script that auto-initializes with GTech admin config
|
|
729
729
|
* 2. **Config override mode**: Fetch config, merge user overrides, and call setup()
|
|
730
730
|
*/
|
|
731
|
-
export declare const useVPPlayerLogic: ({ scriptId, videoId, scriptUrl, projectId, config, playerId, isVertical, isReels, onReady, onPlay, onPause, onResume, onComplete, onError, onVideoStarted, onTimeUpdate, onQuartile25, onQuartile50, onQuartile75, onNext, onPrevious, onProgress10s, onProgress20s, onPlaylistItem, }: VPPlayerProps_2) => {
|
|
731
|
+
export declare const useVPPlayerLogic: ({ scriptId, videoId, scriptUrl, projectId, config, playerId, isVertical, isReels, onReady, onPlay, onPause, onResume, onComplete, onError, onVideoStarted, onTimeUpdate, onQuartile25, onQuartile50, onQuartile75, onNext, onPrevious, onProgress10s, onProgress20s, onPlaylistItem, onVideoSwitch, }: VPPlayerProps_2) => {
|
|
732
732
|
playerRef: RefObject<HTMLDivElement | null>;
|
|
733
733
|
playerInstanceRef: RefObject<VPPlayerInstance_2 | null>;
|
|
734
734
|
isScriptLoaded: boolean;
|
|
735
735
|
isLoading: boolean;
|
|
736
736
|
error: string | null;
|
|
737
737
|
generatedPlayerId: string;
|
|
738
|
-
isInPlaylistTransitionRef: RefObject<boolean>;
|
|
739
|
-
pendingVideoLockingRef: RefObject<VideoLockingConfig_2 | null>;
|
|
740
738
|
};
|
|
741
739
|
|
|
742
740
|
/**
|
|
@@ -828,6 +826,11 @@ export declare interface VideoLockingConfig {
|
|
|
828
826
|
value: number;
|
|
829
827
|
}
|
|
830
828
|
|
|
829
|
+
export declare interface VideoSwitchData {
|
|
830
|
+
direction?: "next" | "prev";
|
|
831
|
+
currentTime?: number;
|
|
832
|
+
}
|
|
833
|
+
|
|
831
834
|
/**
|
|
832
835
|
* Volume skin configuration
|
|
833
836
|
*/
|
|
@@ -985,6 +988,8 @@ export declare interface VPPlayerInstance {
|
|
|
985
988
|
setLevelToAuto?: () => void;
|
|
986
989
|
setCuePoint?: (cue: number, callback: () => void) => void;
|
|
987
990
|
setVideoLocking?: (config: VideoLockingConfig) => void;
|
|
991
|
+
removeVideoLock?: () => void;
|
|
992
|
+
shouldLockVideo?: () => VideoLockingConfig;
|
|
988
993
|
on?: (event: string, callback: (data?: unknown) => void) => void;
|
|
989
994
|
off?: (event: string, callback?: (data?: unknown) => void) => void;
|
|
990
995
|
videoIndex?: number;
|
|
@@ -1168,6 +1173,11 @@ export declare interface VPPlayerProps {
|
|
|
1168
1173
|
* @param data - Video metadata for the new playlist item
|
|
1169
1174
|
*/
|
|
1170
1175
|
onPlaylistItem?: (data: CurrentVideoData_2) => void;
|
|
1176
|
+
/**
|
|
1177
|
+
* Called when the SDK emits vp-video-switch (e.g. user switched to next/prev video).
|
|
1178
|
+
* Use with ref.shouldLockVideo() for video locking; see README Video Locking section.
|
|
1179
|
+
*/
|
|
1180
|
+
onVideoSwitch?: (data: VideoSwitchData) => void;
|
|
1171
1181
|
}
|
|
1172
1182
|
|
|
1173
1183
|
/**
|
|
@@ -1207,10 +1217,14 @@ export declare interface VPPlayerRef {
|
|
|
1207
1217
|
isPaused: () => boolean;
|
|
1208
1218
|
isFullscreen: () => boolean;
|
|
1209
1219
|
/**
|
|
1210
|
-
* Set
|
|
1211
|
-
*
|
|
1220
|
+
* Set the shouldLockVideo callback on the player (SDK naming).
|
|
1221
|
+
* Pass a function that returns lock config, or null to clear.
|
|
1222
|
+
*/
|
|
1223
|
+
shouldLockVideo: (callback: (() => VideoLockingConfig) | null) => void;
|
|
1224
|
+
/**
|
|
1225
|
+
* Remove/unlock the video.
|
|
1212
1226
|
*/
|
|
1213
|
-
|
|
1227
|
+
removeVideoLock: () => void;
|
|
1214
1228
|
}
|
|
1215
1229
|
|
|
1216
1230
|
/**
|