Skip to content

sonata-sdk/sonata

Repository files navigation

Sonata

🎡 Sonata

Lavalink-compatible audio server
pure TypeScript Β· no Java Β· no yt-dlp

License Version Last Commit Code Size Node Docs

Features β€’ Quick Start β€’ Configuration β€’ API β€’ Sources β€’ Performance


Sonata is a drop-in replacement for Lavalink (Java) written entirely in TypeScript. It provides the same REST + WebSocket protocol that Discord bots expect, but with faster startup, lower memory, and native YouTube/SoundCloud/Spotify resolution β€” no Java runtime or yt-dlp required.


✨ Features

🎧 Audio Playback PCM β†’ Opus encoding, DAVE/E2EE encryption, real-time mixing
🌐 12 Audio Sources YouTube (InnerTube), Spotify, SoundCloud, Deezer, Apple Music, Bandcamp, Twitch, Vimeo, NicoNico, Mixcloud, Podcasts, HTTP, Local
πŸŽ›οΈ 13 DSP Filters EQ (15-band), karaoke, timescale, tremolo, vibrato, rotation (8D), distortion, channel mix, low-pass, high-pass, reverb, limiter, volume
πŸ“¦ Zero Java Pure Node.js β€” no JRE, no Maven, no yt-dlp
πŸ”Œ Plugin System npm packages, local paths, auto-scan β€” all with full type support
πŸš€ Performance ~200ms startup, ~15MB idle, ~30MB with 10 players
πŸ”„ Protocol Lavalink v4 + v3 β€” works with any lavaclient
πŸ“Š Observability Prometheus metrics, health check, HTML dashboard

πŸš€ Quick Start

πŸ“¦ npm (global)

npm install -g @sonata-sdk/server
sonata                          # start with default config (./config.js)
sonata /etc/sonata/config.js    # start with custom config

β—» npx (no install)

npx @sonata-sdk/server          # run directly

🐳 Docker

docker build -t sonata .
docker run -p 2333:2333 -v ./config.js:/app/config.js sonata

πŸ”§ From source

git clone https://github.com/sonata-sdk/sonata.git
cd sonata
npm install
npm run build
node dist/index.js

⚑ Dev mode (no build)

npx tsx src/index.ts           # one-shot
npm run dev                     # watch mode (auto-restart)

πŸ—οΈ Bootstrap (clone + build)

sonata --build                  # clones repo, installs deps, compiles

πŸ’» CLI

sonata [config-path]

Options:
  -v, --version       Show version
  -h, --help          Show this help
  --build             Clone repo, install deps, and build from GitHub

βš™οΈ Configuration

Copy config.example.js β†’ config.js. Every option is documented inline.

Section Description
server Host, port, password, CORS, SSL, dashboard path
logging Level, format (text/json), file transport, colors
sources Toggle each source on/off, set API keys
lavalink API version, session resume, plugin directory
voice UDP mode, encryption fallback, keepalive
player Volume, idle timeout, normalization, auto-leave
queue Max size, history, crossfade, shuffle, loop
cache LRU or Redis, TTL, max entries
metrics Prometheus endpoint
rateLimiting Window, max requests, per-user
security HSTS, content-type enforcement, SQLi/XSS blocking
plugins npm packages, local paths, per-plugin config
clustering Multi-node (coming soon)
resolving Search aliases, retry, fallbacks
dashboard Theme, refresh, player controls

πŸ“‘ Audio Sources

Source Method Playlists Auth Required
YouTube InnerTube API (5 clients) βœ… β€”
SoundCloud Public API βœ… β€”
Spotify Web API + YouTube mirror βœ… clientId + clientSecret
Deezer Gateway API + CDN βœ… arl
Apple Music iTunes Search API ❌ β€”
Bandcamp HTML ❌ β€”
Twitch HTML ❌ β€”
Vimeo HTML ❌ β€”
NicoNico API + HTML ❌ β€”
Mixcloud API + HTML ❌ β€”
Podcast RSS/XML βœ… β€”
🌐 HTTP Direct URL ❌ β€”
πŸ“ Local Filesystem path ❌ β€”

Deezer requires an arl cookie for high-quality streaming. Set sources.deezer.arl in config. SOCKS proxy is also supported via sources.deezer.proxy.


πŸ“– API

Lavalink v4

Method Endpoint
GET /v4/info
GET /v4/stats
GET / POST / DELETE /v4/sessions, /v4/sessions/{id}
GET /v4/sessions/{id}/players
GET / PATCH / DELETE /v4/sessions/{id}/players/{guildId}
POST /v4/sessions/{id}/players/{guildId}/voice
GET /v4/loadtracks?identifier=
GET / POST /v4/decodetrack?track=
POST /v4/decodetracks
POST / DELETE / PATCH /v4/sessions/{id}/players/{guildId}/queue
GET /v4/sessions/{id}/players/{guildId}/history
GET /v4/routeplanner/status
POST /v4/routeplanner/free/address, /v4/routeplanner/free/all

