Raven Scott Music
Raven Scott Music is a sophisticated, dark-themed web application designed to curate and display music playlists from SoundCloud across three genres: Metal, Alt Rock, and Rap. Built with Node.js, Express, and EJS, this project combines server-side rendering, efficient caching, and a responsive front-end to deliver a seamless music discovery experience. Whether you're a developer looking to explore the code or a music enthusiast browsing tracks, this app offers a robust foundation with plenty of room for customization.
Table of Contents
- Features
- Live Demo
- Prerequisites
- Installation
- Usage
- Technical Overview
- File Structure
- Tech Stack Rationale
- Configuration
- Deployment
- Development
- Troubleshooting
- License
- Acknowledgments
Features
- Genre-Specific Playlists: Dynamically fetches and displays tracks from SoundCloud playlists for Metal, Alt Rock, and Rap.
- Efficient Caching: Stores playlist data in local JSON files, refreshing only after a week to minimize API calls and improve load times.
- Responsive UI: Leverages Bootstrap 4.5.2 and custom CSS for a mobile-friendly, dark-mode interface with orange accents.
- Track Pages: Dedicated pages for each track with embedded SoundCloud players, titles, and descriptions.
- SEO Optimization: Generates a
sitemap.xml
dynamically for better search engine visibility. - JSON API: Provides a RESTful endpoint (
/json/:genre
) for programmatic access to track data. - Custom Styling: Features a slim dark-mode scrollbar, animated navbar hover effects, and a cohesive aesthetic tailored for music lovers.
- Sorting Logic: Tracks are sorted by play count (descending) and then by publication date (newest first) for a curated experience.
Live Demo
Explore the live site at raven-scott.rocks. Check out the Metal, Alt Rock, and Rap sections, dive into individual track pages, or inspect the sitemap at /sitemap.xml
.
Prerequisites
To run this project locally, ensure you have:
- Node.js: Version 14.x or higher (includes npm).
- npm: Package manager for installing dependencies.
- SoundCloud Access: The playlists specified in
music_site.js
must be public and accessible via thesoundcloud-scraper
library. - Git: For cloning the repository (optional but recommended).
Installation
-
Clone the Repository:
git clone https://git.ssh.surf/snxraven/ravenscott-rocks.git cd ravenscott-rocks
-
Install Dependencies:
npm install
This installs
express
,soundcloud-scraper
,ejs
, and other required packages listed inpackage.json
. -
Optional: Environment Variables:
- Create a
.env
file in the root directory to customize the port:PORT=6767
- Alternatively, set the
PORT
variable in your terminal:export PORT=6767 # Linux/macOS set PORT=6767 # Windows
- Create a
-
Start the Server:
node music_site.js
The app will run on
http://localhost:6767
(or your specified port). Open this URL in your browser to begin exploring.
Usage
- Home Page (
/
): Displays all genre playlists with embedded SoundCloud players and "More Details" links. - Genre Navigation (
/#genre
): Use the navbar to jump to specific genres (e.g.,#metal
,#altrock
,#rap
). - Track Details (
/:genre/track/:slug
): Click "More Details" to view a track’s page with its SoundCloud player and description. - JSON API (
/json/:genre
): Fetch raw track data for a genre (e.g.,http://localhost:6767/json/metal
) in JSON format. - Sitemap (
/sitemap.xml
): Access a dynamically generated sitemap for SEO purposes.
Example API response:
[
{
"title": "Heavy Riffs",
"description": "A brutal metal track.",
"url": "https://soundcloud.com/snxraven/heavy-riffs",
"playCount": 1200,
"publishedAt": "2023-05-10T12:00:00Z",
"slug": "heavy-riffs"
}
]
Technical Overview
Backend
- Framework: Uses Express.js to handle routing, static file serving, and API endpoints.
- SoundCloud Integration: The
soundcloud-scraper
library fetches playlist data, including track titles, URLs, play counts, and publication dates. - Routing:
/
: Renders the home page with all genres./:genre
: Redirects to the home page’s genre section (e.g.,/#metal
)./:genre/track/:slug
: Renders individual track pages./json/:genre
: Returns track data in JSON./sitemap.xml
: Generates an XML sitemap.
- Slug Generation: Converts track titles into URL-friendly slugs (e.g., "Heavy Riffs" →
heavy-riffs
).
Frontend
- Templating: EJS renders dynamic HTML with data from the backend.
- Styling:
- Bootstrap 4.5.2 (via CDN) provides the grid system and card components.
- Custom CSS adds a dark theme, orange buttons, a fixed navbar with hover animations, and a slim scrollbar.
- Scripts: jQuery, Popper.js, and Bootstrap JS (via CDN) enable navbar toggling and other interactive elements.
Caching Mechanism
- Purpose: Reduces API calls to SoundCloud by storing playlist data locally.
- Implementation:
- Cache files (
cache_metal.json
, etc.) store tracks and a timestamp. - The
getTracks
function checks if the cache is older than 1 week (configurable viaoneWeekInMs
). - If outdated or missing, it fetches fresh data and updates the cache.
- Cache files (
- Sorting: Tracks are sorted by play count (highest first) and then by publication date (newest first).
File Structure
raven-scott-music/
├── public/ # Static assets
│ └── css/ # Custom CSS (currently empty; styles are inline in EJS)
├── views/ # EJS templates
│ ├── index.ejs # Home page with genre sections
│ ├── layout.ejs # Base layout (not fully utilized in this setup)
│ └── track.ejs # Individual track page
├── cache_metal.json # Cached Metal tracks (auto-generated)
├── cache_altrock.json # Cached Alt Rock tracks (auto-generated)
├── cache_rap.json # Cached Rap tracks (auto-generated)
├── music_site.js # Core server logic and routing
├── package.json # Project metadata and dependencies
├── package-lock.json # Dependency lock file
└── README.md # This documentation
Tech Stack Rationale
- Node.js & Express: Lightweight and fast for building a server-side application with minimal overhead.
- soundcloud-scraper: Chosen for its simplicity and ability to scrape public playlist data without requiring an official API key.
- EJS: Offers server-side rendering with easy integration into Express, ideal for dynamic content like playlists.
- Bootstrap: Speeds up development with pre-built components and ensures responsiveness out of the box.
- File-System Caching: A simple, effective solution for persistence without the complexity of a database.
Configuration
- Playlists: Modify the
playlists
object inmusic_site.js
:const playlists = { metal: { url: 'https://soundcloud.com/snxraven/sets/raven-scott-metal', ... }, // Add new genres here };
- Cache Refresh: Adjust
oneWeekInMs
(in milliseconds) ingetTracks
:const oneWeekInMs = 7 * 24 * 60 * 60 * 1000; // Change to 24 * 60 * 60 * 1000 for daily refresh
- Port: Set via
.env
or directly inmusic_site.js
:const PORT = process.env.PORT || 6767;
Development
Getting Started
- Fork and clone the repo.
- Install dependencies (
npm install
). - Run locally (
node music_site.js
). - Make changes and test in your browser.
Enhancement Ideas
- Database Integration: Replace file caching with MongoDB or SQLite for scalability.
- Search Functionality: Add a search bar to filter tracks by title or description.
- User Accounts: Implement authentication (e.g., with Passport.js) for favoriting tracks.
- Additional Platforms: Integrate Spotify or YouTube using their APIs.
- Analytics: Track page views or play counts with a tool like Google Analytics.
- Lazy Loading: Optimize the home page by loading tracks incrementally.
Troubleshooting
- SoundCloud Fetch Fails:
- Verify playlist URLs in
music_site.js
are correct and public. - Update
soundcloud-scraper
(npm install soundcloud-scraper@latest
).
- Verify playlist URLs in
- Cache Issues:
- Delete
cache_*.json
files and restart the server to force a refresh. - Check file permissions if cache files aren’t being written.
- Delete
- Port Conflicts:
- Change the
PORT
value or kill the conflicting process:lsof -i :6767 # Linux/macOS kill -9 <PID>
- Change the
- 404 Errors:
- Ensure genre or slug matches the data (case-sensitive).
- Check console logs for errors during playlist fetching.
- Styling Problems:
- Clear browser cache if CSS changes don’t appear.
- Verify CDN links for Bootstrap and jQuery are accessible.