stormcloud-video-player 0.1.8 β†’ 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 CHANGED
@@ -1,263 +1,291 @@
1
- ## stormcloud-video-player
1
+ # Stormcloud Video Player
2
2
 
3
- Ad-first HLS player module for the web with tight ad break alignment. It uses the HTML5 video element with hls.js, parses SCTE-35 signals from HLS tags and ID3 timed metadata, and integrates Google IMA for VAST/VPAID ad playback.
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
- ### Key goals
5
+ ## 🎯 Key Features
6
6
 
7
- - Precise ad start alignment on SCTE-35 CUE-OUT
8
- - Mid-ad join synchronization (play remaining portion if you tune in late)
9
- - Flexible fallback for feeds without SCTE-35 via external schedules
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
- ### Features (current)
14
+ ## πŸš€ Quick Start
12
15
 
13
- - HLS playback via hls.js with native HLS fallback
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
- This library targets modern browsers (ES2020) and expects a DOM environment.
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 MyApp() {
28
+ function MyVideoApp() {
66
29
  return (
67
30
  <StormcloudVideoPlayerComponent
68
- src="https://example.com/live/playlist.m3u8"
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: "640px", height: "360px" }}
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:", player);
38
+ console.log("Player is ready!", player);
87
39
  }}
88
40
  />
89
41
  );
90
42
  }
91
43
  ```
92
44
 
93
- ### Vanilla JavaScript Usage
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
- <div id="player" style="position:relative;width:640px;height:360px;">
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
- const video = document.getElementById("video");
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://example.com/live/playlist.m3u8",
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
- ## API
86
+ ### StormcloudVideoPlayer Class
133
87
 
134
- ### Class: `StormcloudVideoPlayer`
88
+ #### Constructor
135
89
 
136
- ```ts
90
+ ```typescript
137
91
  new StormcloudVideoPlayer(config: StormcloudVideoPlayerConfig)
138
92
  ```
139
93
 
140
- - `load(): Promise<void>`: Attach and start playback for the configured source
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`
145
- - `toggleMute(): void`: Toggle video mute state
146
- - `toggleFullscreen(): Promise<void>`: Toggle fullscreen mode
147
- - `isMuted(): boolean`: Check if video is currently muted
148
- - `isFullscreen(): boolean`: Check if video is currently in fullscreen
149
-
150
- ### Types
151
-
152
- ```ts
153
- type LateJoinPolicy = "play_remaining" | "skip_to_content";
154
-
155
- interface AdBreak {
156
- id?: string;
157
- startTimeMs: number;
158
- durationMs?: number;
159
- vastTagUrl?: string;
160
- }
94
+ #### Methods
161
95
 
162
- interface AdSchedule {
163
- breaks: AdBreak[];
164
- lateJoinPolicy?: LateJoinPolicy;
165
- }
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>` |
105
+
106
+ #### Configuration Options
166
107
 
108
+ ```typescript
167
109
  interface StormcloudVideoPlayerConfig {
168
- videoElement: HTMLVideoElement;
169
- src: string;
170
- autoplay?: boolean;
171
- muted?: boolean;
172
- allowNativeHls?: boolean;
173
- adSchedule?: AdSchedule;
174
- defaultVastTagUrl?: string;
175
- licenseKey?: string;
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)
176
118
  }
177
119
  ```
178
120
 
179
- ---
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
180
131
 
181
- ## License Key Authentication
132
+ ### Supported HLS Tags
182
133
 
183
- The player supports license key authentication for API calls. When a `licenseKey` is provided, it will be included as a `Bearer` token in the `Authorization` header for all API requests to:
134
+ - `#EXT-X-CUE-OUT`
135
+ - `#EXT-X-CUE-OUT-CONT`
136
+ - `#EXT-X-CUE-IN`
137
+ - `#EXT-X-DATERANGE`
138
+ - ID3 timed metadata
184
139
 
185
- - Ad configuration endpoint: `https://adstorm.co/api-adstorm-dev/adstorm/ads/web`
186
- - Initial tracking: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track`
187
- - Heartbeat tracking: `https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat`
140
+ ### Late Join Behavior
188
141
 
189
- ### Usage
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:
190
150
 
191
151
  ```javascript
