stormcloud-video-player 0.3.17 → 0.4.1

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,6 +1,6 @@
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, custom VAST ad serving, and optional Google IMA SDK integration for seamless ad playback. Now featuring a modern, extensible architecture inspired by react-player with comprehensive Smart TV support.
4
4
 
5
5
  ## 🎯 Key Features
6
6
 
@@ -11,9 +11,11 @@ A professional video player with advanced ad integration for web applications. B
11
11
  - **Enhanced UI Controls**: Beautiful, adaptive video controls that work on any background color
12
12
  - **Live Mode Support**: Specialized controls for live streaming with volume adjustment
13
13
  - **Cross-Platform**: Works on desktop, mobile, tablets, and smart TVs
14
+ - **Smart TV Optimized**: Native support for LG WebOS, Samsung Tizen, Sony BRAVIA, and other CTV platforms
14
15
  - **React Ready**: Multiple React components for different use cases
15
16
  - **TypeScript Support**: Full type definitions included
16
17
  - **Professional Architecture**: Modular player system with lazy loading
18
+ - **Built-in Polyfills**: Automatic compatibility for older browsers and legacy TV platforms
17
19
 
18
20
  ## 🚀 Quick Start
19
21
 
@@ -41,7 +43,6 @@ function MyVideoApp() {
41
43
  showCustomControls={true} // Enable enhanced UI controls
42
44
  allowNativeHls={true} // Allow native HLS for better performance
43
45
  licenseKey="your_license_key_here"
44
- vastMode="adstorm" // Use AdStorm mode with HLS ad player
45
46
  style={{ width: "100%", aspectRatio: "16/9" }}
46
47
  wrapperStyle={{ borderRadius: "12px", overflow: "hidden" }}
47
48
  onReady={(player) => {
@@ -78,7 +79,6 @@ function MyVideoApp() {
78
79
  allowNativeHls={true}
79
80
  showCustomControls={true}
80
81
  licenseKey="your_license_key_here"
81
- vastMode="adstorm" // Use AdStorm mode (or omit for default mode)
82
82
  onReady={(player) => {
83
83
  console.log("Player is ready!", player);
84
84
  }}
@@ -264,13 +264,10 @@ interface StormcloudPlayerProps {
264
264
  immediateManifestAds?: boolean;
265
265
  debugAdTiming?: boolean;
266
266
  showCustomControls?: boolean;
267
+ hideLoadingIndicator?: boolean; // Hide the loading spinner/indicator
267
268
  licenseKey?: string;
268
269
  adFailsafeTimeoutMs?: number;
269
-
270
- // Ad player configuration
271
- vastMode?: 'adstorm' | 'default'; // VAST mode: 'adstorm' (HLS player + AdStorm VAST endpoint) or 'default' (IMA SDK + /ads/web endpoint) (default: 'default')
272
- vastTagUrl?: string; // Custom VAST URL (used in default mode if provided; when not provided, uses /ads/web endpoint)
273
- adPlayerType?: 'ima' | 'hls'; // Manual override for ad player type (auto-determined by vastMode if not specified)
270
+ minSegmentsBeforePlay?: number; // Number of segments to buffer before starting playback (default: 2)
274
271
 
275
272
  // Event handlers
276
273
  onReady?: (player: StormcloudVideoPlayer) => void;
@@ -346,17 +343,16 @@ interface StormcloudVideoPlayerConfig {
346
343
  muted?: boolean; // Start muted (default: false)
347
344
  allowNativeHls?: boolean; // Use native HLS when available (default: false)
348
345
  showCustomControls?: boolean; // Enable enhanced UI controls (default: false)
346
+ hideLoadingIndicator?: boolean; // Hide the loading spinner/indicator (default: false)
349
347
  lowLatencyMode?: boolean; // Enable low-latency mode for live streams (default: false)
350
348
  driftToleranceMs?: number; // Drift tolerance for live streams (default: 1000)
351
349
  immediateManifestAds?: boolean; // Load ads immediately from manifest (default: true)
350
+ minSegmentsBeforePlay?: number; // Number of segments to buffer before starting playback (default: 2)
352
351
  licenseKey?: string; // API authentication key
353
352
  debugAdTiming?: boolean; // Enable debug logging (default: false)
354
353
  adFailsafeTimeoutMs?: number; // Ad timeout in milliseconds (default: 10000)
355
-
356
- // Ad configuration
357
- vastMode?: 'adstorm' | 'default'; // VAST mode: 'adstorm' (uses HLS player + AdStorm VAST endpoint) or 'default' (uses Google IMA SDK + /ads/web endpoint) (default: 'default')
358
- vastTagUrl?: string; // Custom VAST tag URL (used in default mode if provided; when not provided, defaults to /ads/web endpoint)
359
- adPlayerType?: 'ima' | 'hls'; // Manual override for ad player type (auto-determined by vastMode if not specified)
354
+ adBreakCheckIntervalMs?: number; // Interval for checking ad breaks (default: 1000)
355
+ maxAdBreakExtensionMs?: number; // Maximum ad break extension time (default: 5000)
360
356
 
361
357
  onVolumeToggle?: () => void; // Callback for volume toggle
362
358
  onFullscreenToggle?: () => void; // Callback for fullscreen toggle
@@ -417,89 +413,69 @@ All controls use a consistent high-contrast design:
417
413
 
418
414
  ## 🎬 Ad Integration (HLS Streams Only)
419
415
 
420
- ### VAST Mode Configuration
421
-
422
- The player supports two VAST modes that automatically configure the appropriate ad player:
416
+ ### Ad Player Configuration
423
417
 
424
- #### 1. **AdStorm Mode** (Recommended)
425
-
426
- Uses AdStorm backend with HLS ad player for optimal performance:
418
+ The player uses AdStorm backend with native ad player for optimal performance:
427
419
 
428
420
  ```javascript
429
421
  const player = new StormcloudVideoPlayer({
430
422
  videoElement: video,
431
423
  src: "https://your-stream.com/playlist.m3u8",
432
424
  licenseKey: "your-license-key",
433
-
434
- // AdStorm mode - uses HLS ad player automatically
435
- vastMode: 'adstorm',
436
-
437
425
  debugAdTiming: true,
438
426
  });
439
427
  ```
440
428
 
441
429
  **What happens:**
442
- - 🎯 Automatically uses HLS ad player (`adPlayerType: 'hls'`)
443
- - 🔗 VAST endpoint: `GET https://adstorm.co/api-adstorm-dev/adstorm/vast/{licenseKey}`
430
+ - 🎯 Automatically uses native ad player with MP4/WebM/HLS support
431
+ - 🔗 VAST Pod endpoint: `GET https://adstorm.co/api-adstorm-dev/adstorm/vast/{licenseKey}/pod`
432
+ - Query parameters:
433
+ - `duration` - Target ad break duration in seconds
434
+ - `metadata` - JSON-encoded video/audio metadata for quality matching
444
435
  - License key is passed in the URL path (no authorization header needed)
445
- - Returns VAST XML directly with HLS media files
436
+ - Returns VAST XML with multiple ads to fill the duration (ad pod)
446
437
  - 📊 Direct tracking and analytics through AdStorm backend
447
438
  - ⚠️ Gracefully handles "no ads available" scenarios (logs warnings, not errors)
448
439
 
440
+ **Pod Ad API Request:**
441
+ ```
442
+ GET /vast/{licenseKey}/pod?duration=60&metadata={"video":{"codec":"h264","width":1920,"height":1080},"audio":{"codec":"aac"}}
443
+ ```
444
+
445
+ **Metadata Structure:**
446
+ ```typescript
447
+ interface AdStormMetadata {
448
+ video?: {
449
+ codec?: string; // e.g., "h264"
450
+ width?: number; // e.g., 1920
451
+ height?: number; // e.g., 1080
452
+ fps?: number; // e.g., 29.97
453
+ bitrate?: number; // e.g., 5000 (kbps)
454
+ profile?: string; // e.g., "high"
455
+ };
456
+ audio?: {
457
+ codec?: string; // e.g., "aac"
458
+ sample_rate?: number; // e.g., 48000
459
+ bitrate?: number; // e.g., 128 (kbps)
460
+ };
461
+ }
462
+ ```
463
+
449
464
  **API Flow:**
450
- 1. Player calls `/vast/{licenseKey}` endpoint
451
- 2. Backend returns VAST XML with HLS media files
452
- 3. Player parses VAST XML and extracts MediaFile URLs
453
- 4. HLS ad player loads and plays the ad segments
465
+ 1. Player detects SCTE-35 marker with ad break duration
466
+ 2. Calls `/vast/{licenseKey}/pod?duration={seconds}&metadata={...}` endpoint
467
+ 3. Backend returns VAST XML with ad pod (multiple ads matching requested duration)
468
+ 4. Native ad player loads and plays ads with quality matching content stream
454
469
 
455
470
  **Benefits:**
456
471
  - ✅ Zero external dependencies (no Google IMA SDK)
457
472
  - ✅ Full control over ad serving
458
- - ✅ Native HLS playback (same format as content)
473
+ - ✅ Multi-format support (MP4, WebM, HLS)
474
+ - ✅ Automatic quality matching to content stream
459
475
  - ✅ Better performance and reliability
460
476
  - ✅ Custom targeting and selection
461
477
  - ✅ Proper error handling (distinguishes parsing errors from "no ads available")
462
-
463
- #### 2. **Default Mode**
464
-
465
- Uses Google IMA SDK for traditional ad serving:
466
-
467
- ```javascript
468
- const player = new StormcloudVideoPlayer({
469
- videoElement: video,
470
- src: "https://your-stream.com/playlist.m3u8",
471
- licenseKey: "your-license-key",
472
-
473
- // Default mode - uses Google IMA SDK automatically
474
- vastMode: 'default', // or omit this property entirely
475
- vastTagUrl: 'https://your-vast-server.com/vast.xml', // optional
476
-
477
- debugAdTiming: true,
478
- });
479
- ```
480
-
481
- **What happens:**
482
- - 🎯 Automatically uses Google IMA SDK (`adPlayerType: 'ima'`)
483
- - 🔗 VAST endpoint resolution:
484
- 1. If `vastTagUrl` is provided, uses that URL directly
485
- 2. Otherwise, calls `GET https://adstorm.co/api-adstorm-dev/adstorm/ads/web`
486
- - Requires `Authorization: Bearer {licenseKey}` header
487
- - Returns JSON response with IMA payload: `{ response: { ima: { "publisherdesk.ima": { payload: "VAST_URL" } } } }`
488
- - Extracts VAST tag URL from the `payload` field
489
- - 📊 Standard VAST/VPAID ad serving through Google IMA SDK
490
-
491
- **API Flow:**
492
- 1. Player calls `/ads/web` endpoint with Bearer token (if no `vastTagUrl` provided)
493
- 2. Backend returns JSON with IMA configuration
494
- 3. Player extracts VAST tag URL from `response.ima["publisherdesk.ima"].payload`
495
- 4. Google IMA SDK loads and plays the VAST ad
496
-
497
- **Benefits:**
498
- - ✅ Industry-standard ad serving
499
- - ✅ Wide format support (VAST, VPAID)
500
- - ✅ Established ecosystem
501
- - ✅ Backward compatible with existing VAST tags
502
- - ✅ Supports both custom VAST URLs and AdStorm backend
478
+ - ✅ Ad pod support (multiple ads per break)
503
479
 
504
480
  ### Ad Pod Generation (Multiple Consecutive Ads)
505
481
 
@@ -560,8 +536,6 @@ const player = new StormcloudVideoPlayer({
560
536
  videoElement: video,
561
537
  src: "https://your-live-stream.com/playlist.m3u8",
562
538
  licenseKey: "your-license-key",
563
-
564
- vastMode: 'default',
565
539
  debugAdTiming: true, // Enable to see adaptive calculations
566
540
  });
567
541
  ```
@@ -619,27 +593,6 @@ Final: 3 ads played (perfectly fills 120 seconds)
619
593
  - ✅ **Smart**: Improves calculation as more data is gathered (uses average of fetched durations)
620
594
  - ✅ **Self-Correcting**: Automatically adjusts if actual ad lengths differ from expectations
621
595
 
622
- ### Manual Ad Player Override
623
-
624
- You can still manually override the ad player type if needed:
625
-
626
- ```javascript
627
- const player = new StormcloudVideoPlayer({
628
- videoElement: video,
629
- src: "https://your-stream.com/playlist.m3u8",
630
-
631
- vastMode: 'default',
632
- adPlayerType: 'hls', // Manual override to use HLS player with default mode
633
- vastTagUrl: 'https://your-backend.com/vast', // Will use this URL directly
634
-
635
- debugAdTiming: true,
636
- });
637
- ```
638
-
639
- **Note:** When `adPlayerType` is manually set, the `vastMode` property still determines which backend endpoint is called:
640
- - `vastMode: 'adstorm'` → Always calls `/vast/{licenseKey}` endpoint
641
- - `vastMode: 'default'` → Calls `/ads/web` endpoint (unless `vastTagUrl` is provided)
642
-
643
596
  ### SCTE-35 Support
644
597
 
645
598
  The HlsPlayer automatically detects and responds to SCTE-35 signals embedded in HLS streams:
@@ -677,6 +630,29 @@ When viewers join during an ad break:
677
630
  />
678
631
  ```
679
632
 
633
+ ### VAST Tracking Events
634
+
635
+ The native ad player automatically fires VAST tracking pixels for the following events:
636
+
637
+ | Event | When Fired |
638
+ |-------|------------|
639
+ | `impression` | When ad is loaded and ready to play |
640
+ | `start` | When ad begins playing |
641
+ | `firstQuartile` | When 25% of ad has played |
642
+ | `midpoint` | When 50% of ad has played |
643
+ | `thirdQuartile` | When 75% of ad has played |
644
+ | `complete` | When ad finishes playing |
645
+ | `mute` | When ad is muted |
646
+ | `unmute` | When ad is unmuted |
647
+ | `pause` | When ad is paused |
648
+ | `resume` | When ad resumes after pause |
649
+ | `fullscreen` | When entering fullscreen |
650
+ | `exitFullscreen` | When exiting fullscreen |
651
+ | `skip` | When ad is skipped |
652
+ | `error` | When an error occurs |
653
+
654
+ Tracking pixels include session ID and license key for analytics correlation.
655
+
680
656
  ### Error Handling
681
657
 
682
658
  The player distinguishes between different types of ad-related issues:
@@ -704,7 +680,7 @@ Example with error handling:
704
680
  ```javascript
705
681
  const player = new StormcloudVideoPlayer({
706
682
  // ... config
707
- vastMode: 'adstorm',
683
+ licenseKey: "your-license-key",
708
684
  debugAdTiming: true, // Enable detailed logging
709
685
  });
710
686
 
@@ -728,14 +704,11 @@ const player = new StormcloudVideoPlayer({
728
704
 
729
705
  Authenticated requests are sent to:
730
706
 
731
- - **AdStorm Mode** (`vastMode: 'adstorm'`):
732
- - VAST endpoint: `GET https://adstorm.co/api-adstorm-dev/adstorm/vast/{licenseKey}` (license key in URL path)
733
-
734
- - **Default Mode** (`vastMode: 'default'`):
735
- - Ad configuration: `GET https://adstorm.co/api-adstorm-dev/adstorm/ads/web` (requires `Authorization: Bearer {licenseKey}` header)
736
- - Returns JSON with IMA payload containing VAST tag URL
707
+ - **VAST Pod endpoint**: `GET https://adstorm.co/api-adstorm-dev/adstorm/vast/{licenseKey}/pod` (license key in URL path)
708
+ - Query parameters: `duration`, `metadata`
709
+ - Returns VAST XML with ad pod for requested duration
737
710
 
738
- - **Player Tracking** (both modes):
711
+ - **Player Tracking**:
739
712
  - Player tracking: `POST https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track` (requires `Authorization: Bearer {licenseKey}` header)
740
713
  - Heartbeat monitoring: `POST https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat` (requires `Authorization: Bearer {licenseKey}` header)
741
714
 
@@ -817,7 +790,70 @@ console.log("Supports PIP:", canPIP); // true for file player
817
790
 
818
791
  - **Desktop**: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
819
792
  - **Mobile**: iOS Safari 12+, Chrome Mobile 60+
820
- - **Smart TV**: WebOS, Tizen, Android TV, Roku, Apple TV
793
+ - **Smart TV**: LG WebOS, Samsung Tizen, Sony BRAVIA, Android TV, Roku, Apple TV, Fire TV
794
+
795
+ ### Smart TV & CTV Platform Support
796
+
797
+ The player includes comprehensive Smart TV detection and automatic configuration:
798
+
799
+ #### Supported Platforms
800
+
801
+ | Platform | Detection | Auto-Config | Notes |
802
+ |----------|-----------|-------------|-------|
803
+ | LG WebOS | ✅ | ✅ | Auto-enables native HLS |
804
+ | Samsung Tizen | ✅ | ✅ | Auto-enables native HLS |
805
+ | Sony BRAVIA | ✅ | ✅ | Auto-enables native HLS |
806
+ | LG NetCast | ✅ | ✅ | Legacy mode enabled |
807
+ | Android TV | ✅ | ✅ | Standard HLS.js mode |
808
+ | Roku | ✅ | ✅ | Native HLS recommended |
809
+ | Apple TV | ✅ | ✅ | Native HLS |
810
+ | Fire TV | ✅ | ✅ | Standard HLS.js mode |
811
+
812
+ #### Automatic Configuration
813
+
814
+ When a Smart TV is detected, the player automatically:
815
+
816
+ 1. **Enables native HLS** for better performance on TV browsers
817
+ 2. **Applies legacy compatibility** for older TV platforms
818
+ 3. **Logs browser info** when debug mode is enabled
819
+
820
+ ```javascript
821
+ // Browser info logged in debug mode
822
+ {
823
+ browser: "Samsung Tizen 6.0",
824
+ platform: "Linux",
825
+ isSmartTV: true,
826
+ isLegacyTV: false,
827
+ supportsModernJS: true,
828
+ userAgent: "..."
829
+ }
830
+ ```
831
+
832
+ #### Manual Override
833
+
834
+ You can override automatic detection if needed:
835
+
836
+ ```javascript
837
+ const player = new StormcloudVideoPlayer({
838
+ videoElement: video,
839
+ src: "https://stream.example.com/playlist.m3u8",
840
+ allowNativeHls: false, // Force HLS.js even on Smart TVs
841
+ debugAdTiming: true, // Log browser detection info
842
+ });
843
+ ```
844
+
845
+ ### Built-in Polyfills
846
+
847
+ The player automatically loads polyfills for older browsers and legacy TV platforms:
848
+
849
+ - **URLSearchParams** - For query string parsing
850
+ - **TextEncoder** - For UTF-8 encoding
851
+ - **Promise.finally** - For promise cleanup
852
+ - **Object.assign** - For object merging
853
+ - **Array.from** - For array-like iteration
854
+ - **String.startsWith/endsWith/includes** - For string operations
855
+
856
+ These polyfills are only loaded when needed and have minimal impact on modern browsers.
821
857
 
822
858
  ### Format Support by Player
823
859
 
@@ -870,9 +906,12 @@ src/
870
906
  ├── ui/
871
907
  │ └── StormcloudVideoPlayer.tsx # Legacy React component
872
908
  ├── sdk/
873
- └── ima.ts # Google IMA integration
909
+ ├── adstormPlayer.ts # Native ad player (MP4/WebM/HLS)
910
+ │ └── hlsAdPlayer.ts # HLS-specific ad player
874
911
  ├── utils/
875
912
  │ ├── tracking.ts # Analytics and tracking
913
+ │ ├── browserCompat.ts # Smart TV & browser detection
914
+ │ ├── polyfills.ts # Legacy browser polyfills
876
915
  │ └── index.ts # Utility functions
877
916
  ├── props.ts # Centralized props system
878
917
  ├── patterns.ts # URL pattern matching
@@ -988,19 +1027,26 @@ MIT License - see [LICENSE](LICENSE) file for details.
988
1027
 
989
1028
  Built with ❤️ by the Stormcloud team
990
1029
 
1030
+ ### What's New in v0.3.17
1031
+
1032
+ - 📺 **Smart TV Support**: Comprehensive detection for LG WebOS, Samsung Tizen, Sony BRAVIA, and more
1033
+ - 🔧 **Automatic Configuration**: Smart TVs automatically use native HLS for better performance
1034
+ - 🛡️ **Built-in Polyfills**: URLSearchParams, TextEncoder, Promise.finally, and more for legacy platforms
1035
+ - 📊 **Browser Detection API**: Detailed browser info logging in debug mode
1036
+ - ⚡ **Buffering Control**: New `minSegmentsBeforePlay` option to control initial buffering (default: 2 segments)
1037
+ - 🎛️ **UI Enhancements**: New `hideLoadingIndicator` option to hide loading spinners
1038
+ - 🎬 **Native Ad Player**: Multi-format ad playback (MP4, WebM, HLS) with quality matching
1039
+ - 📦 **Pod Ad API**: New `/vast/{licenseKey}/pod` endpoint for ad pod generation with metadata
1040
+ - 🎯 **Quality Matching**: Automatic ad quality selection based on content stream parameters
1041
+
991
1042
  ### What's New in v0.3
992
1043
 
993
1044
  - 🎬 **Custom HLS Ad Player**: Native HLS ad playback with custom VAST service
994
- - 🎯 **Flexible Ad Integration**: Choose between custom HLS or Google IMA SDK
1045
+ - 🎯 **Flexible Ad Integration**: Native ad player with AdStorm VAST endpoint
995
1046
  - 📊 **Direct Analytics**: Full control over ad tracking and metrics
996
1047
  - ⚡ **Better Performance**: Native HLS playback for ads (same format as content)
997
- - 🔧 **Custom VAST URLs**: Point to your own ad serving backend
998
- - 🔄 **Backward Compatible**: Existing Google IMA integration still works
999
- - 📦 **Zero Dependencies**: No external ad SDKs required (when using HLS ad player)
1048
+ - 📦 **Zero Dependencies**: No external ad SDKs required
1000
1049
  - 🎨 **Seamless Playback**: Same player for content and ads
1001
- - 🔀 **VAST Mode System**: `vastMode` property automatically configures endpoints and ad players
1002
- - `vastMode: 'adstorm'` → Uses `/vast/{licenseKey}` endpoint with HLS ad player
1003
- - `vastMode: 'default'` → Uses `/ads/web` endpoint with Google IMA SDK
1004
1050
  - ⚠️ **Improved Error Handling**: Distinguishes between parsing errors and "no ads available" scenarios
1005
1051
  - Logs warnings for "no ads available" (graceful handling)
1006
1052
  - Logs errors for actual parsing/fetch failures