stormcloud-video-player 0.2.35 → 0.3.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/README.md +118 -0
- package/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +234 -60
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +8 -3
- package/lib/index.d.ts +8 -3
- package/lib/index.js +234 -60
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +234 -60
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +8 -3
- package/lib/players/HlsPlayer.cjs +234 -60
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +234 -60
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +1 -10
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +234 -60
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
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:
|