stormcloud-video-player 0.3.57 → 0.3.59
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 +243 -10
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +841 -88
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +40 -0
- package/lib/index.d.ts +40 -0
- package/lib/index.js +841 -88
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +841 -88
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +40 -0
- package/lib/players/HlsPlayer.cjs +841 -88
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +841 -88
- package/lib/players/index.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +841 -88
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# Stormcloud Video Player
|
|
2
2
|
|
|
3
|
-
A professional video player with advanced ad integration for web applications. Built with precision ad break alignment, SCTE-35 signal parsing, custom VAST ad serving, and optional Google IMA SDK integration for seamless ad playback. Now featuring a modern, extensible architecture inspired by react-player.
|
|
3
|
+
A professional video player with advanced ad integration for web applications. Built with precision ad break alignment, SCTE-35 signal parsing, VMAP ad-break scheduling, custom VAST ad serving, and optional Google IMA SDK integration for seamless ad playback. Now featuring a modern, extensible architecture inspired by react-player.
|
|
4
4
|
|
|
5
5
|
## 🎯 Key Features
|
|
6
6
|
|
|
7
7
|
- **Multi-Format Support**: Automatic detection and playback of HLS streams and regular video files
|
|
8
8
|
- **Precision Ad Alignment**: Tight synchronization with SCTE-35 CUE-OUT signals
|
|
9
|
+
- **VMAP 1.0 Support**: Schedule pre-roll, mid-roll, and post-roll ad breaks via a VMAP manifest
|
|
9
10
|
- **Smart Mid-Roll Handling**: Automatic detection and playback of remaining ad portions when joining late
|
|
10
|
-
- **Flexible Ad Scheduling**: Support for
|
|
11
|
+
- **Flexible Ad Scheduling**: Support for SCTE-35 markers, VMAP manifests, and external ad schedules
|
|
11
12
|
- **Enhanced UI Controls**: Beautiful, adaptive video controls that work on any background color
|
|
12
13
|
- **Live Mode Support**: Specialized controls for live streaming with volume adjustment
|
|
13
|
-
- **Cross-Platform
|
|
14
|
+
- **Cross-Platform & Smart TV Ready**: Desktop, mobile, tablets, LG WebOS, Samsung Tizen, Sony BRAVIA, Android TV, Roku, Apple TV
|
|
15
|
+
- **Automatic Browser Compatibility**: Built-in browser detection, polyfills, and automatic ad-player selection for legacy Smart TVs
|
|
14
16
|
- **React Ready**: Multiple React components for different use cases
|
|
15
17
|
- **TypeScript Support**: Full type definitions included
|
|
16
18
|
- **Professional Architecture**: Modular player system with lazy loading
|
|
@@ -39,9 +41,11 @@ function MyVideoApp() {
|
|
|
39
41
|
muted={true}
|
|
40
42
|
controls={true}
|
|
41
43
|
showCustomControls={true} // Enable enhanced UI controls
|
|
44
|
+
hideLoadingIndicator={false} // Hide the built-in loading spinner
|
|
42
45
|
allowNativeHls={true} // Allow native HLS for better performance
|
|
43
46
|
licenseKey="your_license_key_here"
|
|
44
47
|
vastMode="adstorm" // Use AdStorm mode with HLS ad player
|
|
48
|
+
vmapUrl="https://your-cdn.com/ads.vmap" // Optional VMAP manifest for scheduled breaks
|
|
45
49
|
style={{ width: "100%", aspectRatio: "16/9" }}
|
|
46
50
|
wrapperStyle={{ borderRadius: "12px", overflow: "hidden" }}
|
|
47
51
|
onReady={(player) => {
|
|
@@ -77,8 +81,10 @@ function MyVideoApp() {
|
|
|
77
81
|
// Stormcloud-specific props
|
|
78
82
|
allowNativeHls={true}
|
|
79
83
|
showCustomControls={true}
|
|
84
|
+
hideLoadingIndicator={false}
|
|
80
85
|
licenseKey="your_license_key_here"
|
|
81
86
|
vastMode="adstorm" // Use AdStorm mode (or omit for default mode)
|
|
87
|
+
vmapUrl="https://your-cdn.com/ads.vmap" // Optional: VMAP manifest URL
|
|
82
88
|
onReady={(player) => {
|
|
83
89
|
console.log("Player is ready!", player);
|
|
84
90
|
}}
|
|
@@ -114,9 +120,12 @@ const player = new StormcloudVideoPlayer({
|
|
|
114
120
|
muted: true,
|
|
115
121
|
allowNativeHls: true, // Enable native HLS when supported
|
|
116
122
|
showCustomControls: true, // Enable enhanced UI controls
|
|
123
|
+
hideLoadingIndicator: false, // Hide built-in loading spinner
|
|
117
124
|
lowLatencyMode: false, // Set to true for live streams
|
|
118
125
|
driftToleranceMs: 3000, // Drift tolerance for live streams
|
|
119
126
|
licenseKey: "your_license_key_here",
|
|
127
|
+
vastMode: "default", // "adstorm" | "default"
|
|
128
|
+
vmapUrl: "https://your-cdn.com/ads.vmap", // Optional VMAP manifest for scheduled ad breaks
|
|
120
129
|
onVolumeToggle: () => console.log("Volume toggled"),
|
|
121
130
|
onFullscreenToggle: () => console.log("Fullscreen toggled"),
|
|
122
131
|
});
|
|
@@ -264,6 +273,7 @@ interface StormcloudPlayerProps {
|
|
|
264
273
|
immediateManifestAds?: boolean;
|
|
265
274
|
debugAdTiming?: boolean;
|
|
266
275
|
showCustomControls?: boolean;
|
|
276
|
+
hideLoadingIndicator?: boolean; // Hide the built-in loading spinner (default: false)
|
|
267
277
|
licenseKey?: string;
|
|
268
278
|
adFailsafeTimeoutMs?: number;
|
|
269
279
|
minSegmentsBeforePlay?: number; // Number of segments to buffer before starting playback (default: 2)
|
|
@@ -271,6 +281,7 @@ interface StormcloudPlayerProps {
|
|
|
271
281
|
// Ad player configuration
|
|
272
282
|
vastMode?: 'adstorm' | 'default'; // VAST mode: 'adstorm' (HLS player + AdStorm VAST endpoint) or 'default' (IMA SDK + /ads/web endpoint) (default: 'default')
|
|
273
283
|
vastTagUrl?: string; // Custom VAST URL (used in default mode if provided; when not provided, uses /ads/web endpoint)
|
|
284
|
+
vmapUrl?: string; // Optional VMAP 1.0 manifest URL used to schedule pre/mid/post-roll ad breaks
|
|
274
285
|
adPlayerType?: 'ima' | 'hls'; // Manual override for ad player type (auto-determined by vastMode if not specified)
|
|
275
286
|
|
|
276
287
|
// Event handlers
|
|
@@ -347,6 +358,7 @@ interface StormcloudVideoPlayerConfig {
|
|
|
347
358
|
muted?: boolean; // Start muted (default: false)
|
|
348
359
|
allowNativeHls?: boolean; // Use native HLS when available (default: false)
|
|
349
360
|
showCustomControls?: boolean; // Enable enhanced UI controls (default: false)
|
|
361
|
+
hideLoadingIndicator?: boolean; // Hide the built-in loading spinner (default: false)
|
|
350
362
|
lowLatencyMode?: boolean; // Enable low-latency mode for live streams (default: false)
|
|
351
363
|
driftToleranceMs?: number; // Drift tolerance for live streams (default: 1000)
|
|
352
364
|
immediateManifestAds?: boolean; // Load ads immediately from manifest (default: true)
|
|
@@ -355,10 +367,15 @@ interface StormcloudVideoPlayerConfig {
|
|
|
355
367
|
adFailsafeTimeoutMs?: number; // Ad timeout in milliseconds (default: 10000)
|
|
356
368
|
minSegmentsBeforePlay?: number; // Number of segments to buffer before starting playback (default: 2)
|
|
357
369
|
|
|
370
|
+
// Ad break timing
|
|
371
|
+
adBreakCheckIntervalMs?: number; // Interval used to re-check an active ad break (default: 1000, min: 250)
|
|
372
|
+
maxAdBreakExtensionMs?: number; // Max time an ad break may be extended past its SCTE-35 duration when ads are still playing/queued (default: 60000)
|
|
373
|
+
|
|
358
374
|
// Ad configuration
|
|
359
375
|
vastMode?: 'adstorm' | 'default'; // VAST mode: 'adstorm' (uses HLS player + AdStorm VAST endpoint) or 'default' (uses Google IMA SDK + /ads/web endpoint) (default: 'default')
|
|
360
376
|
vastTagUrl?: string; // Custom VAST tag URL (used in default mode if provided; when not provided, defaults to /ads/web endpoint)
|
|
361
|
-
|
|
377
|
+
vmapUrl?: string; // Optional VMAP 1.0 manifest URL used to schedule pre/mid/post-roll ad breaks
|
|
378
|
+
adPlayerType?: 'ima' | 'hls'; // Manual override for ad player type (auto-determined by vastMode/browser if not specified)
|
|
362
379
|
|
|
363
380
|
onVolumeToggle?: () => void; // Callback for volume toggle
|
|
364
381
|
onFullscreenToggle?: () => void; // Callback for fullscreen toggle
|
|
@@ -621,6 +638,94 @@ Final: 3 ads played (perfectly fills 120 seconds)
|
|
|
621
638
|
- ✅ **Smart**: Improves calculation as more data is gathered (uses average of fetched durations)
|
|
622
639
|
- ✅ **Self-Correcting**: Automatically adjusts if actual ad lengths differ from expectations
|
|
623
640
|
|
|
641
|
+
### VMAP Ad Break Scheduling
|
|
642
|
+
|
|
643
|
+
In addition to SCTE-35 markers and continuous-ad-fetch, the player supports **VMAP 1.0** manifests for scheduling ad breaks at specific positions in the timeline. This is ideal for VOD content where you want to declaratively define pre-roll, mid-roll, and post-roll breaks with explicit time offsets.
|
|
644
|
+
|
|
645
|
+
#### Usage
|
|
646
|
+
|
|
647
|
+
Provide a `vmapUrl` in addition to (or instead of) a VAST/AdStorm configuration:
|
|
648
|
+
|
|
649
|
+
```javascript
|
|
650
|
+
const player = new StormcloudVideoPlayer({
|
|
651
|
+
videoElement: video,
|
|
652
|
+
src: "https://your-stream.com/video.m3u8",
|
|
653
|
+
licenseKey: "your-license-key",
|
|
654
|
+
|
|
655
|
+
vastMode: 'default',
|
|
656
|
+
vmapUrl: 'https://your-cdn.com/schedule.vmap', // VMAP 1.0 manifest
|
|
657
|
+
|
|
658
|
+
debugAdTiming: true,
|
|
659
|
+
});
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
Or with React:
|
|
663
|
+
|
|
664
|
+
```jsx
|
|
665
|
+
<StormcloudPlayer
|
|
666
|
+
src="https://your-stream.com/video.m3u8"
|
|
667
|
+
licenseKey="your-license-key"
|
|
668
|
+
vmapUrl="https://your-cdn.com/schedule.vmap"
|
|
669
|
+
playing={true}
|
|
670
|
+
/>
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
#### Supported `timeOffset` Formats
|
|
674
|
+
|
|
675
|
+
The VMAP parser recognizes all standard `timeOffset` values:
|
|
676
|
+
|
|
677
|
+
| Value | Meaning |
|
|
678
|
+
| --------------------- | ---------------------------------------------------- |
|
|
679
|
+
| `start` | Pre-roll (playback position 0) |
|
|
680
|
+
| `end` | Post-roll (resolved at runtime using media duration) |
|
|
681
|
+
| `HH:MM:SS` / `HH:MM:SS.mmm` | Absolute timestamp mid-roll |
|
|
682
|
+
| `NN%` | Percentage of media duration (resolved at runtime) |
|
|
683
|
+
|
|
684
|
+
#### Example VMAP Manifest
|
|
685
|
+
|
|
686
|
+
```xml
|
|
687
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
688
|
+
<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">
|
|
689
|
+
<vmap:AdBreak timeOffset="start" breakType="linear" breakId="preroll">
|
|
690
|
+
<vmap:AdSource>
|
|
691
|
+
<vmap:AdTagURI templateType="vast3">
|
|
692
|
+
<![CDATA[https://your-ad-server.com/vast?position=preroll]]>
|
|
693
|
+
</vmap:AdTagURI>
|
|
694
|
+
</vmap:AdSource>
|
|
695
|
+
</vmap:AdBreak>
|
|
696
|
+
|
|
697
|
+
<vmap:AdBreak timeOffset="00:05:00" breakType="linear" breakId="midroll-1">
|
|
698
|
+
<vmap:AdSource>
|
|
699
|
+
<vmap:AdTagURI templateType="vast3">
|
|
700
|
+
<![CDATA[https://your-ad-server.com/vast?position=midroll-1]]>
|
|
701
|
+
</vmap:AdTagURI>
|
|
702
|
+
</vmap:AdSource>
|
|
703
|
+
</vmap:AdBreak>
|
|
704
|
+
|
|
705
|
+
<vmap:AdBreak timeOffset="end" breakType="linear" breakId="postroll">
|
|
706
|
+
<vmap:AdSource>
|
|
707
|
+
<vmap:AdTagURI templateType="vast3">
|
|
708
|
+
<![CDATA[https://your-ad-server.com/vast?position=postroll]]>
|
|
709
|
+
</vmap:AdTagURI>
|
|
710
|
+
</vmap:AdSource>
|
|
711
|
+
</vmap:AdBreak>
|
|
712
|
+
</vmap:VMAP>
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
#### How It Works
|
|
716
|
+
|
|
717
|
+
1. The player fetches the VMAP manifest on load (before playback starts).
|
|
718
|
+
2. Each `<AdBreak>` is parsed into an `AdBreak` object with a resolved `startTimeMs` and the associated `vastTagUrl` from `<AdTagURI>`.
|
|
719
|
+
3. During playback, the player matches the current time against each scheduled break and triggers the ad request at the correct offset.
|
|
720
|
+
4. **Mid-roll join behavior**: If the viewer joins mid-stream and has already passed a scheduled break, the player will honor the configured late-join policy (e.g., play the remaining portion or skip to content).
|
|
721
|
+
5. Each break is only consumed once per session to avoid replaying breaks after seeking.
|
|
722
|
+
|
|
723
|
+
**Benefits:**
|
|
724
|
+
- ✅ Declarative ad scheduling — no custom code needed per break
|
|
725
|
+
- ✅ Works alongside `vastMode: 'adstorm'` and `vastMode: 'default'`
|
|
726
|
+
- ✅ Supports pre-roll, mid-roll, percentage-based, and post-roll breaks
|
|
727
|
+
- ✅ Gracefully handles malformed XML and fetch failures (logged when `debugAdTiming` is enabled)
|
|
728
|
+
|
|
624
729
|
### Manual Ad Player Override
|
|
625
730
|
|
|
626
731
|
You can still manually override the ad player type if needed:
|
|
@@ -819,6 +924,52 @@ Authenticated requests are sent to:
|
|
|
819
924
|
- **Player Tracking** (both modes):
|
|
820
925
|
- Player tracking: `POST https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track` (requires `Authorization: Bearer {licenseKey}` header)
|
|
821
926
|
- Heartbeat monitoring: `POST https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat` (requires `Authorization: Bearer {licenseKey}` header)
|
|
927
|
+
- Ad-detect, ad-loaded, and ad-impression events are automatically emitted during ad breaks.
|
|
928
|
+
|
|
929
|
+
### Tracking Utilities
|
|
930
|
+
|
|
931
|
+
The player exposes low-level tracking helpers if you want to fire events manually or build custom analytics:
|
|
932
|
+
|
|
933
|
+
```javascript
|
|
934
|
+
import {
|
|
935
|
+
getClientInfo,
|
|
936
|
+
getBrowserID,
|
|
937
|
+
sendInitialTracking,
|
|
938
|
+
sendHeartbeat,
|
|
939
|
+
sendAdDetectTracking,
|
|
940
|
+
sendAdLoadedTracking,
|
|
941
|
+
sendAdImpressionTracking,
|
|
942
|
+
} from "stormcloud-video-player";
|
|
943
|
+
|
|
944
|
+
const clientInfo = getClientInfo();
|
|
945
|
+
const browserId = getBrowserID();
|
|
946
|
+
|
|
947
|
+
await sendInitialTracking(licenseKey, clientInfo);
|
|
948
|
+
await sendHeartbeat(licenseKey, { browserId, timestamp: new Date().toISOString() });
|
|
949
|
+
|
|
950
|
+
// Ad lifecycle tracking
|
|
951
|
+
await sendAdDetectTracking(licenseKey, {
|
|
952
|
+
source: "scte35",
|
|
953
|
+
durationSeconds: 30,
|
|
954
|
+
ptsSeconds: 120.5,
|
|
955
|
+
detectedAtFragmentSn: 1234,
|
|
956
|
+
timestamp: new Date().toISOString(),
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
await sendAdLoadedTracking(licenseKey, {
|
|
960
|
+
source: "ima", // 'prebid' | 'ima' | 'hls'
|
|
961
|
+
vastUrl: "https://...",
|
|
962
|
+
durationSeconds: 15,
|
|
963
|
+
timestamp: new Date().toISOString(),
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
await sendAdImpressionTracking(licenseKey, {
|
|
967
|
+
source: "ima",
|
|
968
|
+
adIndex: 0,
|
|
969
|
+
durationSeconds: 15,
|
|
970
|
+
timestamp: new Date().toISOString(),
|
|
971
|
+
});
|
|
972
|
+
```
|
|
822
973
|
|
|
823
974
|
## 🔧 Advanced Configuration
|
|
824
975
|
|
|
@@ -927,11 +1078,74 @@ console.log("Supports PIP:", canPIP); // true for file player
|
|
|
927
1078
|
/>
|
|
928
1079
|
```
|
|
929
1080
|
|
|
930
|
-
## 🌐 Browser Support
|
|
1081
|
+
## 🌐 Browser & Smart TV Support
|
|
931
1082
|
|
|
932
1083
|
- **Desktop**: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
|
|
933
1084
|
- **Mobile**: iOS Safari 12+, Chrome Mobile 60+
|
|
934
|
-
- **Smart TV**: WebOS, Tizen, Android TV, Roku, Apple TV
|
|
1085
|
+
- **Smart TV**: LG WebOS (v2+), Samsung Tizen (v2+), Sony BRAVIA, Android TV, Roku, Apple TV, generic Smart TV user-agents
|
|
1086
|
+
|
|
1087
|
+
### Automatic Browser Detection & Ad Player Selection
|
|
1088
|
+
|
|
1089
|
+
The player automatically detects the runtime environment and chooses the optimal ad-player configuration. This is especially useful for Smart TVs where the Google IMA SDK may not be available on older devices.
|
|
1090
|
+
|
|
1091
|
+
```javascript
|
|
1092
|
+
import {
|
|
1093
|
+
detectBrowser,
|
|
1094
|
+
supportsGoogleIMA,
|
|
1095
|
+
getRecommendedAdPlayer,
|
|
1096
|
+
supportsModernJS,
|
|
1097
|
+
logBrowserInfo,
|
|
1098
|
+
getBrowserConfigOverrides,
|
|
1099
|
+
supportsFeature,
|
|
1100
|
+
} from "stormcloud-video-player";
|
|
1101
|
+
|
|
1102
|
+
const info = detectBrowser();
|
|
1103
|
+
// {
|
|
1104
|
+
// name: 'LG WebOS',
|
|
1105
|
+
// version: '5.0',
|
|
1106
|
+
// majorVersion: 5,
|
|
1107
|
+
// isSmartTV: true,
|
|
1108
|
+
// isLegacyTV: false,
|
|
1109
|
+
// supportsIMA: true,
|
|
1110
|
+
// supportsModernJS: true,
|
|
1111
|
+
// recommendedAdPlayer: 'ima',
|
|
1112
|
+
// webOSVersion: 5,
|
|
1113
|
+
// chromeVersion: 79,
|
|
1114
|
+
// ...
|
|
1115
|
+
// }
|
|
1116
|
+
|
|
1117
|
+
console.log(supportsGoogleIMA()); // true | false
|
|
1118
|
+
console.log(getRecommendedAdPlayer()); // 'ima' | 'hls'
|
|
1119
|
+
console.log(supportsFeature('fetch')); // true | false
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
**What happens automatically:**
|
|
1123
|
+
|
|
1124
|
+
- **Legacy Smart TVs** (LG NetCast, old WebOS < 3, old Tizen): `adPlayerType` is forced to `'hls'` and `allowNativeHls` is enabled.
|
|
1125
|
+
- **Modern Smart TVs**: `allowNativeHls` is enabled by default (TVs generally play HLS better natively).
|
|
1126
|
+
- **If IMA SDK is unsupported**: the player falls back to the HLS ad player automatically.
|
|
1127
|
+
- **Browser overrides** are merged with your config — user-provided options always take precedence.
|
|
1128
|
+
|
|
1129
|
+
Call `logBrowserInfo(true)` (or enable `debugAdTiming`) to print a detailed compatibility report to the console.
|
|
1130
|
+
|
|
1131
|
+
### Automatic Polyfills for Legacy Devices
|
|
1132
|
+
|
|
1133
|
+
On older Smart TVs and browsers, `initializePolyfills()` is invoked automatically at construction time. It adds missing primitives needed for the player to run:
|
|
1134
|
+
|
|
1135
|
+
- `URLSearchParams`
|
|
1136
|
+
- `TextEncoder`
|
|
1137
|
+
- `Promise.prototype.finally`
|
|
1138
|
+
- `Object.assign`
|
|
1139
|
+
- `Array.from`
|
|
1140
|
+
- `String.prototype.startsWith` / `endsWith` / `includes`
|
|
1141
|
+
|
|
1142
|
+
You can also run it manually before bootstrapping anything else:
|
|
1143
|
+
|
|
1144
|
+
```javascript
|
|
1145
|
+
import { initializePolyfills } from "stormcloud-video-player";
|
|
1146
|
+
|
|
1147
|
+
initializePolyfills();
|
|
1148
|
+
```
|
|
935
1149
|
|
|
936
1150
|
### Format Support by Player
|
|
937
1151
|
|
|
@@ -980,16 +1194,19 @@ src/
|
|
|
980
1194
|
│ ├── HlsPlayer.tsx # HLS stream handler
|
|
981
1195
|
│ └── FilePlayer.tsx # Regular video handler
|
|
982
1196
|
├── player/
|
|
983
|
-
│ └── StormcloudVideoPlayer.ts # Core player class
|
|
1197
|
+
│ └── StormcloudVideoPlayer.ts # Core player class (SCTE-35, VMAP, ad pods)
|
|
984
1198
|
├── ui/
|
|
985
1199
|
│ └── StormcloudVideoPlayer.tsx # Legacy React component
|
|
986
1200
|
├── sdk/
|
|
987
|
-
│
|
|
1201
|
+
│ ├── ima.ts # Google IMA integration
|
|
1202
|
+
│ └── hlsAdPlayer.ts # Native HLS ad player (AdStorm mode, legacy TVs)
|
|
988
1203
|
├── utils/
|
|
989
|
-
│ ├── tracking.ts # Analytics and tracking
|
|
990
|
-
│
|
|
1204
|
+
│ ├── tracking.ts # Analytics and ad tracking
|
|
1205
|
+
│ ├── browserCompat.ts # Browser / Smart TV detection & auto-overrides
|
|
1206
|
+
│ └── polyfills.ts # Legacy browser polyfills
|
|
991
1207
|
├── props.ts # Centralized props system
|
|
992
1208
|
├── patterns.ts # URL pattern matching
|
|
1209
|
+
├── utils.ts # Shared utilities
|
|
993
1210
|
└── types.ts # TypeScript definitions
|
|
994
1211
|
```
|
|
995
1212
|
|
|
@@ -1102,6 +1319,22 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
1102
1319
|
|
|
1103
1320
|
Built with ❤️ by the Stormcloud team
|
|
1104
1321
|
|
|
1322
|
+
### What's New in v0.5
|
|
1323
|
+
|
|
1324
|
+
- 🗓️ **VMAP 1.0 Support**: New `vmapUrl` config/prop loads a VMAP manifest and schedules pre-roll, mid-roll, percentage-based, and post-roll breaks automatically
|
|
1325
|
+
- Supports `start`, `end`, `HH:MM:SS[.mmm]`, and `NN%` `timeOffset` values
|
|
1326
|
+
- Namespaced (`vmap:AdBreak`) and non-namespaced manifests both supported
|
|
1327
|
+
- Breaks are consumed-once-per-session and integrate with the existing late-join policy
|
|
1328
|
+
- 📺 **Smart TV First-Class Support**: New browser-compat layer auto-detects LG WebOS, Samsung Tizen, Sony BRAVIA, LG NetCast and generic Smart TV UAs
|
|
1329
|
+
- Exports `detectBrowser`, `supportsGoogleIMA`, `getRecommendedAdPlayer`, `supportsModernJS`, `logBrowserInfo`, `getBrowserConfigOverrides`, `supportsFeature`
|
|
1330
|
+
- Automatically forces HLS ad player on legacy TVs where IMA SDK is not available
|
|
1331
|
+
- Automatically enables `allowNativeHls` on Smart TVs for more reliable playback
|
|
1332
|
+
- 🧩 **Automatic Polyfills**: `initializePolyfills()` runs at construction time and backfills `URLSearchParams`, `TextEncoder`, `Promise.prototype.finally`, `Object.assign`, `Array.from`, and `String.prototype.startsWith/endsWith/includes` for legacy environments
|
|
1333
|
+
- 📊 **Expanded Ad Tracking**: New `sendAdDetectTracking`, `sendAdLoadedTracking`, and `sendAdImpressionTracking` helpers (plus `AdDetectInfo`, `AdLoadedInfo`, `AdImpressionInfo`, and `AdTrackingSource` types) for prebid/IMA/HLS ad lifecycle events
|
|
1334
|
+
- ⚙️ **Ad-Break Timing Controls**: New `adBreakCheckIntervalMs` (default 1000ms, min 250ms) and `maxAdBreakExtensionMs` (default 60000ms) options give you precise control over how long the player is allowed to extend an ad break past its SCTE-35 duration when ads are still playing or queued
|
|
1335
|
+
- 🙈 **Hide Loading Indicator**: New `hideLoadingIndicator` prop/config hides the built-in buffering spinner when you want to render your own overlay
|
|
1336
|
+
- 🔌 **Expanded Public API**: `createImaController`, `createHlsAdPlayer`, and `initializePolyfills` are now exported alongside the new browser-compat utilities, making it easier to build custom integrations on top of the player core
|
|
1337
|
+
|
|
1105
1338
|
### What's New in v0.4
|
|
1106
1339
|
|
|
1107
1340
|
- 🚀 **Early Ad Prefetching**: Detects SCTE-35 markers in manifest fragments before playback reaches them, prefetching ads in advance for zero-delay ad starts
|