Skip to content

Hexadecinull/Meeb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Meeb 🎵

Free, open-source, self-hosted web music player — a unified frontend for YouTube Music, Spotify, and SoundCloud.

License: GPL-3.0 PHP 8.1+ No framework


What is Meeb?

Meeb is a self-hosted, ad-free, open-source music web app that lets you search, stream, and manage music from YouTube Music, Spotify, and SoundCloud simultaneously from a single beautiful interface. Log into all three accounts at once, unify your liked songs, playlists, and listening history, and enjoy a rich desktop-class audio experience — all from a tab in your browser.

It does not rely on any paid cloud services. Your server is the only backend.


Features

Multi-provider Streaming

  • YouTube Music — full search, stream via yt-dlp, no ads
  • Spotify — search, metadata, 30s previews (full playback requires Spotify Premium + Web Playback SDK)
  • SoundCloud — full search and streaming via the SoundCloud API
  • Log into all three accounts simultaneously; sync liked songs, playlists, and history from each
  • Easily add more providers by extending BaseProvider

Audio Engine

  • Web Audio API pipeline with pre-gain → 10-band EQ → dynamics compressor → master gain
  • 10-band graphic equalizer with presets: Flat, Rock, Pop, Jazz, Classical, Electronic, Bass Boost, Vocal
  • Pre-amplifier (±12 dB), live frequency-response curve canvas
  • Crossfade between tracks (0–12 s, configurable)
  • Gapless playback support
  • Volume normalisation
  • Playback speed control (0.5× – 2×) with pitch preservation
  • Surround/Night Mode compressor modes

Visualizer

  • Bars — animated frequency bars with glowing caps
  • Waveform — real-time oscilloscope
  • Circle — radial spectrum analyser
  • Particles — energy-reactive particle system
  • Mini visualizer always visible in the player bar

BPM Finder

  • Real-time BPM detection via FFT onset analysis (kick-drum band 80–200 Hz)
  • Tap-tempo fallback
  • Confidence display and musical tempo name (Andante, Allegro, Presto…)
  • Beat-pulse animation synced to detected tempo

Appearance & Theming

  • Material You dynamic colour system — the entire UI tints to match the current album art's dominant colour, animated smoothly on every track change
  • Themes: Dark (default), Light, AMOLED Black
  • Accent palettes: Violet, Blue, Green, Rose, Amber, Cyan — or fully dynamic from album art
  • Compact mode, adjustable font size
  • Full CSS custom-property system — every colour, radius, spacing value is a variable
  • All colours can be overridden with one line of CSS per user preference

Player

  • Persistent bottom player bar with progress seek, volume, speed
  • Shuffle (Fisher-Yates weighted), Repeat (none / all / one)
  • Queue management with drag-and-drop reorder
  • Previous / Next with 3-second back-seek on double-press
  • Like / unlike tracks synced to each provider's account
  • Media Session API — lock screen and OS media controls

Memory & Persistence

  • Restores last playing track, position, queue, volume, shuffle/repeat state on reload
  • Play history (last 200 tracks) per provider
  • Liked-track cache for instant local lookup

Lyrics

  • Synced (LRC) lyrics via LRCLIB — free, no key required
  • Plain-text fallback search
  • Auto-scroll with active line highlight
  • Toggle auto-show on track change

Cache & Offline

  • Service Worker caches static assets, stream URLs, and album art
  • Configurable audio cache size (default 512 MB, up to 4 GB)
  • Stale-while-revalidate for images, cache-first for audio
  • Background cache eviction when limit is reached

Other Tools

  • Sleep timer — stop playback after 15 / 30 / 45 / 60 / 90 min or custom
  • Song info panel — full metadata (title, artist, album, genre, release date, duration, provider, explicit flag)
  • Keyboard shortcuts — fully customisable, 20+ default bindings
  • Browser notifications — track-change alerts (optional)
  • Context menu on tracks — play, add to queue, add to playlist, like, view artist/album, share
  • PWA — installable as a desktop or mobile app

Stack

Layer Technology
Server PHP 8.1+ (no framework)
Frontend Vanilla ES2022 (ES modules, no bundler required)
Styles Pure CSS (custom properties, Grid, Flexbox)
Audio Web Audio API
Fonts Outfit, Inter, JetBrains Mono (Google Fonts)
YouTube yt-dlp (server-side stream extraction)
Lyrics LRCLIB (free, no key)
PWA Service Worker + Web App Manifest

