Skip to content

Commit 7851bc6

Browse files
chore: public the NODELINK FEATS md.
Makes RIffy's internal NODELINK FEAT md file to the public.
1 parent b31ba9b commit 7851bc6

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

NODELINK-FEATURES.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Nodelink-Only Features
2+
3+
[Nodelink](https://nodelink.js.org) is a Lavalink-compatible server that Riffy treats as a superset of Lavalink. Riffy auto-detects it from `node.info.isNodelink` (populated from the `/info` response on WS `open`). Almost every Nodelink API is guarded so calling it on a plain Lavalink node throws a clear error.
4+
5+
Detection helpers: `node.info?.isNodelink` (boolean), `node.mixer.check()`, `node.sponserBlock.check()`, `node.lyrics.checkAvailable(...)`.
6+
7+
## Lyrics (`Node.lyrics`)
8+
- `lyrics.checkAvailable(eitherOne=true, ...plugins)` — verifies required plugins are present on the node (`lavalyrics-plugin`, `java-lyrics-plugin`, `lyrics`). Throws `RangeError` if missing and node not connected.
9+
- `lyrics.get(trackOrEncoded, skipTrackSource=false)` — v4 `/v4/lyrics?...`.
10+
- `lyrics.getCurrentTrack(guildId, skipTrackSource, plugin)` — fetches lyrics for the active track, with fallback URL logic depending on which lyric plugins the node exposes.
11+
12+
These surface as `lyricsFound` / `lyricsNotFound` / `lyricsLine` events.
13+
14+
## Audio Mixer (`Node.mixer`)
15+
Adds/removes/updates mix layers (overlapping audio) on a player — Nodelink's "Audio Mixer".
16+
- `mixer.addMixLayer(guildId, { track, volume })``POST /v4/.../mix`.
17+
- `mixer.getActiveMixLayers(guildId)``GET`.
18+
- `mixer.updateMixLayerVolume(guildId, mixId, volume)``PATCH` (volume 0–1).
19+
- `mixer.removeMixLayer(guildId, mixId)``DELETE`.
20+
- All throw if `!isNodelink`. Surfaced via `mixStarted` / `mixEnded` events.
21+
22+
## SponsorBlock (`Node.sponsorBlock`)
23+
Nodelink's segment-skip feature.
24+
- `sponsorBlock.getCurrentBlock(guildId)``GET`.
25+
- `sponsorBlock.updateSettings(guildId, options)``PATCH` with strict validation (categories array of strings, optional actionTypes, non-negative `skipMarginMs`).
26+
- `sponsorBlock.setBlockSegments(guildId, segments)``PUT` (validates each segment: uuid, start/end, category, actionType, votes, locked, videoDuration, description).
27+
- `sponsorBlock.clearSponsorBlock(guildId)``DELETE`.
28+
- Surfaced via `sponsorBlockSegmentsLoaded` / `sponsorBlockSegmentSkipped` events.
29+
30+
## Direct streaming & PCM (`Node`)
31+
Require corresponding server-side config flags on the Nodelink server.
32+
- `fetchTrackStream(encodedTrackStr, itag=null)``GET /v4/trackstream?...` returns the source audio URL (not the bytes). Needs `enableTrackStreamEndpoint`.
33+
- `fetchPCMStream(encodedTrackStr, volume, position, filters)``POST /v4/loadstream` returns a raw PCM `ReadableStream` for custom processing/recording. Needs `enableLoadStreamEndpoint`. Validates `volume` (0–1000), `position` (≥0).
34+
- `loadChapters(encodedTrackStr)``GET /v4/loadchapters?...` returns YouTube chapter markers.
35+
36+
## Other Nodelink touches
37+
- **Player `sendNextTrack(track)`** — preloads next track for gapless playback (`{ nextTrack: { encoded } }`).
38+
- **Player `setFadings(enabled, fading)`** — high-fidelity volume fades (trackStart/trackEnd/trackStop/seek/ducking) with duration + curve.
39+
- **v4 voice payload `channelId`** — added in v1.0.12 (`Connection.checkAndSend`) for upcoming Nodelink v4.2.0.
40+
41+
## Change guidance
42+
- Any new Nodelink method must: (1) live on `Node` (or `Player` for player-scoped ones), (2) guard with `this.info?.isNodelink` / `*.check()`, (3) throw `TypeError` for invalid args matching the existing strict validation style, and (4) map emitted events in `Player.handleEvent` and `RiffyEvents` (`index.d.ts`).
43+
- Nodelink search types use `searchType` (`track|album|playlist|artist`) in `Riffy.resolve`; the node filter `n.info.isNodelink` is applied when a `searchType` is requested.

0 commit comments

Comments
 (0)