Files
RDJ-np-widget/README.md
2026-04-12 21:42:24 -04:00

12 KiB
Raw Permalink Blame History

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

  1. Place these files in /new-make-rdj/ directory
  2. Create three files in the same directory:
    • artist.txt - Contains artist name
    • title.txt - Contains song title
    • Album-Art.png - Album artwork (square image recommended)
  3. Use in OBS Browser Source or open index.html in 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.txt and title.txt every 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

  1. Create Browser Source in OBS
  2. Set URL:
    http://localhost/new-make-rdj/index.html
    
    Or with custom refresh rate:
    http://localhost/new-make-rdj/index.html?refreshrate=6
    
  3. Set Canvas Size: 650×200 pixels (or larger, widget will scale)
  4. Enable Refresh: Ensure "Refresh browser when scene becomes active" is checked
  5. 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):

  1. Open script.js
  2. Find this line near the top (around line 9):
    const IMAGE_FILENAME = "Album-Art.png";
    
  3. Change it to your filename:
    const IMAGE_FILENAME = "cover.jpg";
    
  4. 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)

  1. Fetch: Requests artist.txt and title.txt from the server
  2. Compare: Checks if content differs from current display
  3. Update: Only refreshes DOM if content changed
  4. Cache Bust: Appends timestamp to image URL when track changes
    • Example: Album-Art.png?v=1711701234567
  5. 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:

  1. VS Code Live Server (Recommended)

    • Install "Live Server" extension in VS Code
    • Right-click index.html → "Open with Live Server"
  2. Python (Built-in on most systems)

    python -m http.server 8000
    # Then open: http://localhost:8000/new-make-rdj/index.html
    
  3. Node.js

    npx http-server
    # Then open: http://localhost:8080/new-make-rdj/index.html
    
  4. 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:

  1. Monitor your music source (local player, streaming API, etc.)
  2. Update these three files in the /new-make-rdj/ directory:
    • artist.txt → Current artist
    • title.txt → Current title
    • Album-Art.png → Current album artwork
  3. Write atomically (avoid partial updates) for reliability
  4. 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:

  1. Verify files exist in /new-make-rdj/:
    • artist.txt, title.txt, Album-Art.png
  2. Check browser console (F12) for errors:
    • Look for CORS, 404, or network errors
  3. 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:

  1. Increase background darkness:
    filter: blur(40px) brightness(0.5);  /* Reduce brightness */
    
  2. Increase text shadow:
    text-shadow: 3px 3px 8px rgba(0, 0, 0, 1);  /* Darker/bigger shadow */
    
  3. Verify CSS file is loaded (check DevTools → Styles)
  4. 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:

  1. Refresh the browser source:
    • Right-click browser source → Refresh
  2. Restart OBS completely
  3. Verify backend is actually updating the image file
  4. Check file permissions are readable
  5. 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:

  1. Increase OBS canvas size:
    • Recommended minimum: 650×200px
    • Recommended ideal: 800×240px or larger
  2. Check browser zoom (should be 100%)
  3. 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?

  1. Check the Troubleshooting section
  2. Verify all three required files exist in /new-make-rdj/
  3. Ensure you're using a local server (not file:// protocol)
  4. Check browser console (F12) for error messages
  5. Verify backend is updating text files correctly

Tested with: OBS 28+, Chrome 120+, Firefox 121+, Safari 16+