Update README.md
This commit is contained in:
443
README.md
443
README.md
@@ -1,2 +1,443 @@
|
|||||||
# RDJ-np-widget
|
# 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:
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* 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:
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* 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):
|
||||||
|
```javascript
|
||||||
|
const IMAGE_FILENAME = "Album-Art.png";
|
||||||
|
```
|
||||||
|
3. Change it to your filename:
|
||||||
|
```javascript
|
||||||
|
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:
|
||||||
|
```css
|
||||||
|
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:
|
||||||
|
```css
|
||||||
|
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`:
|
||||||
|
```css
|
||||||
|
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)
|
||||||
|
```bash
|
||||||
|
python -m http.server 8000
|
||||||
|
# Then open: http://localhost:8000/new-make-rdj/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Node.js**
|
||||||
|
```bash
|
||||||
|
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):
|
||||||
|
```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):
|
||||||
|
```javascript
|
||||||
|
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:
|
||||||
|
```css
|
||||||
|
filter: blur(40px) brightness(0.5); /* Reduce brightness */
|
||||||
|
```
|
||||||
|
2. Increase text shadow:
|
||||||
|
```css
|
||||||
|
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:
|
||||||
|
```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
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* 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+
|
||||||
|
|||||||
Reference in New Issue
Block a user