Requirements

Requirement Version
PHP 8.1 or newer
PHP extensions curl, json, mbstring
Web server Apache (mod_rewrite) or Nginx
yt-dlp Latest stable — pip install -U yt-dlp
Python 3.8+ (for yt-dlp)

Installation

1. Clone

git clone https://github.com/yourname/meeb.git
cd meeb

2. Install yt-dlp

# Linux/macOS
pip install -U yt-dlp
which yt-dlp   # note the path

# Or download the binary directly:
curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
chmod +x /usr/local/bin/yt-dlp

3. Create API credentials

Spotify

  1. Go to developer.spotify.com/dashboard → Create App
  2. Add redirect URI: https://yourdomain.com/api/auth/spotify.php?action=callback
  3. Copy Client ID and Client Secret

YouTube Music / Google

  1. Go to console.cloud.google.com → New Project
  2. Enable YouTube Data API v3
  3. Create OAuth 2.0 credentials (Web Application)
  4. Add redirect URI: https://yourdomain.com/api/auth/youtube.php?action=callback
  5. Also create an API Key for public search

SoundCloud

  1. Go to soundcloud.com/you/apps → Register a new application
  2. Add redirect URI: https://yourdomain.com/api/auth/soundcloud.php?action=callback
  3. Copy Client ID and Client Secret

4. Configure

cp config/config.php config/config.local.php
# Edit config.local.php — fill in all API keys
nano config/config.local.php

Or use environment variables:

export SPOTIFY_CLIENT_ID="your_id"
export SPOTIFY_CLIENT_SECRET="your_secret"
export YOUTUBE_CLIENT_ID="your_id"
export YOUTUBE_CLIENT_SECRET="your_secret"
export YOUTUBE_API_KEY="your_key"
export SOUNDCLOUD_CLIENT_ID="your_id"
export SOUNDCLOUD_CLIENT_SECRET="your_secret"
export YTDLP_PATH="/usr/local/bin/yt-dlp"
export MEEB_BASE_URL="https://yourdomain.com"

5. Set permissions

chmod 755 cache/ cache/audio/ cache/images/ cache/metadata/ logs/
chown -R www-data:www-data cache/ logs/   # or your web server user

6. Configure web server

Apache (.htaccess is already included — just enable mod_rewrite):

a2enmod rewrite
systemctl restart apache2

Nginx:

server {
    listen 443 ssl http2;
    server_name yourdomain.com;
    root /var/www/meeb;
    index index.php;

    # Static assets
    location /public/ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }

    # PHP files
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # SPA fallback
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

7. Register the Service Worker

