Skip to main content

Ads (ads)

The ads deck is the station's commercial spots: downloaded Egyptian radio ads that air on a fixed cadence (AD_EVERY) rather than in a block. Files live in media/ads as AD_*.mp3, are Break-tagged and R128-mastered.

Acquisition

Ads come from yt-dlp searches — not the music queries. content-pipeline.js defines an ad query set:

اعلانات مصرية جديدة 2026
اعلان تجاري مصري 2026

yields AD_<timestamp>.mp3 into media/ads. The fetch target is 24 per refresh, the purge cap 24, and ADS_MAX_AGE_DAYS = 35 — a spot older than 35 days is retired at the next refresh.

Ad-aware dedup (why ads are refetchable)

Music uses a permanent download archive (logs/yt_download_archive.txt) that blocks re-downloading an ID forever. Ads instead use a per-run temporary archive (logs/yt_download_archive_ads_tmp.txt, deleted after the fetch), so an archived ad ID is never blocked forever — a purged spot can be re-adopted within the 45-day window. The duplicate check only blocks when the matched registry file is still live.

How the scheduler slots them

Ads air on a guaranteed cadence slot:

NAD=max(10, targetSize/8)N_{AD} = \max(10,\ \lfloor \text{targetSize} / 8 \rfloor)

so a 120-track rotation gets a spot roughly every 15 slots (~every 40–60 min), with a guard that an ad never immediately follows an ad (lastType !== 'ads'). Ads are imaging elements: 10 min cooldown, and liq_cross_duration = 0.5 (spots run 10–30 s).

Refresh budget & pool health

server.js refresh defaults ads: o.ads ?? 16; the pool-health monitor keeps the deck near its 30-file cap (restores from pro_archive if it drops below 50 %). The HEADROOM.ads purge margin keeps stale promos from surviving.

Verify on air

  1. media/ads holds a healthy deck (10–30 files) of AD_*.mp3.
  2. m3u entries: annotate:type=ads,liq_cross_duration=0.5:.
  3. Rotation cadence: an ad about every AD_EVERY slots.
  4. /api/upnext shows an ad correctly typed (not listed as a song).