stormcloud-video-player 0.1.7 β 0.1.9
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 +205 -173
- package/dist/stormcloud-vp.min.js +3 -3
- package/lib/index.cjs +718 -306
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +7 -5
- package/lib/index.d.ts +7 -5
- package/lib/index.js +719 -307
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,259 +1,291 @@
|
|
|
1
|
-
|
|
1
|
+
# Stormcloud Video Player
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A professional HLS video player with advanced ad integration for web applications. Built with precision ad break alignment, SCTE-35 signal parsing, and Google IMA SDK integration for seamless VAST/VPAID ad playback.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## π― Key Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- Mid-
|
|
9
|
-
- Flexible
|
|
7
|
+
- **Precision Ad Alignment**: Tight synchronization with SCTE-35 CUE-OUT signals
|
|
8
|
+
- **Smart Mid-Roll Handling**: Automatic detection and playback of remaining ad portions when joining late
|
|
9
|
+
- **Flexible Ad Scheduling**: Support for both SCTE-35 markers and external ad schedules
|
|
10
|
+
- **Cross-Platform**: Works on desktop, mobile, tablets, and smart TVs
|
|
11
|
+
- **React Ready**: Includes React component for easy integration
|
|
12
|
+
- **TypeScript Support**: Full type definitions included
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
## π Quick Start
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
- SCTE-35 parsing from HLS tags: `#EXT-X-CUE-OUT`, `#EXT-X-CUE-OUT-CONT`, `#EXT-X-CUE-IN`, `#EXT-X-DATERANGE`
|
|
15
|
-
- SCTE-35/markers parsing from ID3 text payloads
|
|
16
|
-
- IMA SDK integration with pause/resume/error handling
|
|
17
|
-
- Remaining-duration countdown and auto-stop when CUE-IN is absent
|
|
18
|
-
- External schedule ingestion helpers and default VAST tag support
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Install
|
|
16
|
+
### Installation
|
|
23
17
|
|
|
24
18
|
```bash
|
|
25
19
|
npm install stormcloud-video-player hls.js
|
|
26
20
|
```
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### CDN Usage
|
|
31
|
-
|
|
32
|
-
You can also use the library directly from CDN without npm:
|
|
33
|
-
|
|
34
|
-
```html
|
|
35
|
-
<!-- Use latest version (recommended for development) -->
|
|
36
|
-
<script src="https://cdn.jsdelivr.net/npm/stormcloud-video-player/dist/stormcloud-vp.min.js"></script>
|
|
37
|
-
|
|
38
|
-
<script>
|
|
39
|
-
// The library is available as window.StormcloudVideoPlayer
|
|
40
|
-
const { StormcloudVideoPlayer } = window.StormcloudVideoPlayer;
|
|
41
|
-
|
|
42
|
-
const video = document.getElementById("video");
|
|
43
|
-
const player = new StormcloudVideoPlayer({
|
|
44
|
-
videoElement: video,
|
|
45
|
-
src: "https://example.com/live/playlist.m3u8",
|
|
46
|
-
autoplay: true,
|
|
47
|
-
muted: true,
|
|
48
|
-
allowNativeHls: false,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
player.load();
|
|
52
|
-
</script>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Quick start
|
|
58
|
-
|
|
59
|
-
### React Usage
|
|
22
|
+
### React Integration
|
|
60
23
|
|
|
61
24
|
```jsx
|
|
62
25
|
import React from "react";
|
|
63
26
|
import { StormcloudVideoPlayerComponent } from "stormcloud-video-player";
|
|
64
27
|
|
|
65
|
-
function
|
|
28
|
+
function MyVideoApp() {
|
|
66
29
|
return (
|
|
67
30
|
<StormcloudVideoPlayerComponent
|
|
68
|
-
src="https://
|
|
31
|
+
src="https://your-stream.com/playlist.m3u8"
|
|
69
32
|
autoplay={true}
|
|
70
33
|
muted={true}
|
|
71
|
-
allowNativeHls={false}
|
|
72
34
|
controls={true}
|
|
73
35
|
licenseKey="your_license_key_here"
|
|
74
|
-
style={{ width: "
|
|
75
|
-
adSchedule={{
|
|
76
|
-
lateJoinPolicy: "play_remaining",
|
|
77
|
-
breaks: [
|
|
78
|
-
{
|
|
79
|
-
startTimeMs: 60_000,
|
|
80
|
-
durationMs: 120_000,
|
|
81
|
-
vastTagUrl: "https://...",
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
}}
|
|
36
|
+
style={{ width: "100%", aspectRatio: "16/9" }}
|
|
85
37
|
onReady={(player) => {
|
|
86
|
-
console.log("Player ready
|
|
38
|
+
console.log("Player is ready!", player);
|
|
87
39
|
}}
|
|
88
40
|
/>
|
|
89
41
|
);
|
|
90
42
|
}
|
|
91
43
|
```
|
|
92
44
|
|
|
93
|
-
### Vanilla JavaScript
|
|
45
|
+
### Vanilla JavaScript
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
import { StormcloudVideoPlayer } from "stormcloud-video-player";
|
|
49
|
+
|
|
50
|
+
const video = document.getElementById("my-video");
|
|
51
|
+
|
|
52
|
+
const player = new StormcloudVideoPlayer({
|
|
53
|
+
videoElement: video,
|
|
54
|
+
src: "https://your-stream.com/playlist.m3u8",
|
|
55
|
+
autoplay: true,
|
|
56
|
+
muted: true,
|
|
57
|
+
allowNativeHls: false,
|
|
58
|
+
licenseKey: "your_license_key_here",
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await player.load();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### CDN Usage
|
|
94
65
|
|
|
95
66
|
```html
|
|
96
|
-
<
|
|
97
|
-
<video
|
|
98
|
-
id="video"
|
|
99
|
-
playsinline
|
|
100
|
-
muted
|
|
101
|
-
controls
|
|
102
|
-
style="width:100%;height:100%;"
|
|
103
|
-
></video>
|
|
104
|
-
</div>
|
|
105
|
-
<script type="module">
|
|
106
|
-
import { StormcloudVideoPlayer } from "stormcloud-video-player";
|
|
67
|
+
<script src="https://cdn.jsdelivr.net/npm/stormcloud-video-player/dist/stormcloud-vp.min.js"></script>
|
|
107
68
|
|
|
108
|
-
|
|
69
|
+
<script>
|
|
70
|
+
const { StormcloudVideoPlayer } = window.StormcloudVideoPlayer;
|
|
109
71
|
|
|
72
|
+
const video = document.getElementById("video");
|
|
110
73
|
const player = new StormcloudVideoPlayer({
|
|
111
74
|
videoElement: video,
|
|
112
|
-
src: "https://
|
|
75
|
+
src: "https://your-stream.com/playlist.m3u8",
|
|
113
76
|
autoplay: true,
|
|
114
77
|
muted: true,
|
|
115
|
-
allowNativeHls: false,
|
|
116
|
-
licenseKey: "your_license_key_here", // Optional
|
|
117
|
-
// Optional external ad schedule
|
|
118
|
-
adSchedule: {
|
|
119
|
-
lateJoinPolicy: "play_remaining",
|
|
120
|
-
breaks: [
|
|
121
|
-
{ startTimeMs: 60_000, durationMs: 120_000, vastTagUrl: "https://..." },
|
|
122
|
-
],
|
|
123
|
-
},
|
|
124
78
|
});
|
|
125
79
|
|
|
126
80
|
player.load();
|
|
127
81
|
</script>
|
|
128
82
|
```
|
|
129
83
|
|
|
130
|
-
|
|
84
|
+
## π API Reference
|
|
131
85
|
|
|
132
|
-
|
|
86
|
+
### StormcloudVideoPlayer Class
|
|
133
87
|
|
|
134
|
-
|
|
88
|
+
#### Constructor
|
|
135
89
|
|
|
136
|
-
```
|
|
90
|
+
```typescript
|
|
137
91
|
new StormcloudVideoPlayer(config: StormcloudVideoPlayerConfig)
|
|
138
92
|
```
|
|
139
93
|
|
|
140
|
-
|
|
141
|
-
- `destroy(): void`: Cleanup player and ad resources
|
|
142
|
-
- `setAdSchedule(schedule?: AdSchedule): void`: Provide/replace ad schedule
|
|
143
|
-
- `loadAdScheduleFromUrl(url: string): Promise<void>`: Fetch and set JSON schedule
|
|
144
|
-
- `loadDefaultVastFromAiry(url: string, params?: Record<string, string>): Promise<void>`: Fetch ad tag from Airy-like API and set `defaultVastTagUrl`
|
|
94
|
+
#### Methods
|
|
145
95
|
|
|
146
|
-
|
|
96
|
+
| Method | Description | Returns |
|
|
97
|
+
| ------------------------------------------ | --------------------------------------------- | --------------- |
|
|
98
|
+
| `load()` | Initialize and start video playback | `Promise<void>` |
|
|
99
|
+
| `destroy()` | Clean up player resources and event listeners | `void` |
|
|
100
|
+
| `toggleMute()` | Toggle video mute state | `void` |
|
|
101
|
+
| `toggleFullscreen()` | Enter/exit fullscreen mode | `Promise<void>` |
|
|
102
|
+
| `isMuted()` | Check if video is currently muted | `boolean` |
|
|
103
|
+
| `isFullscreen()` | Check if player is in fullscreen mode | `boolean` |
|
|
104
|
+
| `loadDefaultVastFromAdstorm(url, params?)` | Load VAST tags from Adstorm API | `Promise<void>` |
|
|
147
105
|
|
|
148
|
-
|
|
149
|
-
type LateJoinPolicy = "play_remaining" | "skip_to_content";
|
|
150
|
-
|
|
151
|
-
interface AdBreak {
|
|
152
|
-
id?: string;
|
|
153
|
-
startTimeMs: number;
|
|
154
|
-
durationMs?: number;
|
|
155
|
-
vastTagUrl?: string;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
interface AdSchedule {
|
|
159
|
-
breaks: AdBreak[];
|
|
160
|
-
lateJoinPolicy?: LateJoinPolicy;
|
|
161
|
-
}
|
|
106
|
+
#### Configuration Options
|
|
162
107
|
|
|
108
|
+
```typescript
|
|
163
109
|
interface StormcloudVideoPlayerConfig {
|
|
164
|
-
videoElement: HTMLVideoElement;
|
|
165
|
-
src: string;
|
|
166
|
-
autoplay?: boolean;
|
|
167
|
-
muted?: boolean;
|
|
168
|
-
allowNativeHls?: boolean;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
110
|
+
videoElement: HTMLVideoElement; // Target video element
|
|
111
|
+
src: string; // HLS stream URL
|
|
112
|
+
autoplay?: boolean; // Auto-start playback (default: false)
|
|
113
|
+
muted?: boolean; // Start muted (default: false)
|
|
114
|
+
allowNativeHls?: boolean; // Use native HLS when available (default: true)
|
|
115
|
+
licenseKey?: string; // API authentication key
|
|
116
|
+
debugAdTiming?: boolean; // Enable debug logging (default: false)
|
|
117
|
+
adFailsafeTimeoutMs?: number; // Ad timeout in milliseconds (default: 10000)
|
|
172
118
|
}
|
|
173
119
|
```
|
|
174
120
|
|
|
175
|
-
|
|
121
|
+
## π¬ Ad Integration
|
|
122
|
+
|
|
123
|
+
### SCTE-35 Support
|
|
124
|
+
|
|
125
|
+
The player automatically detects and responds to SCTE-35 signals embedded in HLS streams:
|
|
126
|
+
|
|
127
|
+
- **CUE-OUT**: Triggers ad break start
|
|
128
|
+
- **CUE-OUT-CONT**: Handles mid-roll continuation
|
|
129
|
+
- **CUE-IN**: Resumes content playback
|
|
130
|
+
- **DATERANGE**: Processes time-based ad markers
|
|
176
131
|
|
|
177
|
-
|
|
132
|
+
### Supported HLS Tags
|
|
178
133
|
|
|
179
|
-
|
|
134
|
+
- `#EXT-X-CUE-OUT`
|
|
135
|
+
- `#EXT-X-CUE-OUT-CONT`
|
|
136
|
+
- `#EXT-X-CUE-IN`
|
|
137
|
+
- `#EXT-X-DATERANGE`
|
|
138
|
+
- ID3 timed metadata
|
|
180
139
|
|
|
181
|
-
|
|
182
|
-
- Initial tracking: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track`
|
|
183
|
-
- Heartbeat tracking: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat`
|
|
140
|
+
### Late Join Behavior
|
|
184
141
|
|
|
185
|
-
|
|
142
|
+
When viewers join during an ad break:
|
|
143
|
+
|
|
144
|
+
- **play_remaining**: Plays the remaining portion of the current ad
|
|
145
|
+
- **skip_to_content**: Skips to main content (configurable via API)
|
|
146
|
+
|
|
147
|
+
## π Authentication
|
|
148
|
+
|
|
149
|
+
The player supports license key authentication for enhanced features:
|
|
186
150
|
|
|
187
151
|
```javascript
|
|
188
|
-
// Vanilla JavaScript
|
|
189
152
|
const player = new StormcloudVideoPlayer({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
licenseKey: "your_license_key_here" // Optional
|
|
153
|
+
// ... other config
|
|
154
|
+
licenseKey: "ADSTORM-YOUR-LICENSE-KEY-HERE",
|
|
193
155
|
});
|
|
194
|
-
|
|
195
|
-
// React Component
|
|
196
|
-
<StormcloudVideoPlayerComponent
|
|
197
|
-
src="https://example.com/stream.m3u8"
|
|
198
|
-
licenseKey="your_license_key_here" // Optional
|
|
199
|
-
/>
|
|
200
156
|
```
|
|
201
157
|
|
|
202
|
-
|
|
158
|
+
Authenticated requests are sent to:
|
|
203
159
|
|
|
204
|
-
|
|
160
|
+
- Ad configuration: `https://adstorm.co/api-adstorm-dev/adstorm/ads/web`
|
|
161
|
+
- Player tracking: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track`
|
|
162
|
+
- Heartbeat monitoring: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat`
|
|
205
163
|
|
|
206
|
-
##
|
|
164
|
+
## π§ Advanced Configuration
|
|
207
165
|
|
|
208
|
-
|
|
209
|
-
- On `CUE-OUT-CONT` (progress): if not already playing, and policy is `play_remaining`, request ads and start; countdown is updated based on elapsed/duration.
|
|
210
|
-
- On `CUE-IN`: stop ads and resume content immediately.
|
|
211
|
-
- Without markers: provide `adSchedule` or a `defaultVastTagUrl` to still serve ads based on wall-clock content time.
|
|
166
|
+
### Custom Styling
|
|
212
167
|
|
|
213
|
-
|
|
168
|
+
```css
|
|
169
|
+
.stormcloud-video-player {
|
|
170
|
+
width: 100%;
|
|
171
|
+
height: 100%;
|
|
172
|
+
background: #000;
|
|
173
|
+
}
|
|
214
174
|
|
|
215
|
-
|
|
175
|
+
.stormcloud-video-player video {
|
|
176
|
+
width: 100%;
|
|
177
|
+
height: 100%;
|
|
178
|
+
object-fit: contain;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
216
181
|
|
|
217
|
-
|
|
182
|
+
### Event Handling
|
|
218
183
|
|
|
219
|
-
|
|
184
|
+
```javascript
|
|
185
|
+
player.on("adStart", (event) => {
|
|
186
|
+
console.log("Ad started:", event.ad);
|
|
187
|
+
});
|
|
220
188
|
|
|
221
|
-
|
|
189
|
+
player.on("adComplete", (event) => {
|
|
190
|
+
console.log("Ad completed:", event.ad);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
player.on("contentResumed", () => {
|
|
194
|
+
console.log("Content playback resumed");
|
|
195
|
+
});
|
|
196
|
+
```
|
|
222
197
|
|
|
223
|
-
##
|
|
198
|
+
## π Browser Support
|
|
199
|
+
|
|
200
|
+
- **Desktop**: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
|
|
201
|
+
- **Mobile**: iOS Safari 12+, Chrome Mobile 60+
|
|
202
|
+
- **Smart TV**: WebOS, Tizen, Android TV, Roku, Apple TV
|
|
203
|
+
|
|
204
|
+
## ποΈ Development
|
|
205
|
+
|
|
206
|
+
### Build Commands
|
|
224
207
|
|
|
225
208
|
```bash
|
|
226
|
-
npm run build
|
|
227
|
-
npm run dev
|
|
228
|
-
npm run clean
|
|
209
|
+
npm run build # Build production bundle
|
|
210
|
+
npm run dev # Development watch mode
|
|
211
|
+
npm run clean # Clean build artifacts
|
|
212
|
+
npm run test # Run test suite
|
|
213
|
+
npm run lint # Lint codebase
|
|
229
214
|
```
|
|
230
215
|
|
|
231
|
-
|
|
216
|
+
### Project Structure
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
src/
|
|
220
|
+
βββ index.ts # Main exports
|
|
221
|
+
βββ player/
|
|
222
|
+
β βββ StormcloudVideoPlayer.ts # Core player class
|
|
223
|
+
βββ ui/
|
|
224
|
+
β βββ StormcloudVideoPlayer.tsx # React component
|
|
225
|
+
βββ sdk/
|
|
226
|
+
β βββ ima.ts # Google IMA integration
|
|
227
|
+
βββ utils/
|
|
228
|
+
β βββ tracking.ts # Analytics and tracking
|
|
229
|
+
βββ types.ts # TypeScript definitions
|
|
230
|
+
```
|
|
232
231
|
|
|
233
|
-
##
|
|
232
|
+
## π― Use Cases
|
|
234
233
|
|
|
235
|
-
-
|
|
236
|
-
-
|
|
237
|
-
-
|
|
234
|
+
- **Live Streaming**: Sports, news, and event broadcasts
|
|
235
|
+
- **VOD Platforms**: Movie and series streaming services
|
|
236
|
+
- **Educational Content**: E-learning and training platforms
|
|
237
|
+
- **Corporate Communications**: Internal and external video content
|
|
238
|
+
- **Digital Signage**: Retail and public display systems
|
|
238
239
|
|
|
239
|
-
|
|
240
|
+
## β οΈ Known Limitations
|
|
240
241
|
|
|
241
|
-
|
|
242
|
+
- Requires DOM environment (browser-only)
|
|
243
|
+
- SCTE-35 binary splice parsing not yet implemented
|
|
244
|
+
- Multi-ad pod competitive separation handled by ad server
|
|
245
|
+
- Low-latency HLS (LL-HLS) optimizations in development
|
|
242
246
|
|
|
243
|
-
|
|
244
|
-
- Stronger late-join logic: handle partial pods, skip-to-content policy
|
|
245
|
-
- Low-Latency HLS (LL-HLS) tuning to reduce ad-start drift further
|
|
246
|
-
- Better drift correction between PTS and wall-clock; tolerance config
|
|
247
|
-
- Ad pod management: sequencing multiple ads per break if provided
|
|
248
|
-
- UI overlays: optional countdown/"Ad" badge and simple debug HUD
|
|
249
|
-
- Retry/backoff and error telemetry for both HLS and IMA flows
|
|
250
|
-
- Analytics events (start/firstQuartile/midpoint/thirdQuartile/complete)
|
|
251
|
-
- Example app and demo page with real streams and test tags
|
|
252
|
-
- Type definitions for IMA surface (remove `any`) and stronger public types
|
|
253
|
-
- CI, unit tests (ID3/daterange parsers), and integration tests
|
|
247
|
+
## πΊοΈ Roadmap
|
|
254
248
|
|
|
255
|
-
|
|
249
|
+
### Upcoming Features
|
|
250
|
+
|
|
251
|
+
- **Enhanced SCTE-35**: Full binary splice_info_section parsing
|
|
252
|
+
- **Advanced Late Join**: Improved partial pod handling
|
|
253
|
+
- **LL-HLS Support**: Low-latency streaming optimizations
|
|
254
|
+
- **Rich Analytics**: Comprehensive event tracking and reporting
|
|
255
|
+
- **UI Components**: Built-in countdown timers and ad indicators
|
|
256
|
+
- **Error Recovery**: Advanced retry logic and failover handling
|
|
257
|
+
|
|
258
|
+
### Performance Improvements
|
|
259
|
+
|
|
260
|
+
- Drift correction between PTS and wall-clock timing
|
|
261
|
+
- Memory optimization for long-running sessions
|
|
262
|
+
- Network bandwidth adaptation
|
|
263
|
+
- Smart preloading strategies
|
|
256
264
|
|
|
257
|
-
##
|
|
265
|
+
## π€ Contributing
|
|
266
|
+
|
|
267
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
268
|
+
|
|
269
|
+
### Development Setup
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
git clone https://github.com/your-org/stormcloud-video-player.git
|
|
273
|
+
cd stormcloud-video-player
|
|
274
|
+
npm install
|
|
275
|
+
npm run dev
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## π License
|
|
279
|
+
|
|
280
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
281
|
+
|
|
282
|
+
## π Support
|
|
283
|
+
|
|
284
|
+
- **Documentation**: [Full API Docs](https://docs.stormcloud.tv)
|
|
285
|
+
- **Issues**: [GitHub Issues](https://github.com/your-org/stormcloud-video-player/issues)
|
|
286
|
+
- **Discord**: [Community Chat](https://discord.gg/stormcloud)
|
|
287
|
+
- **Email**: support@stormcloud.tv
|
|
288
|
+
|
|
289
|
+
---
|
|
258
290
|
|
|
259
|
-
|
|
291
|
+
Built with β€οΈ by the Stormcloud team
|