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 CHANGED
@@ -1,259 +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`
94
+ #### Methods
145
95
 
146
- ### Types
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
- ```ts
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
- adSchedule?: AdSchedule;
170
- defaultVastTagUrl?: string;
171
- 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)
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
- ## License Key Authentication
132
+ ### Supported HLS Tags
178
133
 
179
- 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
180
139
 
181
- - Ad configuration endpoint: `https://adstorm.co/api-adstorm-dev/adstorm/ads/web`
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
- ### 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:
186
150
 
187
151
  ```javascript
188
- // Vanilla JavaScript
189
152
  const player = new StormcloudVideoPlayer({
190
- videoElement: video,
191
- src: "https://example.com/stream.m3u8",
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
- 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:
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
- ## How ad alignment works
164
+ ## πŸ”§ Advanced Configuration
207
165
 
208
- - 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.
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
- ## External schedules and Airy API
175
+ .stormcloud-video-player video {
176
+ width: 100%;
177
+ height: 100%;
178
+ object-fit: contain;
179
+ }
180
+ ```
216
181
 
217
- 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
218
183
 
219
- 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
+ });
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
- ## 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
224
207
 
225
208
  ```bash
226
- npm run build # build ESM + CJS with types
227
- npm run dev # watch mode
228
- 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
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
- ## Limitations
232
+ ## 🎯 Use Cases
234
233
 
235
- - This module targets browsers (DOM required). SSR/Node-only not supported.
236
- - SCTE-35 parsing relies on HLS tags and ID3 text; binary splice parsing is not implemented yet.
237
- - 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
238
239
 
239
- ---
240
+ ## ⚠️ Known Limitations
240
241
 
241
- ## 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
242
246
 
243
- - Robust SCTE-35 binary parsing (splice_info_section) and richer marker mapping
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
- ## 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
+ ---
258
290
 
259
- MIT
291
+ Built with ❀️ by the Stormcloud team