192
- // Vanilla JavaScript
193
152
  const player = new StormcloudVideoPlayer({
194
- videoElement: video,
195
- src: "https://example.com/stream.m3u8",
196
- licenseKey: "your_license_key_here" // Optional
153
+ // ... other config
154
+ licenseKey: "ADSTORM-YOUR-LICENSE-KEY-HERE",
197
155
  });
198
-
199
- // React Component
200
- <StormcloudVideoPlayerComponent
201
- src="https://example.com/stream.m3u8"
202
- licenseKey="your_license_key_here" // Optional
203
- />
204
156
  ```
205
157
 
206
- The license key is optional and the player will work without it, but some API features may be limited or unavailable.
158
+ Authenticated requests are sent to:
207
159
 
208
- ---
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`
209
163
 
210
- ## How ad alignment works
164
+ ## πŸ”§ Advanced Configuration
211
165
 
212
- - On `CUE-OUT`/`DATERANGE` start: request IMA ads and start playback immediately; if duration is known, a countdown is scheduled to auto-stop if `CUE-IN` is missing.
213
- - 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.
214
- - On `CUE-IN`: stop ads and resume content immediately.
215
- - Without markers: provide `adSchedule` or a `defaultVastTagUrl` to still serve ads based on wall-clock content time.
166
+ ### Custom Styling
216
167
 
217
- ---
168
+ ```css
169
+ .stormcloud-video-player {
170
+ width: 100%;
171
+ height: 100%;
172
+ background: #000;
173
+ }
218
174
 
219
- ## External schedules and Airy API
175
+ .stormcloud-video-player video {
176
+ width: 100%;
177
+ height: 100%;
178
+ object-fit: contain;
179
+ }
180
+ ```
220
181
 
221
- You can set an `AdSchedule` directly via `setAdSchedule` or load a JSON schedule from a URL with `loadAdScheduleFromUrl`. For Airy-like APIs (`https://api.airy.tv/api/v2.1.7/ads/web`), use `loadDefaultVastFromAiry(airyApiUrl, params)` to set the default VAST tag returned by the service.
182
+ ### Event Handling
222
183
 
223
- Note: Real-world APIs may require authentication or custom mapping from their JSON to `AdSchedule`. Add an adapter as needed before calling `setAdSchedule`.
184
+ ```javascript
185
+ player.on("adStart", (event) => {
186
+ console.log("Ad started:", event.ad);
187
+ });
224
188
 
225
- ---
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
+ ```
226
197
 
227
- ## Development
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
228
207
 
229
208
  ```bash
230
- npm run build # build ESM + CJS with types
231
- npm run dev # watch mode
232
- npm run clean # remove dist
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
233
214
  ```
234
215
 
235
- ---
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
+ ```
236
231
 
237
- ## Limitations
232
+ ## 🎯 Use Cases
238
233
 
239
- - This module targets browsers (DOM required). SSR/Node-only not supported.
240
- - SCTE-35 parsing relies on HLS tags and ID3 text; binary splice parsing is not implemented yet.
241
- - Multi-ad pod stitching and competitive separation are left to the ad server/IMA.
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
242
239
 
243
- ---
240
+ ## ⚠️ Known Limitations
244
241
 
245
- ## Roadmap / Remaining tasks
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
246
246
 
247
- - Robust SCTE-35 binary parsing (splice_info_section) and richer marker mapping
248
- - Stronger late-join logic: handle partial pods, skip-to-content policy
249
- - Low-Latency HLS (LL-HLS) tuning to reduce ad-start drift further
250
- - Better drift correction between PTS and wall-clock; tolerance config
251
- - Ad pod management: sequencing multiple ads per break if provided
252
- - UI overlays: optional countdown/"Ad" badge and simple debug HUD
253
- - Retry/backoff and error telemetry for both HLS and IMA flows
254
- - Analytics events (start/firstQuartile/midpoint/thirdQuartile/complete)
255
- - Example app and demo page with real streams and test tags
256
- - Type definitions for IMA surface (remove `any`) and stronger public types
257
- - CI, unit tests (ID3/daterange parsers), and integration tests
247
+ ## πŸ—ΊοΈ Roadmap
258
248
 
259
- ---
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
260
264
 
261
- ## License
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
+ ---
262
290
 
263
- MIT
291
+ Built with ❀️ by the Stormcloud team