Raven Scott Music

Raven Scott Music is a sophisticated, dark-themed web application designed to curate and display music playlists from SoundCloud across multiple genres: Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts. Built with Node.js, Express, and EJS, this project combines server-side rendering, efficient caching, pagination, and real-time updates via WebSockets to deliver a seamless music discovery experience. Whether you're a developer exploring the code or a music enthusiast browsing tracks, this app offers a robust, scalable foundation with a polished user interface.

Table of Contents

Features

  • Genre-Specific Playlists: Dynamically fetches and displays tracks from SoundCloud playlists for Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts.
  • Pagination: Displays 4 tracks per page per genre, with Previous/Next buttons for efficient navigation.
  • Real-Time Updates: Uses Socket.IO for dynamic loading of paginated track data without full page reloads.
  • Efficient Caching: Stores playlist data in local JSON files, refreshing only after a week to minimize API calls and improve load times.
  • Unique Slugs: Ensures track slugs are unique within each genre to prevent URL conflicts.
  • 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:
    • Most genres: Tracks sorted by play count (descending), then publication date (newest first).
    • Cuts genre: Tracks sorted by EP number extracted from titles (ascending).

Live Demo

Explore the live site at raven-scott.rocks. Navigate through Metal, Alt Rock, Rap, Lo-Fi, EDM, and Cuts sections using pagination controls, 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 the soundcloud.ts library.
  • Git: For cloning the repository (optional but recommended).

Installation

  1. Clone the Repository:

    git clone https://git.ssh.surf/snxraven/ravenscott-rocks.git
    cd ravenscott-rocks
    
  2. Install Dependencies:

    npm install
    

    This installs express, soundcloud.ts, ejs, socket.io, and other required packages listed in package.json.

  3. 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
      
  4. 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 paginated 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).
  • Pagination: Use Previous/Next buttons to navigate through tracks in each genre (4 tracks per page).
  • Track Details (/:genre/track/:slug): Click "More Details" to view a tracks 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",
    "embedUrl": "https://w.soundcloud.com/player/?url=https%3A//soundcloud.com/snxraven/heavy-riffs&color=%23ff5500&auto_play=false...",
    "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.ts library fetches playlist data, including track titles, URLs, play counts, and publication dates.
  • WebSockets: Socket.IO enables real-time pagination, handling request_page events to deliver paginated track data.
  • Routing:
    • /: Renders the home page with paginated genre tracks.
    • /:genre: Redirects to the home pages genre section (e.g., /#metal).
    • /:genre/track/:slug: Renders individual track pages using unique slugs.
    • /json/:genre: Returns all track data for a genre in JSON.
    • /sitemap.xml: Generates an XML sitemap with all track URLs.
  • Slug Generation: Creates unique, URL-friendly slugs per genre (e.g., "Heavy Riffs" → heavy-riffs) with conflict resolution.
  • Pagination: Limits to 4 tracks per page, with server-side logic to calculate total pages and track subsets.

Frontend

  • Templating: EJS renders dynamic HTML with paginated track data.
  • 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, a slim scrollbar, and pagination styling.
  • Interactivity:
    • Socket.IO client handles real-time page requests and updates.
    • Client-side caching stores rendered pages to minimize server requests.
    • Lazy-loaded iframes optimize performance by loading SoundCloud players only when in view.
  • Scripts: jQuery, Popper.js, Bootstrap JS, and Socket.IO (via CDN) enable navbar toggling, pagination, and WebSocket communication.

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 via oneWeekInMs).
    • If outdated or missing, it fetches fresh data and updates the cache.
  • Sorting:
    • Standard genres: Sort by play count (highest first), then publication date (newest first).
    • Cuts genre: Sort by EP number (ascending).

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 paginated 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)
├── cache_lofi.json          # Cached Lo-Fi tracks (auto-generated)
├── cache_edm.json           # Cached EDM tracks (auto-generated)
├── cache_cuts.json          # Cached Cuts tracks (auto-generated)
├── music_site.js            # Core server logic, routing, and WebSocket handling
├── 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.ts: Simplifies fetching public playlist data without requiring an official API key.
  • Socket.IO: Enables real-time pagination, improving user experience by avoiding full page reloads.
  • 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.
  • File-System Caching: A simple, effective solution for persistence without a database.

Configuration

  • Playlists: Modify the playlists object in music_site.js:
    const playlists = {
      metal: { url: 'https://soundcloud.com/snxraven/sets/raven-scott-metal', ... },
      // Add new genres here
    };
    
  • Cache Refresh: Adjust oneWeekInMs (in milliseconds) in getTracks:
    const oneWeekInMs = 7 * 24 * 60 * 60 * 1000; // Change to 24 * 60 * 60 * 1000 for daily refresh
    
  • Pagination: Modify TRACKS_PER_PAGE in music_site.js:
    const TRACKS_PER_PAGE = 4; // Change to desired tracks per page
    
  • Port: Set via .env or directly in music_site.js:
    const PORT = process.env.PORT || 6767;
    

Deployment

  1. Prepare for Production:

    • Set NODE_ENV=production to optimize Express.
    • Ensure .env includes the production port or use a platform-specific configuration.
  2. Example: Deploy to Render:

    • Push the repository to a Git service (e.g., GitHub).
    • Create a new Web Service on Render, linking to your repository.
    • Set environment variables:
      PORT=6767
      NODE_ENV=production
      
    • Configure the start command: node music_site.js.
  3. Verify:

    • Check the deployed URL for functionality.
    • Monitor logs for errors related to SoundCloud fetching or caching.

Development

Getting Started

  1. Fork and clone the repo.
  2. Install dependencies (npm install).
  3. Run locally (node music_site.js).
  4. 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 Google Analytics.
  • Infinite Scroll: Replace pagination with infinite scroll for seamless track loading.

Troubleshooting

  • SoundCloud Fetch Fails:
    • Verify playlist URLs in music_site.js are correct and public.
    • Update soundcloud.ts (npm install soundcloud.ts@latest).
  • Cache Issues:
    • Delete cache_*.json files and restart the server to force a refresh.
    • Check file permissions if cache files arent being written.
  • WebSocket Errors:
    • Ensure Socket.IO client and server versions match (npm install socket.io@latest).
    • Check browser console for connection issues (e.g., CORS or port mismatches).
  • Pagination Problems:
    • Verify TRACKS_PER_PAGE is set correctly.
    • Check server logs for errors in getTracks or WebSocket handlers.
  • Port Conflicts:
    • Change the PORT value or kill the conflicting process:
      lsof -i :6767  # Linux/macOS
      kill -9 <PID>
      
  • 404 Errors:
    • Ensure genre or slug matches the data (case-sensitive).
    • Check console logs for errors during playlist fetching or slug generation.
  • Styling Problems:
    • Clear browser cache if CSS changes dont appear.
    • Verify CDN links for Bootstrap, jQuery, and Socket.IO are accessible.
Description
No description provided
Readme 166 KiB
Languages
EJS 65.1%
JavaScript 34.9%