stormcloud-video-player 0.2.36 → 0.3.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
@@ -501,6 +501,124 @@ const player = new StormcloudVideoPlayer({
501
501
  - ✅ Backward compatible with existing VAST tags
502
502
  - ✅ Supports both custom VAST URLs and AdStorm backend
503
503
 
504
+ ### Ad Pod Generation (Multiple Consecutive Ads)
505
+
506
+ The player automatically generates **ad pods** (multiple ads played consecutively) from a single VAST URL. This works differently for VOD and live streams:
507
+
508
+ #### VOD Mode: Fixed Ad Count
509
+
510
+ For **Video on Demand**, the player uses the `number_ads` field from the API response to determine how many ads to play:
511
+
512
+ **API Response Configuration:**
513
+ ```json
514
+ {
515
+ "response": {
516
+ "ima": {
517
+ "publisherdesk.ima": {
518
+ "payload": "https://pubads.g.doubleclick.net/gampad/ads?...",
519
+ "priority": 1
520
+ }
521
+ },
522
+ "options": {
523
+ "vast": {
524
+ "cue_tones": {
525
+ "number_ads": 3
526
+ }
527
+ }
528
+ }
529
+ }
530
+ }
531
+ ```
532
+
533
+ **How it works:**
534
+ 1. Player receives a single VAST URL from the API
535
+ 2. The `number_ads` field specifies how many ads should play (e.g., 3)
536
+ 3. Player generates 3 unique VAST URLs by adding different `correlator` values
537
+ 4. Each unique correlator causes GAM to return a different ad
538
+ 5. All 3 ads play consecutively in the ad break
539
+
540
+ **Example:**
541
+ ```javascript
542
+ // Base URL from API
543
+ "https://pubads.g.doubleclick.net/...&correlator="
544
+
545
+ // Generated URLs (3 ads)
546
+ [
547
+ "https://pubads.g.doubleclick.net/...&correlator=1730995200000123456780",
548
+ "https://pubads.g.doubleclick.net/...&correlator=1730995200000789012341",
549
+ "https://pubads.g.doubleclick.net/...&correlator=1730995200000345678902"
550
+ ]
551
+ ```
552
+
553
+ #### Live Mode: Adaptive Duration-Based Ad Filling
554
+
555
+ For **live streams**, the player uses an **adaptive strategy** that fetches VAST responses, extracts actual ad durations, and dynamically requests additional ads as needed to fill the SCTE-35 marker duration:
556
+
557
+ **Configuration:**
558
+ ```javascript
559
+ const player = new StormcloudVideoPlayer({
560
+ videoElement: video,
561
+ src: "https://your-live-stream.com/playlist.m3u8",
562
+ licenseKey: "your-license-key",
563
+
564
+ vastMode: 'default',
565
+ debugAdTiming: true, // Enable to see adaptive calculations
566
+ });
567
+ ```
568
+
569
+ **How Adaptive Mode Works:**
570
+
571
+ 1. **Initial Request**: Player starts with 2 initial VAST URLs
572
+ 2. **Fetch Real Duration**: As each VAST is fetched, the player extracts the actual `<Duration>` from the XML
573
+ 3. **Adaptive Calculation**: After fetching each ad, the player:
574
+ - Calculates total duration of fetched ads
575
+ - Compares against target SCTE-35 duration
576
+ - Dynamically generates more VAST URLs if needed
577
+ 4. **Smart Filling**: Uses **average** of actual fetched durations (not estimates) to calculate remaining ads
578
+ 5. **Continuous Adaptation**: Recalculates after each ad fetch until target duration is met
579
+
580
+ **Example Scenario:**
581
+ ```
582
+ SCTE-35 Duration: 120 seconds
583
+
584
+ Step 1: Start with 2 initial ads
585
+ → Fetch Ad 1: Actual duration = 45s
586
+ → Recalculate: Need (120-45)/45 = 2 more ads
587
+ → Generate 2 additional VAST URLs
588
+
589
+ Step 2: Fetch Ad 2: Actual duration = 40s
590
+ → Total so far: 85s (45s + 40s)
591
+ → Recalculate: Need (120-85)/42.5 = 1 more ad
592
+ → Generate 1 additional VAST URL
593
+
594
+ Step 3: Fetch Ad 3: Actual duration = 35s
595
+ → Total: 120s ✅ Target reached!
596
+
597
+ Final: 3 ads played (perfectly fills 120 seconds)
598
+ ```
599
+
600
+ **Debug Output:**
601
+ ```
602
+ [ADAPTIVE-POD] 📺 LIVE MODE (ADAPTIVE): Target duration=120000ms | Starting with 2 ads, will fetch actual durations and add more dynamically
603
+ [DEBUG-POD] 🔄 Generated 2 initial VAST URLs with unique correlators
604
+ [ADAPTIVE-POD] ✓ Fetched ad duration: 45s (1 ads fetched so far)
605
+ [ADAPTIVE-POD] 📊 Need 2 more ads | Fetched: 45000ms / Target: 120000ms | Remaining: 75000ms | Avg duration: 45000ms
606
+ [ADAPTIVE-POD] 🔄 Adding 2 additional VAST URLs to queue
607
+ [ADAPTIVE-POD] ✓ Fetched ad duration: 40s (2 ads fetched so far)
608
+ [ADAPTIVE-POD] 📊 Need 1 more ads | Fetched: 85000ms / Target: 120000ms | Remaining: 35000ms | Avg duration: 42500ms
609
+ [ADAPTIVE-POD] ✓ Fetched ad duration: 35s (3 ads fetched so far)
610
+ [ADAPTIVE-POD] ✅ Target duration reached: 120000ms / 120000ms
611
+ ```
612
+
613
+ **Benefits of Adaptive Approach:**
614
+
615
+ - ✅ **Accurate Filling**: Uses actual ad durations from VAST responses
616
+ - ✅ **Less Waste**: Doesn't over-request ads unnecessarily
617
+ - ✅ **Flexible**: Adapts to GAM returning 15s, 30s, 60s, or mixed-length ads
618
+ - ✅ **Efficient**: Fetches durations while preloading, no extra latency
619
+ - ✅ **Smart**: Improves calculation as more data is gathered (uses average of fetched durations)
620
+ - ✅ **Self-Correcting**: Automatically adjusts if actual ad lengths differ from expectations
621
+
504
622
  ### Manual Ad Player Override
505
623
 
506
624
  You can still manually override the ad player type if needed: