Jellylink plugin init

This commit is contained in:
2026-02-13 21:00:46 +01:00
commit f6a28fe131
10 changed files with 709 additions and 0 deletions

184
README.md Normal file
View File

@@ -0,0 +1,184 @@
# Jellylink Jellyfin Music Plugin for Lavalink
Play music from your **Jellyfin** media server through **Lavalink**. Jellylink is a Lavalink plugin that lets Discord bots search and stream audio directly from a Jellyfin library — no YouTube needed.
> **Keywords:** Jellyfin Lavalink plugin, Jellyfin Discord music bot, Lavalink Jellyfin source, stream Jellyfin audio Discord, self-hosted music bot
---
## Features
- **Search your Jellyfin library** from any Lavalink client using the `jfsearch:` prefix
- **Stream audio directly** — plays FLAC, MP3, OGG, and other formats from Jellyfin
- **Cover art & metadata** — track title, artist, album, duration, and artwork are passed to your client
- **Configurable audio quality** — stream original files or transcode to a specific bitrate/codec
- **Username/password authentication** — no need to manage API keys manually
- Works alongside YouTube, SoundCloud, Spotify, and all other Lavalink sources
---
## Installation
### Prerequisites
- [Lavalink v4](https://github.com/lavalink-devs/Lavalink) (tested with 4.0.8)
- A running [Jellyfin](https://jellyfin.org/) server with music in its library
- Java 17+
### Step 1 — Download or Build the Plugin
**Option A: Download the JAR**
Grab the latest `jellylink-x.x.x.jar` from the [Releases](../../releases) page.
**Option B: Build from Source**
```bash
git clone https://github.com/Myxelium/Jellylink.git
cd Jellylink
gradle build
```
The JAR will be at `build/libs/jellylink-0.1.0.jar`.
> **Tip:** If you don't have Gradle installed, run `gradle wrapper --gradle-version 8.7` first, then use `./gradlew build`.
### Step 2 — Install the Plugin
Copy the JAR into your Lavalink `plugins/` directory:
```
lavalink/
├── application.yml
├── Lavalink.jar
└── plugins/
└── jellylink-0.1.0.jar ← put it here
```
If you use **Docker**, mount it into the container's plugins volume:
```yaml
volumes:
- ./application.yml:/opt/Lavalink/application.yml
- ./plugins/:/opt/Lavalink/plugins/
```
### Step 3 — Configure Lavalink
Add the following to your `application.yml` under `plugins:`:
```yaml
plugins:
jellylink:
jellyfin:
baseUrl: "http://your-jellyfin-server:8096"
username: "your_username"
password: "your_password"
searchLimit: 5 # max results to return (default: 5)
audioQuality: "ORIGINAL" # ORIGINAL | HIGH | MEDIUM | LOW | custom kbps
audioCodec: "mp3" # only used when audioQuality is not ORIGINAL
```
#### Audio Quality Options
| Value | Bitrate | Description |
|-------------|-----------|------------------------------------------|
| `ORIGINAL` | — | Serves the raw file (FLAC, MP3, etc.) |
| `HIGH` | 320 kbps | Transcoded via Jellyfin |
| `MEDIUM` | 192 kbps | Transcoded via Jellyfin |
| `LOW` | 128 kbps | Transcoded via Jellyfin |
| `256` | 256 kbps | Any number = custom bitrate in kbps |
#### Docker Networking
If Lavalink runs in Docker and Jellyfin runs on the host:
- Use your host's LAN IP (e.g. `http://192.168.1.100:8096`)
- Or use `http://host.docker.internal:8096` (Docker Desktop)
- Or use `http://172.17.0.1:8096` (Docker bridge gateway)
### Step 4 — Restart Lavalink
Restart Lavalink and check the logs. You should see:
```
Loaded plugin: jellylink-jellyfin
```
Verify at `GET /v4/info``jellyfin` should appear under `sourceManagers`.
---
## Usage
Search your Jellyfin library using the `jfsearch:` prefix when loading tracks:
```
jfsearch:Bohemian Rhapsody
jfsearch:Daft Punk
jfsearch:Bach Cello Suite
```
### Example with Lavalink4NET (C#)
> **Lavalink4NET users:** Install the companion NuGet package [Lavalink4NET.Jellyfin](https://github.com/Myxelium/Lavalink4NET.Jellyfin) for built-in search mode support, query parsing, and source detection.
```bash
dotnet add package Lavalink4NET.Jellyfin
```
```csharp
using Lavalink4NET.Jellyfin;
using Lavalink4NET.Rest.Entities.Tracks;
// Parse user input — automatically detects jfsearch:, ytsearch:, scsearch:, etc.
var (searchMode, cleanQuery) = SearchQueryParser.Parse(
"jfsearch:Bohemian Rhapsody",
defaultMode: JellyfinSearchMode.Jellyfin // default when no prefix
);
var options = new TrackLoadOptions { SearchMode = searchMode };
var result = await audioService.Tracks.LoadTracksAsync(cleanQuery, options);
```
Or use `ParseExtended` for detailed source info:
```csharp
var result = SearchQueryParser.ParseExtended(userInput, JellyfinSearchMode.Jellyfin);
if (result.IsJellyfin)
Console.WriteLine("Searching Jellyfin library...");
Console.WriteLine($"Source: {result.SourceName}, Query: {result.Query}");
```
### Example with Lavalink.py (Python)
```python
results = await player.node.get_tracks("jfsearch:Bohemian Rhapsody")
```
### Example with Shoukaku (JavaScript)
```javascript
const result = await node.rest.resolve("jfsearch:Bohemian Rhapsody");
```
The plugin only handles identifiers starting with `jfsearch:`. All other sources (YouTube, SoundCloud, Spotify, etc.) continue to work normally.
---
## Troubleshooting
| Problem | Solution |
|---------|----------|
| `Jellyfin authentication failed` | Check `baseUrl`, `username`, and `password`. Make sure the URL is reachable from the Lavalink host/container. |
| `No Jellyfin results found` | Verify the song exists in your Jellyfin library and that the user has access to it. |
| `Unknown file format` | Update to the latest version — this was fixed by using direct audio streaming. |
| No cover art | Update to the latest version — artwork URLs are now always included. |
| Unicode characters broken (e.g. `\u0026`) | Update to the latest version — JSON escape sequences are now decoded. |
---
## License
MIT