@thewhateverapp/tile-sdk 0.12.2 → 0.12.3
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.
|
@@ -59,28 +59,14 @@ export interface CuePoint {
|
|
|
59
59
|
data?: unknown;
|
|
60
60
|
}
|
|
61
61
|
export interface VideoPlayerProps {
|
|
62
|
-
/**
|
|
63
|
-
* Video source URL (HLS playlist or direct video URL).
|
|
64
|
-
* If not provided, VideoPlayer will auto-fetch from the tile's metadata
|
|
65
|
-
* using the tileId from NEXT_PUBLIC_TILE_ID environment variable.
|
|
66
|
-
*/
|
|
67
|
-
src?: string;
|
|
68
|
-
/** Auto-start playback (default: true, or from tile metadata) */
|
|
69
|
-
autoplay?: boolean;
|
|
70
|
-
/** Loop video (default: false, but true in preview mode) */
|
|
71
|
-
loop?: boolean;
|
|
72
|
-
/** Start muted (default: true for autoplay compliance) */
|
|
73
|
-
muted?: boolean;
|
|
74
|
-
/** Poster image URL (auto-fetched from tile metadata if not provided) */
|
|
75
|
-
poster?: string;
|
|
76
|
-
/** Show native controls (default: false) */
|
|
77
|
-
controls?: boolean;
|
|
78
62
|
/** Children rendered as overlay */
|
|
79
63
|
children?: ReactNode;
|
|
80
64
|
/** Additional class names */
|
|
81
65
|
className?: string;
|
|
82
66
|
/** Video wrapper class names */
|
|
83
67
|
videoClassName?: string;
|
|
68
|
+
/** Show native controls (default: false) */
|
|
69
|
+
controls?: boolean;
|
|
84
70
|
/** Cue points for time-based triggers */
|
|
85
71
|
cuePoints?: CuePoint[];
|
|
86
72
|
/** Callback when a cue point is reached */
|
|
@@ -93,13 +79,20 @@ export interface VideoPlayerProps {
|
|
|
93
79
|
* Provides video state and controls to child overlays via context.
|
|
94
80
|
*
|
|
95
81
|
* Features:
|
|
82
|
+
* - Auto-fetches video URL from tile metadata (no src prop needed!)
|
|
96
83
|
* - HLS streaming with automatic quality adaptation
|
|
97
84
|
* - Time-based cue points for triggering overlays
|
|
98
85
|
* - Visibility-aware playback (plays when visible, pauses when hidden)
|
|
99
|
-
* - Auto-loops
|
|
100
|
-
*
|
|
86
|
+
* - Auto-loops by default (can be disabled via tile metadata)
|
|
87
|
+
*
|
|
88
|
+
* Usage:
|
|
89
|
+
* ```tsx
|
|
90
|
+
* <VideoPlayer className="w-full h-full">
|
|
91
|
+
* <YourOverlay />
|
|
92
|
+
* </VideoPlayer>
|
|
93
|
+
* ```
|
|
101
94
|
*/
|
|
102
|
-
export declare function VideoPlayer({
|
|
95
|
+
export declare function VideoPlayer({ controls, children, className, videoClassName, cuePoints, onCuePoint, onTimeUpdate, }: VideoPlayerProps): React.JSX.Element;
|
|
103
96
|
/**
|
|
104
97
|
* Hook to access video state and controls from within VideoPlayer children.
|
|
105
98
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/VideoPlayer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA0Ef,UAAU,WAAW;IACnB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;IACpE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,SAAS;IACjB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,UAAU,EAAE;QACV,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,KAAK,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,CAAC;CAClF;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,EAAE,SAAS,CAAC;KAChB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;CAC7C;AAID,MAAM,WAAW,QAAQ;IACvB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B
|
|
1
|
+
{"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/VideoPlayer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -38,24 +38,25 @@ async function fetchVideoMetadata(tileId) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const VideoContext = createContext(null);
|
|
41
|
-
// Detect if we're in preview mode (tile-preview sets this global)
|
|
42
|
-
function isPreviewMode() {
|
|
43
|
-
if (typeof window === 'undefined')
|
|
44
|
-
return false;
|
|
45
|
-
return !!window.__PREVIEW_SESSION_ID__;
|
|
46
|
-
}
|
|
47
41
|
/**
|
|
48
42
|
* VideoPlayer component with HLS streaming support.
|
|
49
43
|
* Provides video state and controls to child overlays via context.
|
|
50
44
|
*
|
|
51
45
|
* Features:
|
|
46
|
+
* - Auto-fetches video URL from tile metadata (no src prop needed!)
|
|
52
47
|
* - HLS streaming with automatic quality adaptation
|
|
53
48
|
* - Time-based cue points for triggering overlays
|
|
54
49
|
* - Visibility-aware playback (plays when visible, pauses when hidden)
|
|
55
|
-
* - Auto-loops
|
|
56
|
-
*
|
|
50
|
+
* - Auto-loops by default (can be disabled via tile metadata)
|
|
51
|
+
*
|
|
52
|
+
* Usage:
|
|
53
|
+
* ```tsx
|
|
54
|
+
* <VideoPlayer className="w-full h-full">
|
|
55
|
+
* <YourOverlay />
|
|
56
|
+
* </VideoPlayer>
|
|
57
|
+
* ```
|
|
57
58
|
*/
|
|
58
|
-
export function VideoPlayer({
|
|
59
|
+
export function VideoPlayer({ controls = false, children, className = '', videoClassName = '', cuePoints = [], onCuePoint, onTimeUpdate, }) {
|
|
59
60
|
const videoRef = useRef(null);
|
|
60
61
|
const hlsRef = useRef(null);
|
|
61
62
|
const triggeredCuePointsRef = useRef(new Set());
|
|
@@ -63,15 +64,11 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
|
|
|
63
64
|
// State for auto-fetched metadata
|
|
64
65
|
const [metadata, setMetadata] = useState(null);
|
|
65
66
|
const [metadataError, setMetadataError] = useState(null);
|
|
66
|
-
// Auto-fetch video metadata
|
|
67
|
+
// Auto-fetch video metadata from tile
|
|
67
68
|
useEffect(() => {
|
|
68
|
-
if (srcProp) {
|
|
69
|
-
// src provided directly, no need to fetch
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
69
|
const tileId = getTileId();
|
|
73
70
|
if (!tileId) {
|
|
74
|
-
setMetadataError('
|
|
71
|
+
setMetadataError('NEXT_PUBLIC_TILE_ID not set');
|
|
75
72
|
return;
|
|
76
73
|
}
|
|
77
74
|
fetchVideoMetadata(tileId).then((data) => {
|
|
@@ -87,14 +84,14 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
|
|
|
87
84
|
setMetadataError('Failed to fetch video metadata');
|
|
88
85
|
}
|
|
89
86
|
});
|
|
90
|
-
}, [
|
|
91
|
-
//
|
|
92
|
-
const src =
|
|
93
|
-
const autoplay =
|
|
94
|
-
const muted =
|
|
95
|
-
const poster =
|
|
96
|
-
//
|
|
97
|
-
const loop =
|
|
87
|
+
}, []);
|
|
88
|
+
// Get values from metadata
|
|
89
|
+
const src = metadata?.videoUrl || null;
|
|
90
|
+
const autoplay = metadata?.autoplay ?? true;
|
|
91
|
+
const muted = metadata?.muted ?? false;
|
|
92
|
+
const poster = metadata?.thumbnail || undefined;
|
|
93
|
+
// Default to loop enabled (videos almost always loop)
|
|
94
|
+
const loop = metadata?.loop ?? true;
|
|
98
95
|
const [state, setState] = useState({
|
|
99
96
|
isPlaying: false,
|
|
100
97
|
currentTime: 0,
|
|
@@ -344,7 +341,7 @@ export function VideoPlayer({ src: srcProp, autoplay: autoplayProp, loop: loopPr
|
|
|
344
341
|
display: none !important;
|
|
345
342
|
}
|
|
346
343
|
`),
|
|
347
|
-
state.isLoading && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center" },
|
|
344
|
+
(state.isLoading || (!src && !metadataError)) && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center" },
|
|
348
345
|
React.createElement("div", { className: "w-10 h-10 border-3 border-white/30 border-t-white rounded-full animate-spin" }))),
|
|
349
346
|
(state.error || metadataError) && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center text-white/80" },
|
|
350
347
|
React.createElement("p", null, state.error || metadataError))),
|