@devix-technologies/react-gjirafa-vp-player 1.0.31-beta.0 → 1.0.31-beta.11

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 CHANGED
@@ -1,25 +1,20 @@
1
1
  # React Gjirafa VP Player
2
2
 
3
- A strict, lightweight React wrapper around the [Gjirafa VP Player SDK](https://vp.gjirafa.tech/documentation/docs/web-player/).
3
+ A lightweight React wrapper for the [Gjirafa VP Player SDK](https://vp.gjirafa.tech/documentation/docs/web-player/).
4
4
 
5
- This package provides a clean interface for integrating the Gjirafa Player into React applications, adhering strictly to the official "Managed Script" implementation guide while adding necessary custom features for specific business needs (Reels mode, Analytics).
5
+ ## v2.0.0 - Simplified Architecture
6
6
 
7
- ## Features
7
+ Version 2.0.0 is a major simplification. The wrapper is now a **thin bridge** to the GTech JS player:
8
8
 
9
- - **Strict SDK Wrapping:** Uses the official `window.vpPlayer` / `window.vpVerticalPlayer` API.
10
- - **Managed Script Loading:** Handles async script loading with caching and error handling.
11
- - **Reels Mode:** Built-in "Overlay" UI for vertical short-form videos.
12
- - **Native Events:** Bridges official SDK events (play, pause, quartiles) to React callbacks.
13
- - **Custom Analytics:** Includes a custom "20 seconds watched" event (calculated from playback time).
14
- - **Playlist Support:** Handles both Web Player and Vertical Player playlist configuration differences automatically.
9
+ - **No configuration interference** - GTech admin panel is the source of truth
10
+ - **Auto-initialization** - Managed scripts auto-init with embedded config
11
+ - **Event forwarding** - React callbacks for SDK events
15
12
 
16
13
  ## Installation
17
14
 
18
15
  ```bash
19
16
  npm install @devix-technologies/react-gjirafa-vp-player
20
17
  # or
21
- yarn add @devix-technologies/react-gjirafa-vp-player
22
- # or
23
18
  pnpm add @devix-technologies/react-gjirafa-vp-player
24
19
  ```
25
20
 
@@ -28,124 +23,247 @@ pnpm add @devix-technologies/react-gjirafa-vp-player
28
23
  ```tsx
29
24
  import { VPPlayer } from "@devix-technologies/react-gjirafa-vp-player";
30
25
 
31
- const App = () => {
32
- return (
33
- <div style={{ maxWidth: "800px", margin: "0 auto" }}>
34
- <VPPlayer
35
- playerId="unique-player-id"
36
- videoUrl="https://example.com/video.mp4"
37
- version="latest"
38
- onPlayerPlay={() => console.log('Playing')}
39
- />
40
- </div>
41
- );
42
- };
26
+ // Using scriptId + videoId (recommended)
27
+ <VPPlayer
28
+ scriptId="ptkzurnx"
29
+ videoId="vjsobqhe"
30
+ onPlay={() => console.log('Playing!')}
31
+ />
32
+
33
+ // OR using full script URL
34
+ <VPPlayer
35
+ scriptUrl="https://host.vpplayer.tech/player/ptkzurnx/vjsobqhe.js"
36
+ onPlay={() => console.log('Playing!')}
37
+ />
43
38
  ```
44
39
 
45
- ## Usage Patterns
40
+ ## How It Works
41
+
42
+ 1. Wrapper generates a unique `divId` for the container
43
+ 2. Script URL: `https://host.vpplayer.tech/player/{scriptId}/{videoId}.js?divId={ourDivId}`
44
+ 3. Script loads and **auto-initializes** with GTech admin config
45
+ 4. Wrapper does **NOT** call `.setup()` - script already did it
46
+ 5. Wrapper attaches event listeners for React callbacks
47
+
48
+ ## Usage Examples
49
+
50
+ ### Web Player
51
+
52
+ ```tsx
53
+ <VPPlayer
54
+ scriptId="ptkzurnx"
55
+ videoId="vjsobqhe"
56
+ onPlay={() => analytics.track('play')}
57
+ onQuartile25={() => analytics.track('25% watched')}
58
+ onProgress20s={() => analytics.track('20s milestone')}
59
+ />
60
+ ```
46
61
 
47
- ### 1. Standard Video Player (Horizontal)
48
- Use for standard 16:9 content.
62
+ ### Vertical Player
49
63
 
50
64
  ```tsx
51
65
  <VPPlayer
52
- playerId="main-player"
53
- videoId="vjsnkiko" // API Video ID
54
- projectId="agmipoaa" // Project ID
55
- scriptUrl="https://host.vpplayer.tech/player/ptkzurly.js" // Your managed script URL
66
+ scriptId="rbqcdwzlg"
67
+ videoId="vjsobqhe"
68
+ isVertical={true}
56
69
  />
57
70
  ```
58
71
 
59
- ### 2. Reels / Vertical Player
60
- Use for TikTok-style vertical feeds. Enabling `isReels` adds the overlay UI.
72
+ ### Reels Mode (TikTok-style)
61
73
 
62
74
  ```tsx
63
75
  <VPPlayer
64
- playerId="reels-player"
76
+ scriptId="rbqcdwzlg"
77
+ videoId="vjsobqhe"
65
78
  isReels={true}
66
- playlistId="lzxikgjw"
67
- projectId="agmipnzb"
68
- scriptUrl="https://host.vpplayer.tech/vertical-player/rbqcdwzlg.js"
69
- thumbnailUrl="https://example.com/poster.jpg"
79
+ thumbnailUrl="https://example.com/thumb.jpg"
80
+ onClose={() => setShowPlayer(false)}
70
81
  />
71
82
  ```
72
83
 
73
- ### 3. Custom Playlist (Direct Files)
74
- Pass a custom playlist structure. The wrapper automatically transforms this for the Vertical Player SDK if needed.
84
+ ### Manual Playlist (Custom Videos Array)
85
+
86
+ For vertical player with your own videos array (not using GTech admin playlists):
75
87
 
76
88
  ```tsx
77
89
  <VPPlayer
78
- playerId="playlist-player"
79
- config={{
80
- video: {
81
- playlist: {
82
- state: true,
83
- videos: [
84
- { title: "Video 1", file: "https://.../1.mp4" },
85
- { title: "Video 2", file: "https://.../2.mp4" }
86
- ]
87
- }
88
- }
90
+ scriptId="rbqcdwzlg"
91
+ projectId="agmipnzb"
92
+ isVertical={true}
93
+ playlist={{
94
+ videos: [
95
+ {
96
+ videoId: "1",
97
+ title: "Big Buck Bunny",
98
+ file: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
99
+ thumbnailUrl: "https://example.com/thumb1.jpg",
100
+ duration: 498,
101
+ },
102
+ {
103
+ videoId: "2",
104
+ title: "Elephants Dream",
105
+ file: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
106
+ thumbnailUrl: "https://example.com/thumb2.jpg",
107
+ duration: 738,
108
+ },
109
+ ],
110
+ startIndex: 0,
89
111
  }}
112
+ onNext={() => console.log('Next video')}
113
+ onVideoStarted={(data) => console.log('Playing:', data.title)}
90
114
  />
91
115
  ```
92
116
 
93
- ## Architecture & Best Practices
117
+ **Note:** Manual playlist mode calls `player.setup()` internally with the built config. This is required because the VP Vertical Player SDK needs `video.file` to be set even in playlist mode.
94
118
 
95
- This wrapper allows you to follow the "Green Field" approach—treating the player as a black box that just works.
119
+ ### Custom Container Sizing
96
120
 
97
- ### 1. Controlled by Props, Powered by SDK
98
- We do **not** expose the internal player instance via `ref`. All interaction should happen via:
99
- - **Props:** To configure the player (`videoUrl`, `config`).
100
- - **Callbacks:** To react to state changes (`onPlayerPlay`, `onVideoStarted`).
121
+ The player fills its container (100% width/height). Control sizing with a wrapper:
101
122
 
102
- ### 2. Event Handling
103
- We map native SDK events directly to React props.
104
- - **Do not** set up your own event listeners using `window.vpPlayer().on(...)`.
105
- - **Use the provided callbacks:**
106
- - `onPlayerStart`, `onPlayerPlay`, `onPlayerPause`, `onPlayerEnd`
107
- - `onPlayerProgressEvery10Seconds` (10s interval)
108
- - `onPlayerProgressAt20Seconds` (Custom 20s milestone)
109
- - `onPlayerQuartile25/50/75`
123
+ ```tsx
124
+ // Responsive 16:9
125
+ <div style={{ width: '100%', maxWidth: '800px', aspectRatio: '16/9' }}>
126
+ <VPPlayer scriptId="ptkzurnx" videoId="vjsobqhe" />
127
+ </div>
110
128
 
111
- ### 3. Vertical Player Configuration
112
- The Vertical Player SDK has a different configuration schema than the Web Player.
113
- - **Web Player:** Accepts standard playlist object.
114
- - **Vertical Player:** Requires `video.file` to be set even for playlists.
115
- - **Solution:** This package's `vpPlayerConfigBuilder` handles this transformation automatically. You can pass the same config structure to both, and the builder will adapt it.
129
+ // Fixed size
130
+ <div style={{ width: '400px', height: '225px' }}>
131
+ <VPPlayer scriptId="ptkzurnx" videoId="vjsobqhe" />
132
+ </div>
133
+ ```
116
134
 
117
- ## Custom Custom Functionality
135
+ ## Props Reference
118
136
 
119
- ### "Reels" Overlay
120
- When `isReels={true}`:
121
- 1. The player renders a thumbnail first.
122
- 2. Clicking the thumbnail opens the full-screen overlay.
123
- 3. The player instance is initialized only when needed (or preloaded if configured).
137
+ ### Identification (one required)
124
138
 
125
- ### "20 Seconds Watched" Event
126
- The Gjirafa SDK does not have a native "watched for 20 seconds" event.
127
- - **Implementation:** We listen to the native `time` event.
128
- - **Logic:** When `currentTime >= 20`, we fire `onPlayerProgressAt20Seconds` once per video session.
139
+ | Prop | Type | Description |
140
+ |------|------|-------------|
141
+ | `scriptId` | `string` | GTech script ID (e.g., "ptkzurnx") |
142
+ | `videoId` | `string` | GTech video ID (e.g., "vjsobqhe") |
143
+ | `scriptUrl` | `string` | Full managed script URL |
129
144
 
130
- ## Props Reference
145
+ ### Optional
131
146
 
132
147
  | Prop | Type | Description |
133
148
  |------|------|-------------|
134
- | `playerId` | `string` | **Required.** Unique DOM ID for the player container. |
135
- | `scriptUrl` | `string` | **Recommended.** The full URL to your Gjirafa managed script. |
136
- | `videoId` | `string` | ID of the video to fetch from Gjirafa API. |
137
- | `videoUrl` | `string` | Direct URL to a video file (mp4/m3u8). |
138
- | `projectId` | `string` | Required if using `videoId` or `playlistId`. |
139
- | `playlistId` | `string` | ID of the playlist to fetch from Gjirafa API. |
140
- | `isReels` | `boolean` | Enables Vertical/Reels UI mode with overlay. |
141
- | `config` | `object` | Deep overrides for the player configuration object. |
142
- | `onPlayerEvent` | `func` | Universal callback for all analytics events. |
143
-
144
- ## Migration Guide
145
-
146
- If refactoring an existing integration to use this package:
147
-
148
- 1. **Remove Old Script Tags:** Ensure `vpplayer.js` is not loaded globally in your `index.html`. This package handles loading.
149
- 2. **Remove Custom State:** Delete any local state tracking `isPlaying`, `currentTime`, etc. Rely on the player's internal state and callbacks.
150
- 3. **Simplify Config:** Stop manually constructing complex config objects. Pass `videoId`, `playlistId`, or `videoUrl` directly as props.
151
- 4. **Use Callbacks:** Replace custom `setInterval` analytics trackers with `onPlayerProgressEvery10Seconds` and `onPlayerQuartile...` props.
149
+ | `projectId` | `string` | GTech project ID (required for manual playlist) |
150
+ | `playlist` | `ManualPlaylistConfig` | Custom videos array for manual playlist mode |
151
+ | `playerId` | `string` | Custom container ID (auto-generated if not provided) |
152
+ | `isVertical` | `boolean` | Force vertical player mode |
153
+ | `isReels` | `boolean` | Enable Reels overlay mode |
154
+ | `thumbnailUrl` | `string` | Thumbnail for Reels mode |
155
+ | `className` | `string` | CSS class for container |
156
+ | `hiddenClasses` | `string[]` | SDK element classes to hide |
157
+
158
+ ### Event Callbacks
159
+
160
+ | Prop | Horizontal | Vertical | Description |
161
+ |------|:----------:|:--------:|-------------|
162
+ | `onReady` | ✓ | ✓ | Player initialized |
163
+ | `onPlay` | | | Playback started |
164
+ | `onPause` | | | Playback paused |
165
+ | `onComplete` | | | Video completed (horizontal only) |
166
+ | `onError` | | | Error occurred |
167
+ | `onVideoStarted` | ✓ | ✓ | Video metadata available (returns `CurrentVideoData`) |
168
+ | `onTimeUpdate` | ✓ | ✓ | Continuous time updates (returns seconds) |
169
+ | `onQuartile25` | ✓ | ✓ | 25% watched |
170
+ | `onQuartile50` | ✓ | ✓ | 50% watched |
171
+ | `onQuartile75` | ✓ | ✓ | 75% watched |
172
+ | `onNext` | ✓ | ✓ | Next video in playlist |
173
+ | `onPrevious` | ✗ | ✓ | Previous video (vertical only) |
174
+ | `onProgress10s` | ✓ | ✓ | Every ~10 seconds (returns seconds) |
175
+ | `onProgress20s` | ✓ | ✓ | 20 second milestone (returns seconds) |
176
+ | `onClose` | - | - | Reels overlay closed |
177
+
178
+ #### Event Implementation Notes
179
+
180
+ **Horizontal Player** uses standard VP Player SDK events:
181
+ - `ready`, `play`, `pause`, `complete`, `video-started`, `video-state`, `time`, `playlistItem`, `error`
182
+ - Quartiles: `analytics-25%-completed`, `analytics-50%-completed`, `analytics-75%-completed`
183
+
184
+ **Vertical Player** uses VP Vertical Player SDK events (different naming):
185
+ - `vp-ready`, `playing`, `pause`, `vp-video-started`, `vp-video-state`, `vp-time`, `vp-video-switch`, `error`
186
+ - Quartiles: `analytics-25%-completed`, `analytics-50%-completed`, `analytics-75%-completed`
187
+ - Direction detection: Uses `player._switchDirection` property (via `queueMicrotask`) to differentiate `onNext` vs `onPrevious`
188
+
189
+ **Key Differences:**
190
+ - `onComplete` - Only available on horizontal player (vertical auto-advances)
191
+ - `onPrevious` - Only available on vertical player (horizontal has no direction detection)
192
+ - `onNext` on horizontal fires for ANY playlist change (next button, auto-advance after complete)
193
+
194
+ ## URL Helpers
195
+
196
+ ```tsx
197
+ import {
198
+ getFullyManagedPlayerScriptUrl,
199
+ getVerticalPlayerScriptUrl,
200
+ appendDivIdToUrl,
201
+ } from '@devix-technologies/react-gjirafa-vp-player';
202
+
203
+ // Build managed script URL
204
+ const url = getFullyManagedPlayerScriptUrl('ptkzurnx', 'vjsobqhe');
205
+ // => "https://host.vpplayer.tech/player/ptkzurnx/vjsobqhe.js"
206
+
207
+ // Build vertical player URL
208
+ const verticalUrl = getVerticalPlayerScriptUrl('rbqcdwzlg');
209
+ // => "https://host.vpplayer.tech/vertical-player/rbqcdwzlg.js"
210
+ ```
211
+
212
+ ## Advanced: Direct Hook Usage
213
+
214
+ For programmatic control, use the hook directly:
215
+
216
+ ```tsx
217
+ import { useVPPlayerLogic, PlayerContainer } from '@devix-technologies/react-gjirafa-vp-player';
218
+
219
+ function CustomPlayer() {
220
+ const { playerRef, playerInstanceRef, isScriptLoaded, generatedPlayerId } =
221
+ useVPPlayerLogic({
222
+ scriptId: 'ptkzurnx',
223
+ videoId: 'vjsobqhe',
224
+ });
225
+
226
+ return (
227
+ <div>
228
+ <PlayerContainer
229
+ id={generatedPlayerId}
230
+ ref={playerRef}
231
+ width="100%"
232
+ height="auto"
233
+ $hiddenClasses={[]}
234
+ />
235
+ <button onClick={() => playerInstanceRef.current?.play?.()}>Play</button>
236
+ <button onClick={() => playerInstanceRef.current?.pause?.()}>Pause</button>
237
+ </div>
238
+ );
239
+ }
240
+ ```
241
+
242
+ ## Migration from v1.x
243
+
244
+ See [MIGRATION.md](./MIGRATION.md) for detailed upgrade instructions.
245
+
246
+ ### Quick Summary
247
+
248
+ ```tsx
249
+ // BEFORE (v1.x)
250
+ <VPPlayer
251
+ videoId="vjsobqhe"
252
+ projectId="abc123"
253
+ scriptUrl="https://host.vpplayer.tech/player/ptkzurnx.js"
254
+ pureMode={true}
255
+ config={{ video: { autoplay: true } }}
256
+ onPlayerPlay={() => console.log('play')}
257
+ />
258
+
259
+ // AFTER (v2.0.0)
260
+ <VPPlayer
261
+ scriptId="ptkzurnx"
262
+ videoId="vjsobqhe"
263
+ onPlay={() => console.log('play')}
264
+ />
265
+ ```
266
+
267
+ ## License
268
+
269
+ MIT