Legacy /v3/* endpoints are also available for backward compatibility.

Extra Endpoints

Method Endpoint Description
GET /health Status, uptime, players, memory
GET /version Version, node, platform
GET /dashboard HTML admin dashboard
GET /metrics Prometheus metrics

Search Prefixes

Input Resolves To
https://youtube.com/watch?v=... YouTube
https://open.spotify.com/track/... Spotify
https://soundcloud.com/user/track SoundCloud
never gonna give you up All sources (auto-detect)
ytmixes:VIDEO_ID YouTube Mix (recommendations)
ytplaylist:QUERY YouTube playlist search

πŸŽ›οΈ Audio Filters

Filter Description Range
Volume Multiplier with 16-bit clamp 0% – 1000%
Equalizer 15-band graphic EQ (Β±0.25 gain) 40Hz – 16kHz
Karaoke Center channel removal β€”
Timescale Speed, pitch, rate 0.5x – 2.0x
Tremolo Amplitude modulation β€”
Vibrato Pitch modulation β€”
Rotation 8D stereo pan 0.05 – 0.5 Hz
Distortion Sin/Cos/Tan waveshaping β€”
Channel Mix Left/right mixing matrix β€”
Low Pass 1-pole low-pass filter β€”
High Pass 1-pole high-pass filter β€”
Reverb Comb-filter delay with decay 0–100% mix
Limiter Dynamic range compression 0–1 threshold

Apply via PATCH /v4/sessions/{id}/players/{guildId} with { filters: { ... } }.

Example usage:

{
  "filters": {
    "reverb": { "delay": 0.05, "decay": 0.4, "mix": 0.3 },
    "highPass": { "smoothing": 0.1 },
    "limiter": { "threshold": 0.95, "attack": 0.002, "release": 0.1 }
  }
}

🧩 Plugin System

Sonata supports plugins via config.js:

plugins: {
  npm: ['@sonata-sdk/plugin-lyrics'],
  paths: ['./my-local-plugin.js'],
  configs: {
    '@sonata-sdk/plugin-lyrics': { geniusApiKey: '...' }
  }
}

Create your own using the @sonata-sdk/plugin-sdk:

import { register } from '@sonata-sdk/plugin-sdk'

export default register({
  name: 'my-plugin',
  version: '1.0.0',
  install(ctx) {
    ctx.onTrackStart((guildId, track) => {
      ctx.log('info', `β–Ά ${track.info.title}`)
    })
    ctx.registerRoute('GET', '/my-plugin/status', (req, res) => {
      res.end(JSON.stringify({ ok: true }))
    })
  },
})

⚑ Performance

Metric Sonata Lavalink (Java)
Runtime Node.js 20+ JRE 17+
Package size ~5 MB JS ~100 MB JAR
RAM (idle) ~15 MB ~300 MB
RAM (10 players) ~30 MB ~500 MB
Startup time ~200 ms ~10 s
Dependencies npm Maven
Docker image ~150 MB ~400 MB

πŸ—οΈ Architecture

src/
β”œβ”€β”€ index.ts              # Entry point
β”œβ”€β”€ config/               # Config module loader
β”œβ”€β”€ server/               # HTTP + WebSocket server / router / middleware
β”œβ”€β”€ lavalink/             # REST API (v3+v4), WS protocol, session manager
β”œβ”€β”€ player/               # Player state machine, queue, track encoder, audio streamer
β”œβ”€β”€ discord/              # Voice connection (Opus + DAVE/MLS encryption)
β”œβ”€β”€ audio/                # DSP mixer with 13 filters
β”œβ”€β”€ resolving/            # 12 audio source resolvers
β”‚   β”œβ”€β”€ youtube/          # InnerTube API (5 client profiles)
β”‚   β”œβ”€β”€ soundcloud/       # SoundCloud public API
β”‚   β”œβ”€β”€ spotify/          # Spotify Web API + YouTube mirror fallback
β”‚   └── ...               # 9 more sources
β”œβ”€β”€ cache/                # LRU / Redis track cache
β”œβ”€β”€ dashboard/            # HTML admin dashboard
β”œβ”€β”€ metrics/              # Prometheus exporter
β”œβ”€β”€ plugin/               # Plugin manager + loader
└── types/                # TypeScript type definitions

~8K lines across 48 files.


πŸ› οΈ Development

npm run typecheck   # TypeScript type checking
npm test            # Run tests (24 passing)
npm run build       # Compile to dist/
npm run dev         # Watch mode with auto-reload

πŸ“¦ Related


Built with ❀️ in TypeScript · MIT License

About

High-performance Lavalink-compatible audio server for Discord bots. TypeScript. Native YouTube/SoundCloud/Spotify resolvers via InnerTube API. No yt-dlp.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors