Stashbox Radio
A custom RDS-backed music, video, merchandise, and advertising platform built to feel simple on the surface while running a sophisticated stack underneath.
Executive Summary
Stashbox Radio began as a music player and evolved into a custom media platform that connects songs, videos, merchandise, advertising, analytics, and admin publishing tools into one lightweight experience. The public player is intentionally simple: a listener can play a song, watch a video, like, share, shop, and continue through the catalog. Behind that simple interface is a custom backend system using AWS, PostgreSQL, API Gateway, Lambda, S3 media, and a custom admin console.
The sophistication of the system is in its simplicity. The user sees a radio experience. The admin sees editable song records, product links, ads, settings, and stats. The platform quietly handles media playback, deep links, persistent likes, ad delivery rules, ad tracking, product carousels, and RDS-backed content management without requiring a full commercial CMS.
Primary Tools and Platforms Used
Frontend
- HTML for page structure
- CSS for responsive player/admin styling
- JavaScript for player logic, UI state, tracking, filters, ads, and admin forms
- GitHub Pages for static site hosting
Backend
- AWS Lambda running Node.js 22.x
- AWS API Gateway HTTP API
- PostgreSQL on AWS RDS
- DBeaver for RDS inspection and SQL updates
- CloudWatch for Lambda logs and error diagnosis
Media and Commerce
- AWS S3 for audio, artwork, and ad media files
- YouTube embeds for music videos and video-only records
- Shopify product data for merch cards
- Specific product URLs per song
- Future external Shopify metadata support planned
Languages and Technical Stack
The Architecture
The architecture separates the public listening experience from the admin publishing experience. The public site is static and fast. The dynamic behavior comes from API calls to Lambda, which reads and writes to RDS.
The browser opens /radio/ or /radio/dev/ and loads songs, counts, ad settings, products, and active ads from API endpoints.
API Gateway routes requests into the Lambda function, which normalizes paths, validates requests, and queries PostgreSQL.
Songs, ads, settings, likes, stats events, product URLs, and admin-managed fields live in PostgreSQL.
The admin dashboard edits songs, saves specific product URLs, manages ads, updates ad delivery settings, and reviews stats.
Likes, plays, shares, ad starts, ad clicks, ad skips, product clicks, and other events are tracked through API calls.
Public Radio Player Features
Music and Video
- Audio-only songs
- Song plus video records
- Video-only tracks
- YouTube video support
- Deep links by song key, such as
/radio/?song=<song_key> - Spacebar play/pause behavior
- Mobile and desktop playback handling
Engagement
- Persistent likes saved to RDS
- Share links using production song URLs
- Play counts
- Product click tracking
- Video click tracking
- Mobile share URL repair
Shopping
- Song-specific product URLs
- Fallback Shopify product carousel
- Product cards with image, title, and price where available
- Specific product links saved from admin
- Future support for external Shopify metadata
Sorting and Filtering
- Song list filtering
- Videos-only quick filter
- Shuffle all
- Latest sorting
- Most played sorting support
- Reset filters
Admin System
The admin system turns Stashbox Radio into a manageable platform rather than a hard-coded player. The admin can edit songs, manage product links, review dashboard stats, archive records, and operate the ad system.
Dashboard
- Operational stats
- Play starts
- Shares
- Likes
- Product clicks
- Listening time
Song Management
- Edit Song loads saved RDS data
- Save Song updates RDS
- Specific product URLs save correctly
- Public notes and internal notes
- Artist, genre, mood, release format, artwork, video, and audio fields
Ads Admin
- Ad inventory list
- Ad title and description
- Active/inactive controls
- Ad ratio and media metadata
- View, click, skip, CTR, and skip-rate stats
API Overview
The system uses a practical REST-style API design. Static pages stay simple and fast, while dynamic data is requested only when needed.
/radio/songs/radio/ads/radio/ad-settings/radio/track/admin/stats/summary/admin/songs/admin/songs/:song_key/admin/songs/:song_key/admin/ads/admin/ads/admin/ads/:id/admin/ads/:id/admin/ad-settings/admin/ad-settings/admin/uploads/presignHow the Ads Roll
The ad system functions like a lightweight custom ad server for Stashbox Radio. Ads are stored in RDS, served through the public API, controlled by the admin panel, and tracked through events.
Ad Inventory
- Ad title
- Description
- Video URL
- Click URL
- Ratio label and dimensions
- Skip-after seconds
- No-skip option
- Active/hidden status
- Frequency/rotation weight
- Optional genre, mood, artist, and song targeting fields
Ad Playback UX
- Ads play after songs or videos based on controller settings
- Ad title and description show in the ad player
- Learn More button opens the CTA link
- Skip countdown shows when skipping is allowed
- Ad duration shows as current time / total time
- Ad break indicator shows progress, such as Ad 2 of 4
- Seconds mode can show a master ad break countdown
- Tap-to-resume handles paused ad playback
Two Ad Delivery Methodologies
Method 1: By Number of Ads
The admin can choose how many ads play in a break. Current options are 1, 2, 3, 4, or 5 ads per break.
- Example: Ads Per Break = 3
- The listener sees Ad 1 of 3, Ad 2 of 3, Ad 3 of 3
- After the final ad, the next song or video resumes
Method 2: By Total Seconds
The admin can choose a target amount of ad time, such as 15, 30, 45, 60, or 90 seconds.
- Example: Target Ad Break Length = 30 seconds
- The player continues selecting ads until the break reaches the target duration
- This prevents one short 5-second ad from counting as a full break
Ad Rotation and Frequency
Each ad has a Low, Medium, or High frequency setting. This is best understood as rotation weight, not break frequency. High-weight ads are more likely to be selected. Low-weight ads are less likely. The break frequency itself is controlled by the Ad Controller.
Ad Controller Settings
- Master Ads On/Off: turns ad breaks on or off globally.
- Ad Break Method: chooses count mode or seconds mode.
- Ads Per Break: used when the method is by number of ads.
- Target Ad Break Length: used when the method is by total seconds.
- Ad Break Timing: controls whether breaks happen after every song/video, every 2, or every 3.
Sort Methods and Discovery
Stashbox Radio uses simple listener-facing controls to keep discovery easy. The goal is not to overload the listener with a complex database interface. It is to give them fast ways to find songs and videos.
Latest
Sorts the catalog toward newer or recently added content, helping the radio experience feel alive and current.
Most Played
Uses play metrics to surface tracks with stronger listener activity.
Videos Filter
Quickly narrows the catalog to songs and records with video content.
Shuffle All
Creates a radio-style experience by moving away from manual selection and into discovery mode.
Deep Links
Every song can be shared as a direct URL using a song key.
Search and Filters
The player supports simple filtering across song, album, artist, and metadata-oriented discovery.
Data Model Overview
The database model is built around a few practical entities rather than an overcomplicated enterprise CMS.
Songs
- Song key
- Song name and display title
- Artist
- Genre and secondary genre
- Mood and mood tags
- Release format
- Album name
- Audio URL
- Video URL or YouTube link
- Artwork URL
- Specific product URLs
- Persistent likes
- Visibility and feature flags
Ads
- Ad title
- Description
- Video URL
- Click URL
- Frequency weight
- Skip settings
- Views
- Clicks
- Skips
- CTR
- Skip rate
- Targeting fields
Ad Settings
- Master ads enabled
- Break method
- Ads per break
- Target seconds
- Break interval
Events and Analytics
- Play starts
- Full plays
- Partial plays
- Likes
- Shares
- Video clicks
- Product clicks
- Ad starts
- Ad clicks
- Ad skips
- Ad completes
Sophistication Through Simplicity
The platform avoids the trap of looking complicated to the user. The public interface is simple enough for a fan to understand instantly, while the backend keeps track of many moving pieces.
Simple to the Listener
- Click play
- Watch a video
- Like a song
- Share a link
- Shop the track
- Continue listening
Sophisticated Underneath
- RDS-backed song records
- Persistent likes and stats
- Ad server logic
- Ad controller settings
- Count-based and seconds-based ad breaks
- Shopify product integrations
- Admin dashboard and edit flows
Project Timeline
Built the public Stashbox Radio experience with song cards, playback controls, artwork, video support, basic filtering, and shopping placement.
Established a safer workflow separating /radio/dev/ from /radio/ and /radio-admin/dev/ from /radio-admin/.
Connected the system to AWS RDS PostgreSQL using Lambda and API Gateway. Songs and stats began moving away from legacy static or sheet-based workflows.
Expanded the admin environment so song records could load from RDS, be edited, saved, and managed with metadata fields.
Added RDS-backed ad inventory with video URLs, click URLs, active status, frequency weight, and public ad loading.
Added ad views, clicks, skips, CTR, and skip-rate tracking. Improved skip countdown, Learn More click behavior, and ad resume handling.
Added admin-controlled ad delivery settings including master ads on/off, ads per break, target ad seconds, and ad break timing. Added count mode and seconds mode.
Fixed Edit Song product URL saving, added persistent likes to RDS, repaired deep-link likes, and made song-specific product links usable in the public player.
Promoted tested dev work from /radio/dev/ to /radio/, from /radio-admin/dev/ to /radio-admin/, and from /radio-admin/dev/ads/ to /radio-admin/ads/, with backups and rollback awareness.
Planned expansion to fetch product image, title, price, and source metadata from outside Shopify stores when those stores allow metadata access.
Current Environment URLs
Future Roadmap
External Product Metadata
Add metadata fetching for external Shopify and product URLs that allow data access. Cards should show image, title, price, and source when available, with a clean fallback when blocked.
Production API Separation
The current working API base may still include a dev name. A future cleanup can create separately named production Lambda/API resources once the system is fully stabilized.
Expanded Ad Targeting
Genre, mood, artist, and song targeting can become smarter so ads can match the listening context more precisely.
Intro and Outro System
Add randomized DJ-style voice intros and outros by global, artist, genre, or song-specific rules.
Additional Analytics
Expand dashboards with completion curves, repeat listeners, product conversion paths, and ad break performance by setting.
CloudFront Media Optimization
Add or expand CDN delivery for audio, artwork, and ad media to improve speed and reduce direct S3 delivery dependency.
Conclusion
Stashbox Radio is now a custom digital music platform with a strong foundation: a public player, RDS-backed content, admin publishing tools, ad inventory, ad delivery controls, persistent likes, product links, and analytics. The system is built in a way that keeps the fan experience simple while giving the admin practical control over the catalog, ads, and engagement data.
The project demonstrates a useful model for independent music brands: own the platform, own the data, connect the music directly to merchandise, and create a custom ad system that can grow without depending entirely on third-party platforms.