Ad Scheduler Documentation
Overview
The AdScheduler is responsible for determining when ads should be shown to users. It balances revenue optimization with user experience by implementing frequency caps, cooldown periods, and session limits.
Table of Contents
- Preroll Ads
- Midroll Ads
- Session Management
- Configuration Options
- Decision Flow Diagrams
- GAM Integration
- Testing & Debugging
1. Preroll Ads
Preroll ads play before the audio content starts.
Default Configuration
| Parameter | Default Value | Description |
|---|---|---|
enabled | true | Enable/disable preroll ads |
initialDelay | 1 | Show preroll on Nth play (1 = first play) |
frequency | 3 | After initial, show every Nth play |
minAudioDuration | 30 seconds | Minimum audio length to show preroll |
cooldownMinutes | 3 | Minutes between preroll ads (preroll-only) |
Frequency Pattern
With default settings (initialDelay: 1, frequency: 3):
| Play # | Preroll Shown? | Reason |
|---|---|---|
1 | ✅ Yes | Matches initialDelay |
2 | ❌ No | Not on frequency |
3 | ❌ No | Not on frequency |
4 | ✅ Yes | (4-1) % 3 === 0 |
5 | ❌ No | Not on frequency |
6 | ❌ No | Not on frequency |
7 | ✅ Yes | (7-1) % 3 === 0 |
... | ... | Pattern continues |
Skip Conditions
Preroll will be skipped if ANY of these conditions are true:
- Preroll disabled -
data-preroll="false" - Audio too short - Duration < 30 seconds
- Autoplay on first play - Prevents bad UX on auto-playing content
- Cooldown active - A preroll was shown within the last 3 minutes
- Hourly limit reached - 12+ ads already shown this hour
- Not on frequency - Play count doesn't match the frequency pattern
2. Midroll Ads
Midroll ads play during the audio content at strategic positions.
Default Configuration
| Parameter | Default Value | Description |
|---|---|---|
enabled | true | Enable/disable midroll ads |
minAudioDuration | 300 seconds (5 min) | Minimum audio length for midrolls |
minIntervalSeconds | 240 seconds (4 min) | Minimum gap between midrolls |
maxMidrollsPerContent | 3 | Maximum midrolls per audio |
avoidStartEndSeconds | 60 seconds | No ads in first/last 60 seconds |
Midroll Positioning
| Audio Duration | Number of Midrolls | Positions |
|---|---|---|
< 5 minutes | 0 | None |
5-15 minutes | 1 | 50% (middle) |
15-30 minutes | 2 | 33%, 67% |
30+ minutes | 3 | Evenly distributed |
Example: 20-minute Audio
Audio Timeline: |----|----|----|----|----|----|----|----|----|----| 0 2 4 6 8 10 12 14 16 18 20 min Midroll Positions: - Position 1: ~6:40 (33%) - Position 2: ~13:20 (67%) Safe Zones (no ads): - First 60 seconds: 0:00 - 1:00 - Last 60 seconds: 19:00 - 20:00
3. Session Management
The scheduler tracks ad delivery across the entire user session.
Session Configuration
| Parameter | Default Value | Description |
|---|---|---|
maxAdsPerHour | 12 | Maximum ads per rolling hour |
cooldownMinutes | 3 | Minimum minutes between preroll ads |
resetAfterMinutes | 30 | Session resets after inactivity |
Session Data Stored
The scheduler persists the following in sessionStorage:
javascript{
startTime: 1701234567890, // Session start timestamp
lastActivity: 1701234567890, // Last user activity
totalAdsServed: 3, // Ads shown this session
lastAdTime: 1701234500000, // Last ad timestamp
lastPrerollTime: 1701234500000, // Last preroll timestamp (for cooldown)
audioPlays: 5, // Total audio plays
prerollsServed: 2 // Prerolls shown
}
Session Key
- Storage key:
mt_ad_session - Automatically expires after 30 minutes of inactivity
4. Configuration Options
HTML Attributes
html<div data-mediathrive
data-ads="true"
data-preroll="true"
data-preroll-frequency="3"
data-preroll-delay="1"
data-midroll="true"
data-midroll-min-duration="480"
data-ad-account="23311059090"
data-ad-unit="/custom/ad/unit"
data-vast="https://example.com/vast.xml">
</div>
Attribute Reference
| Attribute | Type | Default | Description |
|---|---|---|---|
data-ads | boolean | false | Enable ads system |
data-preroll | boolean | true | Enable preroll ads |
data-preroll-frequency | number | 3 | Preroll frequency (every Nth play) |
data-preroll-delay | number | 1 | Initial play to show first preroll |
data-midroll | boolean | true | Enable midroll ads |
data-midroll-min-duration | number | 480 | Min seconds for midrolls |
data-ad-account | string | (default) | GAM account ID |
data-ad-unit | string | (auto) | Custom ad unit path |
data-vast | string | (none) | Direct VAST URL (bypasses GAM) |
5. Decision Flow Diagrams
Preroll Decision Flow
┌─────────────────────────────────────────────────────────────┐ │ USER CLICKS PLAY │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────┐ │ Preroll enabled? │ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ Audio >= 30s? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ Autoplay + 1st? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ YES │ NO ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ In cooldown? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ YES │ NO ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ Hourly limit? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ YES │ NO ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ On frequency? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Play content │ │ SHOW PREROLL │ └─────────────────┘ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Play content │ └─────────────────┘
Midroll Decision Flow
┌─────────────────────────────────────────────────────────────┐ │ AUDIO PROGRESS UPDATE (every 2s) │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────┐ │ Midroll enabled? │ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Continue │ │ Audio >= 8min? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Continue │ │ At midroll pos? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ NO │ YES ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Continue │ │ Already played? │ └─────────────────┘ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ YES │ NO ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Continue │ │ SHOW MIDROLL │ └─────────────────┘ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Resume content │ └─────────────────┘
6. GAM Integration
Tracked Events
The IMA SDK automatically reports these events to Google Ad Manager:
| Event | Description | When Fired |
|---|---|---|
IMPRESSION | Ad was viewed | When ad starts |
STARTED | Ad playback began | When ad starts |
FIRST_QUARTILE | 25% viewed | At 25% progress |
MIDPOINT | 50% viewed | At 50% progress |
THIRD_QUARTILE | 75% viewed | At 75% progress |
COMPLETE | 100% viewed | When ad finishes |
SKIPPED | User skipped ad | When skip clicked |
CLICK | User clicked ad | On ad click |
PAUSED | Ad paused | On pause |
RESUMED | Ad resumed | On resume |
Ad Tag URL Structure
https://pubads.g.doubleclick.net/gampad/ads? iu=/23311059090/mediathrive.com//audio//preroll # Ad unit &description_url=https://example.com/article # Page URL &tfcd=0 # Child-directed &npa=0 # Non-personalized &ad_type=audio # Ad type &sz=1x1 # Size &cust_params=domain%3Dexample.com%26position%3Dpreroll # Custom params &gdfp_req=1 &unviewed_position_start=1 &output=vast &env=vp &vpos=preroll # Position &vpmute=0 &vpa=click # Auto/click
7. Testing & Debugging
Console Logs
With data-log-level="DEBUG", you'll see:
[AdScheduler] Checking preroll - audioId: abc123, duration: 72s, isAutoplay: false [AdScheduler] Play #1 for audio abc123 [AdScheduler] Preroll APPROVED for play #1 of audio abc123 [IMAAdManager] GAM: Impression tracked [IMAAdManager] GAM: First quartile (25%) tracked [IMAAdManager] GAM: Midpoint (50%) tracked [IMAAdManager] GAM: Third quartile (75%) tracked [IMAAdManager] Ad completed
Clear Session for Testing
To reset the ad scheduler state:
javascript// In browser console
sessionStorage.removeItem('mt_ad_session');
location.reload();
Force Show Preroll
To test preroll without scheduler restrictions:
javascript// Temporarily bypass scheduler
window.MTMediaKit.getInstance('player-id').ads.playPreRoll(null, false);
Check Current Session
javascript// View current session data
JSON.parse(sessionStorage.getItem('mt_ad_session'));
Common Issues
| Issue | Cause | Solution |
|---|---|---|
No preroll on first play | Cooldown from previous session | Clear mt_ad_session |
Ads never show | data-ads not set to "true" | Add data-ads="true" |
CORS errors | CDN missing headers | Add CORS headers to ad server |
Skip not working | IMA SDK restrictions | Wait for skip delay (6s) |
Appendix: Code References
| File | Description |
|---|---|
src/lib/ads/AdScheduler.js | Core scheduling logic |
src/providers/GoogleAdsProvider.js | IMA SDK integration |
src/lib/ima/IMAAdManager.js | Ad playback management |
src/components/player/AdDisplay.js | Ad UI overlay |
src/components/player/PlayButtonWithAds.js | Play button with ad intercept |
Version History
| Version | Date | Changes |
|---|---|---|
1.0 | 2024-12 | Initial scheduler implementation |
Document generated for MediaThrive Ads Team