stormcloud-video-player 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [2025] [Showfer Media LLC]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ ## stormcloud-video-player
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.
4
+
5
+ ### Key goals
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
10
+
11
+ ### Features (current)
12
+
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
23
+
24
+ ```bash
25
+ npm install stormcloud-video-player hls.js
26
+ ```
27
+
28
+ This library targets modern browsers (ES2020) and expects a DOM environment.
29
+
30
+ ---
31
+
32
+ ## Quick start
33
+
34
+ ### React Usage
35
+
36
+ ```jsx
37
+ import React from "react";
38
+ import { StormcloudVideoPlayerComponent } from "stormcloud-video-player";
39
+
40
+ function MyApp() {
41
+ return (
42
+ <StormcloudVideoPlayerComponent
43
+ src="https://example.com/live/playlist.m3u8"
44
+ autoplay={true}
45
+ muted={true}
46
+ allowNativeHls={false}
47
+ controls={true}
48
+ style={{ width: "640px", height: "360px" }}
49
+ adSchedule={{
50
+ lateJoinPolicy: "play_remaining",
51
+ breaks: [
52
+ {
53
+ startTimeMs: 60_000,
54
+ durationMs: 120_000,
55
+ vastTagUrl: "https://...",
56
+ },
57
+ ],
58
+ }}
59
+ onReady={(player) => {
60
+ console.log("Player ready:", player);
61
+ }}
62
+ />
63
+ );
64
+ }
65
+ ```
66
+
67
+ ### Vanilla JavaScript Usage
68
+
69
+ ```html
70
+ <div id="player" style="position:relative;width:640px;height:360px;">
71
+ <video
72
+ id="video"
73
+ playsinline
74
+ muted
75
+ controls
76
+ style="width:100%;height:100%;"
77
+ ></video>
78
+ </div>
79
+ <script type="module">
80
+ import { StormcloudVideoPlayer } from "stormcloud-video-player";
81
+
82
+ const video = document.getElementById("video");
83
+
84
+ const player = new StormcloudVideoPlayer({
85
+ videoElement: video,
86
+ src: "https://example.com/live/playlist.m3u8",
87
+ autoplay: true,
88
+ muted: true,
89
+ allowNativeHls: false,
90
+ // Optional external ad schedule
91
+ adSchedule: {
92
+ lateJoinPolicy: "play_remaining",
93
+ breaks: [
94
+ { startTimeMs: 60_000, durationMs: 120_000, vastTagUrl: "https://..." },
95
+ ],
96
+ },
97
+ });
98
+
99
+ player.load();
100
+ </script>
101
+ ```
102
+
103
+ ---
104
+
105
+ ## API
106
+
107
+ ### Class: `StormcloudVideoPlayer`
108
+
109
+ ```ts
110
+ new StormcloudVideoPlayer(config: StormcloudVideoPlayerConfig)
111
+ ```
112
+
113
+ - `load(): Promise<void>`: Attach and start playback for the configured source
114
+ - `destroy(): void`: Cleanup player and ad resources
115
+ - `setAdSchedule(schedule?: AdSchedule): void`: Provide/replace ad schedule
116
+ - `loadAdScheduleFromUrl(url: string): Promise<void>`: Fetch and set JSON schedule
117
+ - `loadDefaultVastFromAiry(url: string, params?: Record<string, string>): Promise<void>`: Fetch ad tag from Airy-like API and set `defaultVastTagUrl`
118
+
119
+ ### Types
120
+
121
+ ```ts
122
+ type LateJoinPolicy = "play_remaining" | "skip_to_content";
123
+
124
+ interface AdBreak {
125
+ id?: string;
126
+ startTimeMs: number;
127
+ durationMs?: number;
128
+ vastTagUrl?: string;
129
+ }
130
+
131
+ interface AdSchedule {
132
+ breaks: AdBreak[];
133
+ lateJoinPolicy?: LateJoinPolicy;
134
+ }
135
+
136
+ interface StormcloudVideoPlayerConfig {
137
+ videoElement: HTMLVideoElement;
138
+ src: string;
139
+ autoplay?: boolean;
140
+ muted?: boolean;
141
+ allowNativeHls?: boolean;
142
+ adSchedule?: AdSchedule;
143
+ defaultVastTagUrl?: string;
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ ## How ad alignment works
150
+
151
+ - 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.
152
+ - 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.
153
+ - On `CUE-IN`: stop ads and resume content immediately.
154
+ - Without markers: provide `adSchedule` or a `defaultVastTagUrl` to still serve ads based on wall-clock content time.
155
+
156
+ ---
157
+
158
+ ## External schedules and Airy API
159
+
160
+ 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.
161
+
162
+ Note: Real-world APIs may require authentication or custom mapping from their JSON to `AdSchedule`. Add an adapter as needed before calling `setAdSchedule`.
163
+
164
+ ---
165
+
166
+ ## Development
167
+
168
+ ```bash
169
+ npm run build # build ESM + CJS with types
170
+ npm run dev # watch mode
171
+ npm run clean # remove dist
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Limitations
177
+
178
+ - This module targets browsers (DOM required). SSR/Node-only not supported.
179
+ - SCTE-35 parsing relies on HLS tags and ID3 text; binary splice parsing is not implemented yet.
180
+ - Multi-ad pod stitching and competitive separation are left to the ad server/IMA.
181
+
182
+ ---
183
+
184
+ ## Roadmap / Remaining tasks
185
+
186
+ - Robust SCTE-35 binary parsing (splice_info_section) and richer marker mapping
187
+ - Stronger late-join logic: handle partial pods, skip-to-content policy
188
+ - Low-Latency HLS (LL-HLS) tuning to reduce ad-start drift further
189
+ - Better drift correction between PTS and wall-clock; tolerance config
190
+ - Ad pod management: sequencing multiple ads per break if provided
191
+ - UI overlays: optional countdown/"Ad" badge and simple debug HUD
192
+ - Retry/backoff and error telemetry for both HLS and IMA flows
193
+ - Analytics events (start/firstQuartile/midpoint/thirdQuartile/complete)
194
+ - Example app and demo page with real streams and test tags
195
+ - Type definitions for IMA surface (remove `any`) and stronger public types
196
+ - CI, unit tests (ID3/daterange parsers), and integration tests
197
+
198
+ ---
199
+
200
+ ## License
201
+
202
+ MIT