The SW registers automatically from public/js/app.js. Make sure your domain uses HTTPS (required for Service Workers and the Web Audio API's full feature set).


Keyboard Shortcuts

Key Action
Space Play / Pause
N Next track
B Previous track
/ Seek ±10 seconds
/ Volume ±5%
M Toggle mute
S Toggle shuffle
R Cycle repeat mode
L Like current track
E Toggle Equalizer
Q Toggle Queue
T Toggle Lyrics
I Song Info
/ Focus search
, Open Settings
1 / 2 / 3 Switch provider
F11 Fullscreen
Esc Close panel / modal
? Show this list

All shortcuts are customisable in Settings → Advanced.


Adding a Custom Provider

  1. Create public/js/providers/myprovider.js extending BaseProvider
  2. Implement: search(), getTrack(), getStreamUrl(), getAlbum(), getArtist(), getPlaylist()
  3. Create api/auth/myprovider.php with an API class MyproviderApi
  4. Register in public/js/app.js:
    import { MyProvider } from './providers/myprovider.js';
    export const providerRegistry = {
      // ...existing providers
      myprovider: new MyProvider(),
    };
  5. Add a provider button in index.php's .provider-switcher

Project Structure

meeb/
├── .htaccess               Apache rewrite rules & security headers
├── index.php               SPA entry point (full HTML shell)
├── composer.json
├── config/
│   └── config.php          All API keys & runtime settings
├── api/
│   ├── index.php           Request router (all /api/* traffic)
│   ├── auth/
│   │   ├── spotify.php     Spotify OAuth + SpotifyApi class
│   │   ├── youtube.php     Google OAuth + YoutubeApi class
│   │   └── soundcloud.php  SC OAuth + SoundcloudApi class
│   ├── proxy/
│   │   ├── stream.php      Audio stream URL resolver (yt-dlp / SC / SP)
│   │   └── image.php       Album-art proxy (CORS fix + disk cache)
│   └── providers/
│       ├── spotify.php     Spotify extra endpoints
│       ├── youtube.php     YouTube extra endpoints
│       └── soundcloud.php  SoundCloud extra endpoints (trending)
├── includes/
│   ├── session.php         Session bootstrap + token management
│   ├── helpers.php         HTTP client, caching, logging utilities
│   └── response.php        json_ok() / json_err() helpers
├── public/
│   ├── manifest.json       PWA manifest
│   ├── sw.js               Service Worker (cache strategies)
│   ├── css/
│   │   ├── variables.css   Complete Material You token system
│   │   └── main.css        All component & layout styles
│   └── js/
│       ├── app.js          Bootstrap — wires all modules together
│       ├── core/
│       │   ├── events.js   Typed event bus
│       │   ├── state.js    Reactive single-source-of-truth store
│       │   └── storage.js  localStorage wrapper + typed helpers
│       ├── player/
│       │   ├── audio.js    Web Audio API engine (crossfade, session restore)
│       │   ├── equalizer.js 10-band EQ + presets + curve canvas
│       │   ├── bpm.js      Real-time BPM detection + tap tempo
│       │   ├── visualizer.js Bars / Waveform / Circle / Particles
│       │   └── queue.js    Queue data helpers
│       ├── providers/
│       │   ├── base.js     Abstract BaseProvider + Track typedef
│       │   ├── spotify.js  Spotify Web API + Web Playback SDK
│       │   ├── youtube.js  YouTube Music (via PHP proxy / yt-dlp)
│       │   └── soundcloud.js SoundCloud API
│       ├── ui/
│       │   ├── theme.js    Material You colour extraction + bloom animation
│       │   ├── settings.js Settings panel renderer (all 30+ settings)
│       │   ├── search.js   Debounced search UI + result templates
│       │   ├── keyboard.js Global keyboard shortcut manager
│       │   ├── modal.js    Modal dialog system
│       │   └── toast.js    Toast notification manager
│       └── utils/
│           ├── api.js      Typed fetch wrapper for PHP API
│           ├── color.js    Material You palette generation, OKLCH math
│           └── time.js     Duration formatting, greeting, time parsing
└── cache/
    ├── audio/              yt-dlp stream URL cache
    ├── images/             Album art cache
    └── metadata/           Track / search metadata cache

Notes on Spotify Streaming

Spotify's API does not allow server-side audio streaming without special partnership agreements. Meeb handles this in two ways:

  1. 30-second previews — available for most tracks via the public API, no account needed
  2. Full playback — available via the Spotify Web Playback SDK for Spotify Premium users who connect their account. The SDK streams directly from Spotify's CDN to the browser; Meeb's server is not involved in the audio data.

If you need unrestricted Spotify playback, consider pairing Meeb with librespot (community project, check its license and ToS implications).


Privacy

  • No telemetry, no analytics, no third-party scripts (except Google Fonts and Spotify SDK, both optional)
  • API credentials are stored server-side in PHP sessions — never exposed to the browser
  • Album art is proxied through your own server to avoid leaking your IP to CDNs
  • Play history and liked tracks are stored locally in your browser's localStorage

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Keep commits atomic with clear messages
  4. Open a pull request against main

Please follow the existing code style: no build step, no framework, readable vanilla JS and PHP.


Roadmap

  • Last.fm scrobbling
  • Discord Rich Presence (via browser extension bridge)
  • Import/export playlists (M3U, JSPF)
  • Deezer provider
  • Smart queue (auto-queue related tracks)
  • Mini player overlay mode
  • Mobile app wrapper (Capacitor)
  • Multi-user support with per-user settings
  • Podcast support

License

GNU General Public License v3.0 — see LICENSE.

You are free to use, modify, and self-host Meeb. If you distribute a modified version, you must also release your modifications under GPL-3.0 and credit the original project.


Built with ♪ and no JavaScript frameworks.

About

Your personal web music player

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors