@streamlayer/web-os 0.1.2 → 0.2.1
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 +230 -2
- package/lib/cjs/index.js +278 -1
- package/lib/es/index.js +43008 -7
- package/lib/index.d.ts +16 -1
- package/lib/style.css +1 -1
- package/package.json +18 -15
- package/lib/cjs/gamification-feature.js +0 -1
- package/lib/cjs/gamification-feature2.js +0 -1
- package/lib/cjs/index2.js +0 -94
- package/lib/es/gamification-feature.js +0 -4
- package/lib/es/gamification-feature2.js +0 -684
- package/lib/es/index2.js +0 -29826
package/README.md
CHANGED
|
@@ -1,3 +1,231 @@
|
|
|
1
|
-
#
|
|
1
|
+
# StreamLayerSDKTv Pause Ad Integration
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
> **Alpha Version**: This feature is currently in alpha. Expect potential instability, including occasional freezes.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
### 1. PAL SDK
|
|
8
|
+
|
|
9
|
+
Add the Google PAL SDK to your HTML `<head>`:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<script type="text/javascript" src="https://imasdk.googleapis.com/pal/sdkloader/pal.js"></script>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Spatial Navigation
|
|
16
|
+
|
|
17
|
+
This feature uses [@noriginmedia/norigin-spatial-navigation](https://github.com/nicetechnologies/norigin-spatial-navigation) with `shouldFocusDOMNode: true` mode for remote control support.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Integration
|
|
22
|
+
|
|
23
|
+
### Props
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Description |
|
|
26
|
+
|------|------|-------------|
|
|
27
|
+
| `showPauseAd` | `boolean` | Controls pause ad visibility. Set to `true` when video pauses. |
|
|
28
|
+
| `onRenderPauseAd` | `(params: { rendered: boolean }) => void` | Called when pause ad overlay renders. Use to hide your UI elements. |
|
|
29
|
+
| `onClosePauseAd` | `() => void` | Called when pause ad closes without resuming video (user dismissed overlay). |
|
|
30
|
+
| `videoPlayerController` | `VideoPlayerCallback` | Called when user resumes video via the pause ad overlay button. |
|
|
31
|
+
| `pauseAdVastUrl` | `Array<{ template: string; url: string }>` | VAST tag configuration. |
|
|
32
|
+
|
|
33
|
+
### pauseAdVastUrl Configuration
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
pauseAdVastUrl={[
|
|
37
|
+
{
|
|
38
|
+
template: 'default', // Currently only 'default' template is supported
|
|
39
|
+
url: 'https://your-vast-tag-url.com/vast.xml',
|
|
40
|
+
},
|
|
41
|
+
]}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> **Note**: Only the first item in the array is used. Multi-item rotation is not yet supported.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Understanding `showPauseAd` vs `pauseAdRendered`
|
|
49
|
+
|
|
50
|
+
These two flags serve different purposes and are controlled by different parties:
|
|
51
|
+
|
|
52
|
+
| Flag | Controlled By | Purpose |
|
|
53
|
+
|------|---------------|---------|
|
|
54
|
+
| `showPauseAd` | **You (integrator)** | Request to show/hide pause ad |
|
|
55
|
+
| `pauseAdRendered` | **SDK (via callback)** | Actual visibility state on screen |
|
|
56
|
+
|
|
57
|
+
### Why two flags?
|
|
58
|
+
|
|
59
|
+
**`showPauseAd`** is your *intent* — "I want the pause ad to appear/disappear."
|
|
60
|
+
|
|
61
|
+
**`pauseAdRendered`** is the *actual state* — "The pause ad is currently visible on screen."
|
|
62
|
+
|
|
63
|
+
These values don't always match due to **animation delays**:
|
|
64
|
+
|
|
65
|
+
- **Opening delay (5 seconds)**: SDK waits before showing the overlay
|
|
66
|
+
- **Closing delay (400ms)**: SDK animates the overlay before removing it
|
|
67
|
+
|
|
68
|
+
### State combinations
|
|
69
|
+
|
|
70
|
+
| `showPauseAd` | `pauseAdRendered` | State |
|
|
71
|
+
|---------------|-------------------|-------|
|
|
72
|
+
| `false` | `false` | Video playing or paused without ad |
|
|
73
|
+
| `true` | `false` | Video paused, SDK preparing overlay (5s delay) |
|
|
74
|
+
| `true` | `true` | Pause ad visible on screen |
|
|
75
|
+
| `false` | `true` | **Closing animation in progress (400ms)** |
|
|
76
|
+
|
|
77
|
+
### Timeline
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Video pauses
|
|
81
|
+
│
|
|
82
|
+
▼
|
|
83
|
+
showPauseAd = true ← You set this on video pause
|
|
84
|
+
pauseAdRendered = false
|
|
85
|
+
│
|
|
86
|
+
│ ← 5 second delay (SDK loads ad, prepares overlay)
|
|
87
|
+
▼
|
|
88
|
+
showPauseAd = true
|
|
89
|
+
pauseAdRendered = true ← SDK calls onRenderPauseAd({ rendered: true })
|
|
90
|
+
Hide your UI controls now
|
|
91
|
+
│
|
|
92
|
+
│ ← User resumes video or closes overlay
|
|
93
|
+
▼
|
|
94
|
+
showPauseAd = false ← You set this on play/close
|
|
95
|
+
pauseAdRendered = true ← Still true! Closing animation playing
|
|
96
|
+
│
|
|
97
|
+
│ ← 400ms closing animation
|
|
98
|
+
▼
|
|
99
|
+
showPauseAd = false
|
|
100
|
+
pauseAdRendered = false ← SDK calls onRenderPauseAd({ rendered: false })
|
|
101
|
+
Safe to show your UI controls
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Why this matters
|
|
105
|
+
|
|
106
|
+
Always use `pauseAdRendered` to control your UI visibility:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
// Correct: hide UI based on actual render state
|
|
110
|
+
const showControls = !pauseAdRendered
|
|
111
|
+
|
|
112
|
+
// This ensures:
|
|
113
|
+
// 1. Your controls don't disappear 5s before the ad appears
|
|
114
|
+
// 2. Your controls don't reappear during the 400ms closing animation
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If you used `showPauseAd` instead, your controls would:
|
|
118
|
+
- Disappear immediately on pause (5s before the ad shows)
|
|
119
|
+
- Reappear during the closing animation (overlapping with the ad)
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Implementation Example
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import { useState, useCallback, useRef } from 'react'
|
|
127
|
+
import { StreamLayerSDKTv, type VideoPlayerCallback } from '@streamlayer/sdk-web-os'
|
|
128
|
+
|
|
129
|
+
export const VideoView = () => {
|
|
130
|
+
const [showPauseAd, setShowPauseAd] = useState(false)
|
|
131
|
+
const [pauseAdRendered, setPauseAdRendered] = useState(false)
|
|
132
|
+
const videoRef = useRef<HTMLVideoElement>(null)
|
|
133
|
+
|
|
134
|
+
// Called when pause ad overlay renders/hides
|
|
135
|
+
const onRenderPauseAd = useCallback((params: { rendered: boolean }) => {
|
|
136
|
+
setPauseAdRendered(params.rendered)
|
|
137
|
+
}, [])
|
|
138
|
+
|
|
139
|
+
// Called when pause ad closes without video resumption
|
|
140
|
+
const onClosePauseAd = useCallback(() => {
|
|
141
|
+
setShowPauseAd(false)
|
|
142
|
+
}, [])
|
|
143
|
+
|
|
144
|
+
// Called when user clicks resume on pause ad overlay
|
|
145
|
+
const videoPlayerController: VideoPlayerCallback = useCallback((data) => {
|
|
146
|
+
if (data.play === true) {
|
|
147
|
+
videoRef.current?.play()
|
|
148
|
+
}
|
|
149
|
+
}, [])
|
|
150
|
+
|
|
151
|
+
// Video event handlers
|
|
152
|
+
const onVideoPause = useCallback(() => {
|
|
153
|
+
setShowPauseAd(true)
|
|
154
|
+
}, [])
|
|
155
|
+
|
|
156
|
+
const onVideoPlay = useCallback(() => {
|
|
157
|
+
setShowPauseAd(false)
|
|
158
|
+
}, [])
|
|
159
|
+
|
|
160
|
+
// Hide your UI controls when pause ad is rendered
|
|
161
|
+
const showControls = !pauseAdRendered
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<StreamLayerSDKTv
|
|
165
|
+
showPauseAd={showPauseAd}
|
|
166
|
+
onRenderPauseAd={onRenderPauseAd}
|
|
167
|
+
onClosePauseAd={onClosePauseAd}
|
|
168
|
+
videoPlayerController={videoPlayerController}
|
|
169
|
+
pauseAdVastUrl={[
|
|
170
|
+
{
|
|
171
|
+
template: 'default',
|
|
172
|
+
url: 'https://your-vast-tag-url.com',
|
|
173
|
+
},
|
|
174
|
+
]}
|
|
175
|
+
>
|
|
176
|
+
{/* Your video container */}
|
|
177
|
+
<div>
|
|
178
|
+
<video
|
|
179
|
+
ref={videoRef}
|
|
180
|
+
onPause={onVideoPause}
|
|
181
|
+
onPlay={onVideoPlay}
|
|
182
|
+
/>
|
|
183
|
+
|
|
184
|
+
{/* Hide controls when pause ad is displayed */}
|
|
185
|
+
{showControls && (
|
|
186
|
+
<div className="video-controls">
|
|
187
|
+
{/* Play button, timeline, etc. */}
|
|
188
|
+
</div>
|
|
189
|
+
)}
|
|
190
|
+
</div>
|
|
191
|
+
</StreamLayerSDKTv>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Lifecycle Flow
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
Video Pauses
|
|
202
|
+
│
|
|
203
|
+
▼
|
|
204
|
+
setShowPauseAd(true) ──► StreamLayerSDKTv receives showPauseAd=true
|
|
205
|
+
│
|
|
206
|
+
▼
|
|
207
|
+
onRenderPauseAd({ rendered: true })
|
|
208
|
+
│
|
|
209
|
+
▼
|
|
210
|
+
Hide your UI (controls, timeline, etc.)
|
|
211
|
+
│
|
|
212
|
+
┌───────────────────────┴───────────────────────┐
|
|
213
|
+
▼ ▼
|
|
214
|
+
User clicks RESUME User closes overlay
|
|
215
|
+
│ │
|
|
216
|
+
▼ ▼
|
|
217
|
+
videoPlayerController({ play: true }) onClosePauseAd()
|
|
218
|
+
│ │
|
|
219
|
+
▼ ▼
|
|
220
|
+
Resume video playback setShowPauseAd(false)
|
|
221
|
+
setShowPauseAd(false) (video stays paused)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Key Points
|
|
227
|
+
|
|
228
|
+
1. **You control `showPauseAd`**: Set it to `true` on video pause, `false` on play/resume.
|
|
229
|
+
2. **Hide UI on render**: When `onRenderPauseAd` fires with `rendered: true`, hide your video controls (play button, timeline, etc.).
|
|
230
|
+
3. **Handle both exit paths**: User can either resume video (via `videoPlayerController`) or dismiss the overlay (via `onClosePauseAd`).
|
|
231
|
+
4. **Single VAST tag**: Only one item in `pauseAdVastUrl` is processed; additional items are ignored.
|