@videncrypt/react 0.1.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.
- package/README.md +288 -0
- package/dist/index.cjs +221 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.mjs +193 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# @videncrypt/react
|
|
2
|
+
|
|
3
|
+
React component and hook for embedding secure VidEncrypt videos.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @videncrypt/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> `@videncrypt/js` is installed automatically as a dependency.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { VidEncryptPlayer } from '@videncrypt/react';
|
|
19
|
+
|
|
20
|
+
export default function Page() {
|
|
21
|
+
return (
|
|
22
|
+
<VidEncryptPlayer
|
|
23
|
+
videoId="YOUR_VIDEO_ID"
|
|
24
|
+
onPlay={() => console.log('playing')}
|
|
25
|
+
onEnded={() => console.log('ended')}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## VidEncryptPlayer
|
|
34
|
+
|
|
35
|
+
The main component. Renders the player inside a responsive container with built-in loading and error states.
|
|
36
|
+
|
|
37
|
+
### Props
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| `videoId` | `string` | **required** | Video ID from your VidEncrypt dashboard |
|
|
42
|
+
| `width` | `string \| number` | `'100%'` | Player width |
|
|
43
|
+
| `aspectRatio` | `string` | `'16/9'` | Aspect ratio e.g. `'4/3'`, `'1/1'` |
|
|
44
|
+
| `title` | `string` | `''` | iframe title (accessibility) |
|
|
45
|
+
| `autoPlay` | `boolean` | `false` | Auto-play on load (requires `muted: true` in most browsers) |
|
|
46
|
+
| `muted` | `boolean` | `false` | Start muted |
|
|
47
|
+
| `loop` | `boolean` | `false` | Loop video |
|
|
48
|
+
| `startTime` | `number` | `0` | Start at N seconds |
|
|
49
|
+
| `showControls` | `boolean` | `true` | Show player controls |
|
|
50
|
+
| `showBranding` | `boolean` | `true` | Show VidEncrypt badge |
|
|
51
|
+
| `primaryColor` | `string` | `'#2563EB'` | Accent color (hex) |
|
|
52
|
+
| `embedBaseUrl` | `string` | `'https://app.videncrypt.com'` | Override for staging |
|
|
53
|
+
| `className` | `string` | — | CSS class on the wrapper div |
|
|
54
|
+
| `style` | `CSSProperties` | — | Inline style on the wrapper div |
|
|
55
|
+
| `loadingSlot` | `ReactNode` | built-in spinner | Custom loading state |
|
|
56
|
+
| `errorSlot` | `(error) => ReactNode` | built-in error UI | Custom error state |
|
|
57
|
+
| `onReady` | `() => void` | — | Player initialized |
|
|
58
|
+
| `onPlay` | `() => void` | — | Playback started |
|
|
59
|
+
| `onPause` | `() => void` | — | Playback paused |
|
|
60
|
+
| `onEnded` | `() => void` | — | Video ended |
|
|
61
|
+
| `onProgress` | `(currentTime, duration) => void` | — | Position update (~5s interval) |
|
|
62
|
+
| `onError` | `(error: PlayerError) => void` | — | Playback error |
|
|
63
|
+
| `onFullscreenChange` | `(isFullscreen: boolean) => void` | — | Fullscreen toggled |
|
|
64
|
+
|
|
65
|
+
### Examples
|
|
66
|
+
|
|
67
|
+
**Custom aspect ratio:**
|
|
68
|
+
```tsx
|
|
69
|
+
<VidEncryptPlayer
|
|
70
|
+
videoId="YOUR_VIDEO_ID"
|
|
71
|
+
aspectRatio="4/3"
|
|
72
|
+
width={640}
|
|
73
|
+
/>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Autoplay muted:**
|
|
77
|
+
```tsx
|
|
78
|
+
<VidEncryptPlayer
|
|
79
|
+
videoId="YOUR_VIDEO_ID"
|
|
80
|
+
autoPlay
|
|
81
|
+
muted
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Custom loading and error states:**
|
|
86
|
+
```tsx
|
|
87
|
+
<VidEncryptPlayer
|
|
88
|
+
videoId="YOUR_VIDEO_ID"
|
|
89
|
+
loadingSlot={<MySpinner />}
|
|
90
|
+
errorSlot={(error) => (
|
|
91
|
+
<div className="error">
|
|
92
|
+
{error.message} ({error.code})
|
|
93
|
+
</div>
|
|
94
|
+
)}
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Custom accent color:**
|
|
99
|
+
```tsx
|
|
100
|
+
<VidEncryptPlayer
|
|
101
|
+
videoId="YOUR_VIDEO_ID"
|
|
102
|
+
primaryColor="#7C3AED"
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## usePlayer hook
|
|
109
|
+
|
|
110
|
+
For full control over the player with your own UI.
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { usePlayer } from '@videncrypt/react';
|
|
114
|
+
|
|
115
|
+
function CustomPlayer({ videoId }: { videoId: string }) {
|
|
116
|
+
const {
|
|
117
|
+
containerRef,
|
|
118
|
+
playing,
|
|
119
|
+
state,
|
|
120
|
+
play,
|
|
121
|
+
pause,
|
|
122
|
+
seek,
|
|
123
|
+
setVolume,
|
|
124
|
+
} = usePlayer({ videoId });
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<div>
|
|
128
|
+
{/* Player mounts here */}
|
|
129
|
+
<div ref={containerRef} />
|
|
130
|
+
|
|
131
|
+
{/* Custom controls */}
|
|
132
|
+
<button onClick={playing ? pause : play}>
|
|
133
|
+
{playing ? 'Pause' : 'Play'}
|
|
134
|
+
</button>
|
|
135
|
+
|
|
136
|
+
<button onClick={() => seek(30)}>
|
|
137
|
+
Skip to 30s
|
|
138
|
+
</button>
|
|
139
|
+
|
|
140
|
+
<input
|
|
141
|
+
type="range"
|
|
142
|
+
min={0}
|
|
143
|
+
max={1}
|
|
144
|
+
step={0.1}
|
|
145
|
+
onChange={(e) => setVolume(Number(e.target.value))}
|
|
146
|
+
/>
|
|
147
|
+
|
|
148
|
+
<p>
|
|
149
|
+
{state.currentTime.toFixed(0)}s / {state.duration.toFixed(0)}s
|
|
150
|
+
</p>
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Hook return values
|
|
157
|
+
|
|
158
|
+
| Value | Type | Description |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `containerRef` | `RefObject<HTMLDivElement>` | Attach to your container div |
|
|
161
|
+
| `state` | `PlayerState` | Full player state snapshot |
|
|
162
|
+
| `ready` | `boolean` | True after player initializes |
|
|
163
|
+
| `playing` | `boolean` | True while playing |
|
|
164
|
+
| `error` | `PlayerError \| null` | Current error or null |
|
|
165
|
+
| `play()` | `() => void` | Start playback |
|
|
166
|
+
| `pause()` | `() => void` | Pause playback |
|
|
167
|
+
| `seek(time)` | `(number) => void` | Seek to seconds |
|
|
168
|
+
| `setVolume(v)` | `(number) => void` | Set volume 0–1 |
|
|
169
|
+
| `mute()` | `() => void` | Mute audio |
|
|
170
|
+
| `unmute()` | `() => void` | Unmute audio |
|
|
171
|
+
| `enterFullscreen()` | `() => void` | Enter fullscreen |
|
|
172
|
+
| `exitFullscreen()` | `() => void` | Exit fullscreen |
|
|
173
|
+
|
|
174
|
+
### PlayerState
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
interface PlayerState {
|
|
178
|
+
playing: boolean;
|
|
179
|
+
muted: boolean;
|
|
180
|
+
currentTime: number;
|
|
181
|
+
duration: number;
|
|
182
|
+
fullscreen: boolean;
|
|
183
|
+
ready: boolean;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### PlayerError
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
interface PlayerError {
|
|
191
|
+
code: 'token-expired' | 'not-found' | 'domain-not-allowed'
|
|
192
|
+
| 'network-error' | 'unknown';
|
|
193
|
+
message: string;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Framework examples
|
|
200
|
+
|
|
201
|
+
### Next.js App Router
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
// app/watch/[id]/page.tsx
|
|
205
|
+
import { VidEncryptPlayer } from '@videncrypt/react';
|
|
206
|
+
|
|
207
|
+
export default function WatchPage({ params }: { params: { id: string } }) {
|
|
208
|
+
return (
|
|
209
|
+
<main className="max-w-4xl mx-auto p-6">
|
|
210
|
+
<VidEncryptPlayer videoId={params.id} />
|
|
211
|
+
</main>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Next.js with progress tracking
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
'use client';
|
|
220
|
+
|
|
221
|
+
import { VidEncryptPlayer } from '@videncrypt/react';
|
|
222
|
+
import { useState } from 'react';
|
|
223
|
+
|
|
224
|
+
export default function VideoPage({ videoId }: { videoId: string }) {
|
|
225
|
+
const [progress, setProgress] = useState(0);
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
<div>
|
|
229
|
+
<VidEncryptPlayer
|
|
230
|
+
videoId={videoId}
|
|
231
|
+
onProgress={(currentTime, duration) => {
|
|
232
|
+
setProgress(Math.round((currentTime / duration) * 100));
|
|
233
|
+
}}
|
|
234
|
+
/>
|
|
235
|
+
<p>{progress}% watched</p>
|
|
236
|
+
</div>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Pause other videos when one plays
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
'use client';
|
|
245
|
+
|
|
246
|
+
import { usePlayer } from '@videncrypt/react';
|
|
247
|
+
|
|
248
|
+
const VIDEO_IDS = ['video-aaa', 'video-bbb', 'video-ccc'];
|
|
249
|
+
|
|
250
|
+
export default function VideoList() {
|
|
251
|
+
const players = VIDEO_IDS.map((id) =>
|
|
252
|
+
usePlayer({
|
|
253
|
+
videoId: id,
|
|
254
|
+
onPlay: () => {
|
|
255
|
+
// pause all others when this one plays
|
|
256
|
+
players.forEach((p, i) => {
|
|
257
|
+
if (VIDEO_IDS[i] !== id) p.pause();
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
})
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<div className="grid grid-cols-3 gap-4">
|
|
265
|
+
{players.map((player, i) => (
|
|
266
|
+
<div key={VIDEO_IDS[i]} ref={player.containerRef} />
|
|
267
|
+
))}
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## TypeScript
|
|
276
|
+
|
|
277
|
+
All types are exported from `@videncrypt/react` — no need to import from `@videncrypt/js` separately.
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import type {
|
|
281
|
+
PlayerOptions,
|
|
282
|
+
PlayerState,
|
|
283
|
+
PlayerError,
|
|
284
|
+
VidEncryptPlayerProps,
|
|
285
|
+
UsePlayerOptions,
|
|
286
|
+
UsePlayerReturn,
|
|
287
|
+
} from '@videncrypt/react';
|
|
288
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
VidEncryptPlayer: () => VidEncryptPlayer,
|
|
24
|
+
usePlayer: () => usePlayer
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/use-player.ts
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
var import_js = require("@videncrypt/js");
|
|
31
|
+
function usePlayer(options) {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
const containerRef = (0, import_react.useRef)(null);
|
|
34
|
+
const playerRef = (0, import_react.useRef)(null);
|
|
35
|
+
const [state, setState] = (0, import_react.useState)({
|
|
36
|
+
playing: false,
|
|
37
|
+
muted: (_a = options.muted) != null ? _a : false,
|
|
38
|
+
currentTime: (_b = options.startTime) != null ? _b : 0,
|
|
39
|
+
duration: 0,
|
|
40
|
+
fullscreen: false,
|
|
41
|
+
ready: false
|
|
42
|
+
});
|
|
43
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
44
|
+
const optsRef = (0, import_react.useRef)(options);
|
|
45
|
+
optsRef.current = options;
|
|
46
|
+
(0, import_react.useEffect)(() => {
|
|
47
|
+
var _a2;
|
|
48
|
+
const container = containerRef.current;
|
|
49
|
+
if (!container) return;
|
|
50
|
+
(_a2 = playerRef.current) == null ? void 0 : _a2.destroy();
|
|
51
|
+
setError(null);
|
|
52
|
+
const player = new import_js.Player({
|
|
53
|
+
...optsRef.current,
|
|
54
|
+
container,
|
|
55
|
+
onReady: () => {
|
|
56
|
+
var _a3, _b2;
|
|
57
|
+
setState((s) => ({ ...s, ready: true }));
|
|
58
|
+
(_b2 = (_a3 = optsRef.current).onReady) == null ? void 0 : _b2.call(_a3);
|
|
59
|
+
},
|
|
60
|
+
onPlay: () => {
|
|
61
|
+
var _a3, _b2;
|
|
62
|
+
setState((s) => ({ ...s, playing: true }));
|
|
63
|
+
(_b2 = (_a3 = optsRef.current).onPlay) == null ? void 0 : _b2.call(_a3);
|
|
64
|
+
},
|
|
65
|
+
onPause: () => {
|
|
66
|
+
var _a3, _b2;
|
|
67
|
+
setState((s) => ({ ...s, playing: false }));
|
|
68
|
+
(_b2 = (_a3 = optsRef.current).onPause) == null ? void 0 : _b2.call(_a3);
|
|
69
|
+
},
|
|
70
|
+
onEnded: () => {
|
|
71
|
+
var _a3, _b2;
|
|
72
|
+
setState((s) => ({ ...s, playing: false }));
|
|
73
|
+
(_b2 = (_a3 = optsRef.current).onEnded) == null ? void 0 : _b2.call(_a3);
|
|
74
|
+
},
|
|
75
|
+
onProgress: (currentTime, duration) => {
|
|
76
|
+
var _a3, _b2;
|
|
77
|
+
setState((s) => ({ ...s, currentTime, duration }));
|
|
78
|
+
(_b2 = (_a3 = optsRef.current).onProgress) == null ? void 0 : _b2.call(_a3, currentTime, duration);
|
|
79
|
+
},
|
|
80
|
+
onError: (e) => {
|
|
81
|
+
var _a3, _b2;
|
|
82
|
+
setError(e);
|
|
83
|
+
(_b2 = (_a3 = optsRef.current).onError) == null ? void 0 : _b2.call(_a3, e);
|
|
84
|
+
},
|
|
85
|
+
onFullscreenChange: (isFullscreen) => {
|
|
86
|
+
var _a3, _b2;
|
|
87
|
+
setState((s) => ({ ...s, fullscreen: isFullscreen }));
|
|
88
|
+
(_b2 = (_a3 = optsRef.current).onFullscreenChange) == null ? void 0 : _b2.call(_a3, isFullscreen);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
playerRef.current = player;
|
|
92
|
+
return () => {
|
|
93
|
+
player.destroy();
|
|
94
|
+
playerRef.current = null;
|
|
95
|
+
};
|
|
96
|
+
}, [options.videoId]);
|
|
97
|
+
const play = (0, import_react.useCallback)(() => {
|
|
98
|
+
var _a2;
|
|
99
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.play();
|
|
100
|
+
}, []);
|
|
101
|
+
const pause = (0, import_react.useCallback)(() => {
|
|
102
|
+
var _a2;
|
|
103
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.pause();
|
|
104
|
+
}, []);
|
|
105
|
+
const seek = (0, import_react.useCallback)((t) => {
|
|
106
|
+
var _a2;
|
|
107
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.seek(t);
|
|
108
|
+
}, []);
|
|
109
|
+
const setVolume = (0, import_react.useCallback)((v) => {
|
|
110
|
+
var _a2;
|
|
111
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.setVolume(v);
|
|
112
|
+
}, []);
|
|
113
|
+
const mute = (0, import_react.useCallback)(() => {
|
|
114
|
+
var _a2;
|
|
115
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.mute();
|
|
116
|
+
}, []);
|
|
117
|
+
const unmute = (0, import_react.useCallback)(() => {
|
|
118
|
+
var _a2;
|
|
119
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.unmute();
|
|
120
|
+
}, []);
|
|
121
|
+
const enterFullscreen = (0, import_react.useCallback)(() => {
|
|
122
|
+
var _a2;
|
|
123
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.enterFullscreen();
|
|
124
|
+
}, []);
|
|
125
|
+
const exitFullscreen = (0, import_react.useCallback)(() => {
|
|
126
|
+
var _a2;
|
|
127
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.exitFullscreen();
|
|
128
|
+
}, []);
|
|
129
|
+
return {
|
|
130
|
+
containerRef,
|
|
131
|
+
state,
|
|
132
|
+
ready: state.ready,
|
|
133
|
+
playing: state.playing,
|
|
134
|
+
error,
|
|
135
|
+
play,
|
|
136
|
+
pause,
|
|
137
|
+
seek,
|
|
138
|
+
setVolume,
|
|
139
|
+
mute,
|
|
140
|
+
unmute,
|
|
141
|
+
enterFullscreen,
|
|
142
|
+
exitFullscreen
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/player.tsx
|
|
147
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
148
|
+
function VidEncryptPlayer({
|
|
149
|
+
className,
|
|
150
|
+
style,
|
|
151
|
+
loadingSlot,
|
|
152
|
+
errorSlot,
|
|
153
|
+
...options
|
|
154
|
+
}) {
|
|
155
|
+
const { containerRef, ready, error } = usePlayer(options);
|
|
156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
157
|
+
"div",
|
|
158
|
+
{
|
|
159
|
+
style: {
|
|
160
|
+
position: "relative",
|
|
161
|
+
width: "100%",
|
|
162
|
+
background: "#000",
|
|
163
|
+
...style
|
|
164
|
+
},
|
|
165
|
+
className,
|
|
166
|
+
children: [
|
|
167
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: containerRef, style: { width: "100%" } }),
|
|
168
|
+
!ready && !error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: overlayStyle, children: loadingSlot != null ? loadingSlot : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefaultLoading, {}) }),
|
|
169
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: overlayStyle, children: errorSlot ? errorSlot(error) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefaultError, { error }) })
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
function DefaultLoading() {
|
|
175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
|
|
176
|
+
position: "absolute",
|
|
177
|
+
inset: 0,
|
|
178
|
+
display: "flex",
|
|
179
|
+
alignItems: "center",
|
|
180
|
+
justifyContent: "center",
|
|
181
|
+
background: "#000",
|
|
182
|
+
pointerEvents: "none"
|
|
183
|
+
}, children: [
|
|
184
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
185
|
+
width: 32,
|
|
186
|
+
height: 32,
|
|
187
|
+
border: "3px solid rgba(255,255,255,0.15)",
|
|
188
|
+
borderTopColor: "#2563EB",
|
|
189
|
+
borderRadius: "50%",
|
|
190
|
+
animation: "ve-spin 0.75s linear infinite"
|
|
191
|
+
} }),
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
|
|
193
|
+
@keyframes ve-spin { to { transform: rotate(360deg); } }
|
|
194
|
+
` })
|
|
195
|
+
] });
|
|
196
|
+
}
|
|
197
|
+
function DefaultError({ error }) {
|
|
198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
|
|
199
|
+
position: "absolute",
|
|
200
|
+
inset: 0,
|
|
201
|
+
display: "flex",
|
|
202
|
+
flexDirection: "column",
|
|
203
|
+
alignItems: "center",
|
|
204
|
+
justifyContent: "center",
|
|
205
|
+
background: "#000",
|
|
206
|
+
gap: 8
|
|
207
|
+
}, children: [
|
|
208
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { color: "rgba(255,255,255,0.5)", fontSize: 13, margin: 0 }, children: error.message }),
|
|
209
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { color: "rgba(255,255,255,0.25)", fontSize: 11, margin: 0 }, children: error.code })
|
|
210
|
+
] });
|
|
211
|
+
}
|
|
212
|
+
var overlayStyle = {
|
|
213
|
+
position: "absolute",
|
|
214
|
+
inset: 0
|
|
215
|
+
};
|
|
216
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
217
|
+
0 && (module.exports = {
|
|
218
|
+
VidEncryptPlayer,
|
|
219
|
+
usePlayer
|
|
220
|
+
});
|
|
221
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/use-player.ts","../src/player.tsx"],"sourcesContent":["// Main component\nexport { VidEncryptPlayer } from './player';\nexport type { VidEncryptPlayerProps } from './player';\n\n// Hook for custom implementations\nexport { usePlayer } from './use-player';\nexport type { UsePlayerOptions, UsePlayerReturn } from './use-player';\n\n// Re-export types from @videncrypt/js so consumers\n// only need to import from @videncrypt/react\nexport type {\n PlayerOptions,\n PlayerState,\n PlayerError,\n PlayerEventMap,\n} from '@videncrypt/js';","import { useEffect, useRef, useState, useCallback } from 'react';\nimport { Player } from '@videncrypt/js';\nimport type { PlayerOptions, PlayerState, PlayerError } from '@videncrypt/js';\n\n// ── usePlayer hook ─────────────────────────────────────────\n// Creates and manages a VidEncryptPlayer instance.\n// Handles lifecycle — creates on mount, destroys on unmount.\n// Re-creates when videoId changes.\n\nexport interface UsePlayerOptions\n extends Omit<PlayerOptions, 'container'> {\n // container is handled by the component via ref\n}\n\nexport interface UsePlayerReturn {\n // Attach this ref to the container div\n containerRef: React.RefObject<HTMLDivElement | null>;\n\n // Current player state\n state: PlayerState;\n ready: boolean;\n playing: boolean;\n error: PlayerError | null;\n\n // Playback controls\n play: () => void;\n pause: () => void;\n seek: (time: number) => void;\n setVolume: (volume: number) => void;\n mute: () => void;\n unmute: () => void;\n enterFullscreen: () => void;\n exitFullscreen: () => void;\n}\n\nexport function usePlayer(options: UsePlayerOptions): UsePlayerReturn {\n const containerRef = useRef<HTMLDivElement>(null);\n const playerRef = useRef<InstanceType<typeof Player> | null>(null);\n\n const [state, setState] = useState<PlayerState>({\n playing: false,\n muted: options.muted ?? false,\n currentTime: options.startTime ?? 0,\n duration: 0,\n fullscreen: false,\n ready: false,\n });\n\n const [error, setError] = useState<PlayerError | null>(null);\n\n // Stable options ref — avoids recreating player on every render\n // when callbacks are inline arrow functions\n const optsRef = useRef(options);\n optsRef.current = options;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Destroy previous instance if videoId changed\n playerRef.current?.destroy();\n setError(null);\n\n const player = new Player({\n ...optsRef.current,\n container,\n\n onReady: () => {\n setState((s) => ({ ...s, ready: true }));\n optsRef.current.onReady?.();\n },\n onPlay: () => {\n setState((s) => ({ ...s, playing: true }));\n optsRef.current.onPlay?.();\n },\n onPause: () => {\n setState((s) => ({ ...s, playing: false }));\n optsRef.current.onPause?.();\n },\n onEnded: () => {\n setState((s) => ({ ...s, playing: false }));\n optsRef.current.onEnded?.();\n },\n onProgress: (currentTime, duration) => {\n setState((s) => ({ ...s, currentTime, duration }));\n optsRef.current.onProgress?.(currentTime, duration);\n },\n onError: (e) => {\n setError(e);\n optsRef.current.onError?.(e);\n },\n onFullscreenChange: (isFullscreen) => {\n setState((s) => ({ ...s, fullscreen: isFullscreen }));\n optsRef.current.onFullscreenChange?.(isFullscreen);\n },\n });\n\n playerRef.current = player;\n\n return () => {\n player.destroy();\n playerRef.current = null;\n };\n }, [options.videoId]); // only re-create when videoId changes\n\n // ── Stable control functions ───────────────────────────\n // useCallback with empty deps — these never change,\n // they just call the current player ref\n\n const play = useCallback(() => playerRef.current?.play(), []);\n const pause = useCallback(() => playerRef.current?.pause(), []);\n const seek = useCallback((t: number) => playerRef.current?.seek(t), []);\n const setVolume = useCallback((v: number) => playerRef.current?.setVolume(v), []);\n const mute = useCallback(() => playerRef.current?.mute(), []);\n const unmute = useCallback(() => playerRef.current?.unmute(), []);\n const enterFullscreen = useCallback(() => playerRef.current?.enterFullscreen(), []);\n const exitFullscreen = useCallback(() => playerRef.current?.exitFullscreen(), []);\n\n return {\n containerRef,\n state,\n ready: state.ready,\n playing: state.playing,\n error,\n play,\n pause,\n seek,\n setVolume,\n mute,\n unmute,\n enterFullscreen,\n exitFullscreen,\n };\n}","'use client';\n\nimport { usePlayer, type UsePlayerOptions } from './use-player';\nimport type { PlayerError } from '@videncrypt/js';\n\n// ── Props ──────────────────────────────────────────────────\n\nexport interface VidEncryptPlayerProps extends UsePlayerOptions {\n // Container sizing\n className?: string;\n style?: React.CSSProperties;\n\n // Loading slot — shown while player initializes\n // Default: simple grey box\n loadingSlot?: React.ReactNode;\n\n // Error slot — shown on playback error\n // Default: error message + code\n errorSlot?: (error: PlayerError) => React.ReactNode;\n}\n\n// ── Component ──────────────────────────────────────────────\n\nexport function VidEncryptPlayer({\n className,\n style,\n loadingSlot,\n errorSlot,\n ...options\n}: VidEncryptPlayerProps) {\n const { containerRef, ready, error } = usePlayer(options);\n\n return (\n <div\n style={{\n position: 'relative',\n width: '100%',\n background: '#000',\n ...style,\n }}\n className={className}\n >\n {/* Player mounts here — always rendered so the ref is stable */}\n <div ref={containerRef} style={{ width: '100%' }} />\n\n {/* Loading overlay — shown until player is ready */}\n {!ready && !error && (\n <div style={overlayStyle}>\n {loadingSlot ?? <DefaultLoading />}\n </div>\n )}\n\n {/* Error overlay */}\n {error && (\n <div style={overlayStyle}>\n {errorSlot ? errorSlot(error) : <DefaultError error={error} />}\n </div>\n )}\n </div>\n );\n}\n\n// ── Default loading state ──────────────────────────────────\n\nfunction DefaultLoading() {\n return (\n <div style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: '#000',\n pointerEvents: 'none',\n }}>\n <div style={{\n width: 32,\n height: 32,\n border: '3px solid rgba(255,255,255,0.15)',\n borderTopColor: '#2563EB',\n borderRadius: '50%',\n animation: 've-spin 0.75s linear infinite',\n }} />\n <style>{`\n @keyframes ve-spin { to { transform: rotate(360deg); } }\n `}</style>\n </div>\n );\n}\n\n// ── Default error state ────────────────────────────────────\n\nfunction DefaultError({ error }: { error: PlayerError }) {\n return (\n <div style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n background: '#000',\n gap: 8,\n }}>\n <p style={{ color: 'rgba(255,255,255,0.5)', fontSize: 13, margin: 0 }}>\n {error.message}\n </p>\n <p style={{ color: 'rgba(255,255,255,0.25)', fontSize: 11, margin: 0 }}>\n {error.code}\n </p>\n </div>\n );\n}\n\n// ── Shared styles ──────────────────────────────────────────\n\nconst overlayStyle: React.CSSProperties = {\n position: 'absolute',\n inset: 0,\n};"],"mappings":"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","names":["_a","_b"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { PlayerOptions, PlayerState, PlayerError } from '@videncrypt/js';
|
|
3
|
+
export { PlayerError, PlayerEventMap, PlayerOptions, PlayerState } from '@videncrypt/js';
|
|
4
|
+
|
|
5
|
+
interface UsePlayerOptions extends Omit<PlayerOptions, 'container'> {
|
|
6
|
+
}
|
|
7
|
+
interface UsePlayerReturn {
|
|
8
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
9
|
+
state: PlayerState;
|
|
10
|
+
ready: boolean;
|
|
11
|
+
playing: boolean;
|
|
12
|
+
error: PlayerError | null;
|
|
13
|
+
play: () => void;
|
|
14
|
+
pause: () => void;
|
|
15
|
+
seek: (time: number) => void;
|
|
16
|
+
setVolume: (volume: number) => void;
|
|
17
|
+
mute: () => void;
|
|
18
|
+
unmute: () => void;
|
|
19
|
+
enterFullscreen: () => void;
|
|
20
|
+
exitFullscreen: () => void;
|
|
21
|
+
}
|
|
22
|
+
declare function usePlayer(options: UsePlayerOptions): UsePlayerReturn;
|
|
23
|
+
|
|
24
|
+
interface VidEncryptPlayerProps extends UsePlayerOptions {
|
|
25
|
+
className?: string;
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
loadingSlot?: React.ReactNode;
|
|
28
|
+
errorSlot?: (error: PlayerError) => React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
declare function VidEncryptPlayer({ className, style, loadingSlot, errorSlot, ...options }: VidEncryptPlayerProps): react_jsx_runtime.JSX.Element;
|
|
31
|
+
|
|
32
|
+
export { type UsePlayerOptions, type UsePlayerReturn, VidEncryptPlayer, type VidEncryptPlayerProps, usePlayer };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { PlayerOptions, PlayerState, PlayerError } from '@videncrypt/js';
|
|
3
|
+
export { PlayerError, PlayerEventMap, PlayerOptions, PlayerState } from '@videncrypt/js';
|
|
4
|
+
|
|
5
|
+
interface UsePlayerOptions extends Omit<PlayerOptions, 'container'> {
|
|
6
|
+
}
|
|
7
|
+
interface UsePlayerReturn {
|
|
8
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
9
|
+
state: PlayerState;
|
|
10
|
+
ready: boolean;
|
|
11
|
+
playing: boolean;
|
|
12
|
+
error: PlayerError | null;
|
|
13
|
+
play: () => void;
|
|
14
|
+
pause: () => void;
|
|
15
|
+
seek: (time: number) => void;
|
|
16
|
+
setVolume: (volume: number) => void;
|
|
17
|
+
mute: () => void;
|
|
18
|
+
unmute: () => void;
|
|
19
|
+
enterFullscreen: () => void;
|
|
20
|
+
exitFullscreen: () => void;
|
|
21
|
+
}
|
|
22
|
+
declare function usePlayer(options: UsePlayerOptions): UsePlayerReturn;
|
|
23
|
+
|
|
24
|
+
interface VidEncryptPlayerProps extends UsePlayerOptions {
|
|
25
|
+
className?: string;
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
loadingSlot?: React.ReactNode;
|
|
28
|
+
errorSlot?: (error: PlayerError) => React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
declare function VidEncryptPlayer({ className, style, loadingSlot, errorSlot, ...options }: VidEncryptPlayerProps): react_jsx_runtime.JSX.Element;
|
|
31
|
+
|
|
32
|
+
export { type UsePlayerOptions, type UsePlayerReturn, VidEncryptPlayer, type VidEncryptPlayerProps, usePlayer };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// src/use-player.ts
|
|
2
|
+
import { useEffect, useRef, useState, useCallback } from "react";
|
|
3
|
+
import { Player } from "@videncrypt/js";
|
|
4
|
+
function usePlayer(options) {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
const containerRef = useRef(null);
|
|
7
|
+
const playerRef = useRef(null);
|
|
8
|
+
const [state, setState] = useState({
|
|
9
|
+
playing: false,
|
|
10
|
+
muted: (_a = options.muted) != null ? _a : false,
|
|
11
|
+
currentTime: (_b = options.startTime) != null ? _b : 0,
|
|
12
|
+
duration: 0,
|
|
13
|
+
fullscreen: false,
|
|
14
|
+
ready: false
|
|
15
|
+
});
|
|
16
|
+
const [error, setError] = useState(null);
|
|
17
|
+
const optsRef = useRef(options);
|
|
18
|
+
optsRef.current = options;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
var _a2;
|
|
21
|
+
const container = containerRef.current;
|
|
22
|
+
if (!container) return;
|
|
23
|
+
(_a2 = playerRef.current) == null ? void 0 : _a2.destroy();
|
|
24
|
+
setError(null);
|
|
25
|
+
const player = new Player({
|
|
26
|
+
...optsRef.current,
|
|
27
|
+
container,
|
|
28
|
+
onReady: () => {
|
|
29
|
+
var _a3, _b2;
|
|
30
|
+
setState((s) => ({ ...s, ready: true }));
|
|
31
|
+
(_b2 = (_a3 = optsRef.current).onReady) == null ? void 0 : _b2.call(_a3);
|
|
32
|
+
},
|
|
33
|
+
onPlay: () => {
|
|
34
|
+
var _a3, _b2;
|
|
35
|
+
setState((s) => ({ ...s, playing: true }));
|
|
36
|
+
(_b2 = (_a3 = optsRef.current).onPlay) == null ? void 0 : _b2.call(_a3);
|
|
37
|
+
},
|
|
38
|
+
onPause: () => {
|
|
39
|
+
var _a3, _b2;
|
|
40
|
+
setState((s) => ({ ...s, playing: false }));
|
|
41
|
+
(_b2 = (_a3 = optsRef.current).onPause) == null ? void 0 : _b2.call(_a3);
|
|
42
|
+
},
|
|
43
|
+
onEnded: () => {
|
|
44
|
+
var _a3, _b2;
|
|
45
|
+
setState((s) => ({ ...s, playing: false }));
|
|
46
|
+
(_b2 = (_a3 = optsRef.current).onEnded) == null ? void 0 : _b2.call(_a3);
|
|
47
|
+
},
|
|
48
|
+
onProgress: (currentTime, duration) => {
|
|
49
|
+
var _a3, _b2;
|
|
50
|
+
setState((s) => ({ ...s, currentTime, duration }));
|
|
51
|
+
(_b2 = (_a3 = optsRef.current).onProgress) == null ? void 0 : _b2.call(_a3, currentTime, duration);
|
|
52
|
+
},
|
|
53
|
+
onError: (e) => {
|
|
54
|
+
var _a3, _b2;
|
|
55
|
+
setError(e);
|
|
56
|
+
(_b2 = (_a3 = optsRef.current).onError) == null ? void 0 : _b2.call(_a3, e);
|
|
57
|
+
},
|
|
58
|
+
onFullscreenChange: (isFullscreen) => {
|
|
59
|
+
var _a3, _b2;
|
|
60
|
+
setState((s) => ({ ...s, fullscreen: isFullscreen }));
|
|
61
|
+
(_b2 = (_a3 = optsRef.current).onFullscreenChange) == null ? void 0 : _b2.call(_a3, isFullscreen);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
playerRef.current = player;
|
|
65
|
+
return () => {
|
|
66
|
+
player.destroy();
|
|
67
|
+
playerRef.current = null;
|
|
68
|
+
};
|
|
69
|
+
}, [options.videoId]);
|
|
70
|
+
const play = useCallback(() => {
|
|
71
|
+
var _a2;
|
|
72
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.play();
|
|
73
|
+
}, []);
|
|
74
|
+
const pause = useCallback(() => {
|
|
75
|
+
var _a2;
|
|
76
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.pause();
|
|
77
|
+
}, []);
|
|
78
|
+
const seek = useCallback((t) => {
|
|
79
|
+
var _a2;
|
|
80
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.seek(t);
|
|
81
|
+
}, []);
|
|
82
|
+
const setVolume = useCallback((v) => {
|
|
83
|
+
var _a2;
|
|
84
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.setVolume(v);
|
|
85
|
+
}, []);
|
|
86
|
+
const mute = useCallback(() => {
|
|
87
|
+
var _a2;
|
|
88
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.mute();
|
|
89
|
+
}, []);
|
|
90
|
+
const unmute = useCallback(() => {
|
|
91
|
+
var _a2;
|
|
92
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.unmute();
|
|
93
|
+
}, []);
|
|
94
|
+
const enterFullscreen = useCallback(() => {
|
|
95
|
+
var _a2;
|
|
96
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.enterFullscreen();
|
|
97
|
+
}, []);
|
|
98
|
+
const exitFullscreen = useCallback(() => {
|
|
99
|
+
var _a2;
|
|
100
|
+
return (_a2 = playerRef.current) == null ? void 0 : _a2.exitFullscreen();
|
|
101
|
+
}, []);
|
|
102
|
+
return {
|
|
103
|
+
containerRef,
|
|
104
|
+
state,
|
|
105
|
+
ready: state.ready,
|
|
106
|
+
playing: state.playing,
|
|
107
|
+
error,
|
|
108
|
+
play,
|
|
109
|
+
pause,
|
|
110
|
+
seek,
|
|
111
|
+
setVolume,
|
|
112
|
+
mute,
|
|
113
|
+
unmute,
|
|
114
|
+
enterFullscreen,
|
|
115
|
+
exitFullscreen
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/player.tsx
|
|
120
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
121
|
+
function VidEncryptPlayer({
|
|
122
|
+
className,
|
|
123
|
+
style,
|
|
124
|
+
loadingSlot,
|
|
125
|
+
errorSlot,
|
|
126
|
+
...options
|
|
127
|
+
}) {
|
|
128
|
+
const { containerRef, ready, error } = usePlayer(options);
|
|
129
|
+
return /* @__PURE__ */ jsxs(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: {
|
|
133
|
+
position: "relative",
|
|
134
|
+
width: "100%",
|
|
135
|
+
background: "#000",
|
|
136
|
+
...style
|
|
137
|
+
},
|
|
138
|
+
className,
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { width: "100%" } }),
|
|
141
|
+
!ready && !error && /* @__PURE__ */ jsx("div", { style: overlayStyle, children: loadingSlot != null ? loadingSlot : /* @__PURE__ */ jsx(DefaultLoading, {}) }),
|
|
142
|
+
error && /* @__PURE__ */ jsx("div", { style: overlayStyle, children: errorSlot ? errorSlot(error) : /* @__PURE__ */ jsx(DefaultError, { error }) })
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
function DefaultLoading() {
|
|
148
|
+
return /* @__PURE__ */ jsxs("div", { style: {
|
|
149
|
+
position: "absolute",
|
|
150
|
+
inset: 0,
|
|
151
|
+
display: "flex",
|
|
152
|
+
alignItems: "center",
|
|
153
|
+
justifyContent: "center",
|
|
154
|
+
background: "#000",
|
|
155
|
+
pointerEvents: "none"
|
|
156
|
+
}, children: [
|
|
157
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
158
|
+
width: 32,
|
|
159
|
+
height: 32,
|
|
160
|
+
border: "3px solid rgba(255,255,255,0.15)",
|
|
161
|
+
borderTopColor: "#2563EB",
|
|
162
|
+
borderRadius: "50%",
|
|
163
|
+
animation: "ve-spin 0.75s linear infinite"
|
|
164
|
+
} }),
|
|
165
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
166
|
+
@keyframes ve-spin { to { transform: rotate(360deg); } }
|
|
167
|
+
` })
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
function DefaultError({ error }) {
|
|
171
|
+
return /* @__PURE__ */ jsxs("div", { style: {
|
|
172
|
+
position: "absolute",
|
|
173
|
+
inset: 0,
|
|
174
|
+
display: "flex",
|
|
175
|
+
flexDirection: "column",
|
|
176
|
+
alignItems: "center",
|
|
177
|
+
justifyContent: "center",
|
|
178
|
+
background: "#000",
|
|
179
|
+
gap: 8
|
|
180
|
+
}, children: [
|
|
181
|
+
/* @__PURE__ */ jsx("p", { style: { color: "rgba(255,255,255,0.5)", fontSize: 13, margin: 0 }, children: error.message }),
|
|
182
|
+
/* @__PURE__ */ jsx("p", { style: { color: "rgba(255,255,255,0.25)", fontSize: 11, margin: 0 }, children: error.code })
|
|
183
|
+
] });
|
|
184
|
+
}
|
|
185
|
+
var overlayStyle = {
|
|
186
|
+
position: "absolute",
|
|
187
|
+
inset: 0
|
|
188
|
+
};
|
|
189
|
+
export {
|
|
190
|
+
VidEncryptPlayer,
|
|
191
|
+
usePlayer
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/use-player.ts","../src/player.tsx"],"sourcesContent":["import { useEffect, useRef, useState, useCallback } from 'react';\nimport { Player } from '@videncrypt/js';\nimport type { PlayerOptions, PlayerState, PlayerError } from '@videncrypt/js';\n\n// ── usePlayer hook ─────────────────────────────────────────\n// Creates and manages a VidEncryptPlayer instance.\n// Handles lifecycle — creates on mount, destroys on unmount.\n// Re-creates when videoId changes.\n\nexport interface UsePlayerOptions\n extends Omit<PlayerOptions, 'container'> {\n // container is handled by the component via ref\n}\n\nexport interface UsePlayerReturn {\n // Attach this ref to the container div\n containerRef: React.RefObject<HTMLDivElement | null>;\n\n // Current player state\n state: PlayerState;\n ready: boolean;\n playing: boolean;\n error: PlayerError | null;\n\n // Playback controls\n play: () => void;\n pause: () => void;\n seek: (time: number) => void;\n setVolume: (volume: number) => void;\n mute: () => void;\n unmute: () => void;\n enterFullscreen: () => void;\n exitFullscreen: () => void;\n}\n\nexport function usePlayer(options: UsePlayerOptions): UsePlayerReturn {\n const containerRef = useRef<HTMLDivElement>(null);\n const playerRef = useRef<InstanceType<typeof Player> | null>(null);\n\n const [state, setState] = useState<PlayerState>({\n playing: false,\n muted: options.muted ?? false,\n currentTime: options.startTime ?? 0,\n duration: 0,\n fullscreen: false,\n ready: false,\n });\n\n const [error, setError] = useState<PlayerError | null>(null);\n\n // Stable options ref — avoids recreating player on every render\n // when callbacks are inline arrow functions\n const optsRef = useRef(options);\n optsRef.current = options;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Destroy previous instance if videoId changed\n playerRef.current?.destroy();\n setError(null);\n\n const player = new Player({\n ...optsRef.current,\n container,\n\n onReady: () => {\n setState((s) => ({ ...s, ready: true }));\n optsRef.current.onReady?.();\n },\n onPlay: () => {\n setState((s) => ({ ...s, playing: true }));\n optsRef.current.onPlay?.();\n },\n onPause: () => {\n setState((s) => ({ ...s, playing: false }));\n optsRef.current.onPause?.();\n },\n onEnded: () => {\n setState((s) => ({ ...s, playing: false }));\n optsRef.current.onEnded?.();\n },\n onProgress: (currentTime, duration) => {\n setState((s) => ({ ...s, currentTime, duration }));\n optsRef.current.onProgress?.(currentTime, duration);\n },\n onError: (e) => {\n setError(e);\n optsRef.current.onError?.(e);\n },\n onFullscreenChange: (isFullscreen) => {\n setState((s) => ({ ...s, fullscreen: isFullscreen }));\n optsRef.current.onFullscreenChange?.(isFullscreen);\n },\n });\n\n playerRef.current = player;\n\n return () => {\n player.destroy();\n playerRef.current = null;\n };\n }, [options.videoId]); // only re-create when videoId changes\n\n // ── Stable control functions ───────────────────────────\n // useCallback with empty deps — these never change,\n // they just call the current player ref\n\n const play = useCallback(() => playerRef.current?.play(), []);\n const pause = useCallback(() => playerRef.current?.pause(), []);\n const seek = useCallback((t: number) => playerRef.current?.seek(t), []);\n const setVolume = useCallback((v: number) => playerRef.current?.setVolume(v), []);\n const mute = useCallback(() => playerRef.current?.mute(), []);\n const unmute = useCallback(() => playerRef.current?.unmute(), []);\n const enterFullscreen = useCallback(() => playerRef.current?.enterFullscreen(), []);\n const exitFullscreen = useCallback(() => playerRef.current?.exitFullscreen(), []);\n\n return {\n containerRef,\n state,\n ready: state.ready,\n playing: state.playing,\n error,\n play,\n pause,\n seek,\n setVolume,\n mute,\n unmute,\n enterFullscreen,\n exitFullscreen,\n };\n}","'use client';\n\nimport { usePlayer, type UsePlayerOptions } from './use-player';\nimport type { PlayerError } from '@videncrypt/js';\n\n// ── Props ──────────────────────────────────────────────────\n\nexport interface VidEncryptPlayerProps extends UsePlayerOptions {\n // Container sizing\n className?: string;\n style?: React.CSSProperties;\n\n // Loading slot — shown while player initializes\n // Default: simple grey box\n loadingSlot?: React.ReactNode;\n\n // Error slot — shown on playback error\n // Default: error message + code\n errorSlot?: (error: PlayerError) => React.ReactNode;\n}\n\n// ── Component ──────────────────────────────────────────────\n\nexport function VidEncryptPlayer({\n className,\n style,\n loadingSlot,\n errorSlot,\n ...options\n}: VidEncryptPlayerProps) {\n const { containerRef, ready, error } = usePlayer(options);\n\n return (\n <div\n style={{\n position: 'relative',\n width: '100%',\n background: '#000',\n ...style,\n }}\n className={className}\n >\n {/* Player mounts here — always rendered so the ref is stable */}\n <div ref={containerRef} style={{ width: '100%' }} />\n\n {/* Loading overlay — shown until player is ready */}\n {!ready && !error && (\n <div style={overlayStyle}>\n {loadingSlot ?? <DefaultLoading />}\n </div>\n )}\n\n {/* Error overlay */}\n {error && (\n <div style={overlayStyle}>\n {errorSlot ? errorSlot(error) : <DefaultError error={error} />}\n </div>\n )}\n </div>\n );\n}\n\n// ── Default loading state ──────────────────────────────────\n\nfunction DefaultLoading() {\n return (\n <div style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: '#000',\n pointerEvents: 'none',\n }}>\n <div style={{\n width: 32,\n height: 32,\n border: '3px solid rgba(255,255,255,0.15)',\n borderTopColor: '#2563EB',\n borderRadius: '50%',\n animation: 've-spin 0.75s linear infinite',\n }} />\n <style>{`\n @keyframes ve-spin { to { transform: rotate(360deg); } }\n `}</style>\n </div>\n );\n}\n\n// ── Default error state ────────────────────────────────────\n\nfunction DefaultError({ error }: { error: PlayerError }) {\n return (\n <div style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n background: '#000',\n gap: 8,\n }}>\n <p style={{ color: 'rgba(255,255,255,0.5)', fontSize: 13, margin: 0 }}>\n {error.message}\n </p>\n <p style={{ color: 'rgba(255,255,255,0.25)', fontSize: 11, margin: 0 }}>\n {error.code}\n </p>\n </div>\n );\n}\n\n// ── Shared styles ──────────────────────────────────────────\n\nconst overlayStyle: React.CSSProperties = {\n position: 'absolute',\n inset: 0,\n};"],"mappings":"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","names":["_a","_b"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@videncrypt/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React component for VidEncrypt secure video player",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "VidEncrypt",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": ">=18.0.0",
|
|
24
|
+
"react-dom": ">=18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@videncrypt/js": "0.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.0.0",
|
|
31
|
+
"tsup": "^8.0.0",
|
|
32
|
+
"@types/react": "^19.0.0",
|
|
33
|
+
"@types/react-dom": "^19.0.0",
|
|
34
|
+
"react": "^19.0.0",
|
|
35
|
+
"react-dom": "^19.0.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"build:watch": "tsup --watch",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"clean": "rm -rf dist"
|
|
42
|
+
}
|
|
43
|
+
}
|