Radio DJ Now Playing Widget
A professional music widget perfect for streamers and broadcasters. Display the currently playing song with a beautiful blurred album art background, crystal-clear track information, and automatic refresh every 6 seconds.
Perfect for: OBS streams, web overlays, Radio station websites, Music player displays
Quick Start
- Place these files in
/new-make-rdj/directory - Create three files in the same directory:
artist.txt- Contains artist nametitle.txt- Contains song titleAlbum-Art.png- Album artwork (square image recommended)
- Use in OBS Browser Source or open
index.htmlin a local server
Core Features
✨ Beautiful Design
- Dark rounded-corner container (border-radius: 20px)
- Heavy blur effect on album artwork (blur 40px + 60% brightness)
- Large, bold typography (30px title, 22px artist)
- Strong text-shadow for readability:
2px 2px 5px rgba(0,0,0,0.9)
🔄 Smart Refresh Engine
- Polls
artist.txtandtitle.txtevery 6 seconds (default) - Only updates display when content actually changes
- Automatic cache-busting with timestamps (
?v=parameter)
⚙️ Flexible Configuration
- Override refresh rate via URL parameter:
?refreshrate=10 - Easy font size customization in CSS
- Simple image filename change in JavaScript
File Requirements
Required Files in /new-make-rdj/ directory:
| File | Purpose | Format |
|---|---|---|
artist.txt |
Current artist name | Plain text, single line |
title.txt |
Current song title | Plain text, single line |
Album-Art.png |
Album artwork | Image (PNG recommended) |
Example Files:
artist.txt:
The Weeknd
title.txt:
Blinding Lights
Album-Art.png
- Should be square (e.g., 500×500px, 1000×1000px)
- PNG format recommended for transparency support
- Updated by your backend whenever the track changes
Usage
Basic Usage
Open in a browser that supports local file access (requires Live Server extension) or place behind a web server:
http://localhost/new-make-rdj/index.html
NOTE: Due to browser security (CORS), you cannot directly open the HTML file with file:// protocol. You must use:
- VS Code Live Server extension (recommended)
- Python:
python -m http.server 8000 - Node.js:
npx http-server - OBS Browser Source (has built-in local access)
Custom Refresh Rate
Override the default 6-second refresh rate:
http://localhost/new-make-rdj/index.html?refreshrate=10
Examples:
?refreshrate=3- Check every 3 seconds (more responsive, more network load)?refreshrate=6- Default (balanced)?refreshrate=15- Check every 15 seconds (less network load)
OBS Integration
- Create Browser Source in OBS
- Set URL:
Or with custom refresh rate:
http://localhost/new-make-rdj/index.htmlhttp://localhost/new-make-rdj/index.html?refreshrate=6 - Set Canvas Size: 650×200 pixels (or larger, widget will scale)
- Enable Refresh: Ensure "Refresh browser when scene becomes active" is checked
- Done! The widget updates automatically
Customization Guide
Changing Title Font Size
Edit style.css and find this section:
/* Song title */
.song-title {
font-size: 30px; /* ← Change this value */
font-weight: 700;
color: #ffffff;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -0.5px;
line-height: 1.1;
}
Tips:
- Reduce to 24px-26px for more character room
- Increase to 32px-36px for larger screens
- Test with your longest song titles
Changing Artist Font Size
Edit style.css and find this section:
/* Song artist */
.song-artist {
font-size: 22px; /* ← Change this value */
font-weight: 500;
color: #ffffff;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -0.3px;
line-height: 1.1;
opacity: 1;
}
Tips:
- Keep it 5-8px smaller than title for visual hierarchy
- Recommended range: 16px-24px
- Test with your longest artist names
Changing Image Filename
If your backend uses a different filename (e.g., cover.jpg instead of Album-Art.png):
- Open
script.js - Find this line near the top (around line 9):
const IMAGE_FILENAME = "Album-Art.png"; - Change it to your filename:
const IMAGE_FILENAME = "cover.jpg"; - Save the file
Supported formats:
- PNG (recommended)
- JPG/JPEG
- WebP
- GIF
The cache-busting mechanism (?v=timestamp) works with any format.
Other Customizations
Blur Strength
Edit in style.css, .background-image section:
filter: blur(40px) brightness(0.6); /* Change 40px to adjust blur */
- Increase blur value (e.g., 50px) for more blur
- Decrease blur value (e.g., 30px) for less blur
- Adjust brightness (0.6 = 60% intensity) from 0.3 to 0.8
Container Padding and Spacing
Edit in style.css, .widget-content section:
gap: 24px; /* Space between album art and text */
padding: 20px; /* Space inside container around all edges */
Text Shadow Intensity
Edit in style.css, both .song-title and .song-artist:
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
/* ↑ x-offset ↑ y-offset ↑ blur-radius ↑ color + opacity */
- More blur = softer shadow (e.g., 8px)
- Less blur = harder shadow (e.g., 3px)
- Change opacity (0.9 = 90%) for more/less darkness
How It Works
Refresh Cycle (every 6 seconds or custom interval)
- Fetch: Requests
artist.txtandtitle.txtfrom the server - Compare: Checks if content differs from current display
- Update: Only refreshes DOM if content changed
- Cache Bust: Appends timestamp to image URL when track changes
- Example:
Album-Art.png?v=1711701234567
- Example:
- Display: Updates artist and title on-screen
Why Cache Busting?
OBS (and browsers) cache images by filename. Without cache busting:
- The old album art would display for 5-10 seconds
- User would see wrong artwork until cache expired
By appending ?v= with a timestamp:
- Each request looks "new" to cached systems
- Forces reload of latest artwork
- Works immediately in OBS without manual clearing
Auto-Image Update on Track Change
The widget is smart about image updates:
- Only updates images when track changes (not on every poll)
- Detects change when artist OR title changes
- Prevents unnecessary re-fetches when nothing changed
- Significantly reduces network traffic
Technical Requirements
Browser Compatibility
- Chrome/Chromium ✅
- Firefox ✅
- Safari ✅
- OBS Browser Source ✅
Local File Access
⚠️ IMPORTANT: Due to browser security (CORS), local HTML files need a server.
Setup Options:
-
VS Code Live Server (Recommended)
- Install "Live Server" extension in VS Code
- Right-click
index.html→ "Open with Live Server"
-
Python (Built-in on most systems)
python -m http.server 8000 # Then open: http://localhost:8000/new-make-rdj/index.html -
Node.js
npx http-server # Then open: http://localhost:8080/new-make-rdj/index.html -
OBS Browser Source
- OBS has built-in local file access
- Use:
http://localhost/new-make-rdj/index.html
Backend Integration
For your backend service to work with the widget, it should:
- Monitor your music source (local player, streaming API, etc.)
- Update these three files in the
/new-make-rdj/directory:artist.txt→ Current artisttitle.txt→ Current titleAlbum-Art.png→ Current album artwork
- Write atomically (avoid partial updates) for reliability
- Update image file to ensure cache-busting works
Example backend update (Python):
import shutil
from pathlib import Path
def update_now_playing(artist, title, artwork_path):
# Write text files
Path("artist.txt").write_text(artist)
Path("title.txt").write_text(title)
# Copy artwork (forces new file timestamp)
shutil.copy2(artwork_path, "Album-Art.png")
print(f"Updated: {artist} - {title}")
Example (Node.js):
const fs = require('fs');
const path = require('path');
function updateNowPlaying(artist, title, artworkPath) {
fs.writeFileSync('artist.txt', artist);
fs.writeFileSync('title.txt', title);
fs.copyFileSync(artworkPath, 'Album-Art.png');
console.log(`Updated: ${artist} - ${title}`);
}
Troubleshooting
"Loading..." displays indefinitely
Possible causes:
- Files not in the correct directory
- Browser can't access local files (need Live Server)
- Filename typo (case-sensitive on Linux/Mac)
Solutions:
- Verify files exist in
/new-make-rdj/:artist.txt,title.txt,Album-Art.png
- Check browser console (F12) for errors:
- Look for CORS, 404, or network errors
- Set up a local server (Live Server, Python, etc.)
Text is hard to read or washed out
Possible causes:
- Album artwork is too bright
- Text shadow isn't rendering properly
- Dark overlay isn't dark enough
Solutions:
- Increase background darkness:
filter: blur(40px) brightness(0.5); /* Reduce brightness */ - Increase text shadow:
text-shadow: 3px 3px 8px rgba(0, 0, 0, 1); /* Darker/bigger shadow */ - Verify CSS file is loaded (check DevTools → Styles)
- Try with a different album artwork image
Album art not updating in OBS
Possible causes:
- OBS cache not being bypassed
- Image file permissions issue
- Backend not updating files correctly
Solutions:
- Refresh the browser source:
- Right-click browser source → Refresh
- Restart OBS completely
- Verify backend is actually updating the image file
- Check file permissions are readable
- Check browser console (F12) for fetch errors
Widget appears too small or too large
Possible causes:
- OBS canvas size too small
- Browser zoom level incorrect
- CSS container size needs adjustment
Solutions:
- Increase OBS canvas size:
- Recommended minimum: 650×200px
- Recommended ideal: 800×240px or larger
- Check browser zoom (should be 100%)
- Adjust container max-width in CSS:
.widget-container { max-width: 650px; /* ← Increase this, e.g., to 800px */ }
Video keeps buffering when opening HTML directly
This is the CORS security issue. You MUST use a local server. See "Local File Access" section above.
Design Specifications
Current Settings
/* Container */
border-radius: 20px;
max-width: 650px;
height: 200px;
/* Background Blur */
filter: blur(40px) brightness(0.6);
/* Album Art */
width: 140px;
height: 140px;
/* Title Text */
font-size: 30px;
font-weight: 700;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
/* Artist Text */
font-size: 22px;
font-weight: 500;
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.9);
Configuration Summary
| Setting | Location | Default | How to Change |
|---|---|---|---|
| Refresh Rate | URL | 6 seconds | ?refreshrate=X |
| Title Size | style.css |
30px | .song-title { font-size: __ } |
| Artist Size | style.css |
22px | .song-artist { font-size: __ } |
| Image Filename | script.js |
Album-Art.png | const IMAGE_FILENAME = "..." |
| Blur Intensity | style.css |
40px | .background-image { filter: blur(__px) } |
| Container Width | style.css |
650px | .widget-container { max-width: __ } |
| Container Height | style.css |
200px | .widget-container { height: __ } |
File Reference
- index.html - Main HTML structure (semantic class-based design)
- style.css - Complete styling, layout, animations, and design
- script.js - Polling logic, cache-busting, DOM updates
- README.md - This documentation
Support
Questions or issues?
- Check the Troubleshooting section
- Verify all three required files exist in
/new-make-rdj/ - Ensure you're using a local server (not
file://protocol) - Check browser console (F12) for error messages
- Verify backend is updating text files correctly
Tested with: OBS 28+, Chrome 120+, Firefox 121+, Safari 16+