All checks were successful
release / build-release (push) Successful in 1m19s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
156 lines
7.2 KiB
Markdown
156 lines
7.2 KiB
Markdown
# Floatplane for Jellyfin
|
|
|
|
A [Jellyfin](https://jellyfin.org) server plugin that brings your
|
|
[Floatplane](https://www.floatplane.com) subscriptions into Jellyfin.
|
|
Creators, their sub-channels and every video appear as a **Floatplane**
|
|
channel under *My Media* in the web client and in all Jellyfin apps, and
|
|
play through the normal Jellyfin player — with watched state, resume,
|
|
"Continue Watching", "Recently Added" and search, like any other library.
|
|
|
|

|
|
|
|
## Features
|
|
|
|
- **Creators → All videos → sub-channels.** Each creator you subscribe to
|
|
gets an *All videos* folder (every sub-channel in release order, newest
|
|
first) plus one folder per sub-channel (TechLinked, ShortCircuit, …).
|
|
- **Real metadata**: thumbnail, description, duration, release date,
|
|
sub-channel as *Genre*, creator as *Studio*.
|
|
- **Newest first by default** in every Jellyfin client, without touching
|
|
the sort menu.
|
|
- **Watched/resume state is shared** between the *All videos* copy and the
|
|
sub-channel copy of a video.
|
|
- **Low-CPU playback**: the server remuxes Floatplane's H.264/AAC stream
|
|
(stream copy, no re-encode). Quality levels show up as *Versions*.
|
|
- **Home screen integration**: "Recently Added in Floatplane" and
|
|
"Continue Watching" work out of the box.
|
|
- **Browse without logging in**: public creators (e.g. `linustechtips`)
|
|
can be listed by url-name; playback needs a logged-in session.
|
|
- **Search test tool** for Floatplane's own search API on the settings
|
|
page, and a scheduled task that refreshes the catalogue.
|
|
|
|

|
|
|
|
## Requirements
|
|
|
|
| | |
|
|
|---|---|
|
|
| Jellyfin | **10.10.x** (plugin targetAbi `10.10.0.0`, .NET 8). Jellyfin 12.x needs a separate build (not available yet). |
|
|
| Architecture | one AnyCPU DLL — runs unchanged on x64 and arm64 (Raspberry Pi 4/5 etc.). |
|
|
| Floatplane | an account with an active subscription for playback. |
|
|
|
|
## Install
|
|
|
|
Step-by-step tutorials with screenshots live in the wiki:
|
|
[Install](https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/wiki/Install) ·
|
|
[Update](https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/wiki/Update).
|
|
|
|
|
|
**From the plugin repository (recommended)**
|
|
|
|
1. Dashboard → Plugins → **Repositories** → **+**. Name it anything and use
|
|
this URL:
|
|
|
|
```
|
|
https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/releases/download/latest/manifest.json
|
|
```
|
|
|
|
2. Dashboard → Plugins → **Catalog** → section *Channels* → **Floatplane**
|
|
→ **Install**.
|
|
3. Restart Jellyfin. The plugin shows as *Active* under *My Plugins*.
|
|
|
|
Updates then appear in the catalog like any other plugin.
|
|
|
|
**With the install script** (Docker — linuxserver.io or official image — or
|
|
a native install; detects the right plugin directory, verifies the checksum,
|
|
restarts Jellyfin):
|
|
|
|
```bash
|
|
curl -fsSL https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/releases/download/latest/install.sh | sh -s -- --dry-run
|
|
curl -fsSL https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/releases/download/latest/install.sh | sh
|
|
```
|
|
|
|
Environment overrides: `TAG` (`latest` or `vX.Y.Z`), `JELLYFIN_CONTAINER`
|
|
(default `jellyfin`, empty = native), `JELLYFIN_CONFIG_DIR`, `PLUGINS_DIR`,
|
|
`PUID`/`PGID`.
|
|
|
|
**Manually**: download `floatplane_<version>.zip` from the
|
|
[releases](https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/releases),
|
|
unzip it into `<jellyfin data>/plugins/Floatplane_<version>/` and restart.
|
|
|
|
## Log in
|
|
|
|
Floatplane's password login requires a Cloudflare captcha that only works on
|
|
floatplane.com, so the plugin cannot ask for your username and password.
|
|
Two options, both on **Dashboard → Plugins → Floatplane**:
|
|
|
|
1. **Session cookie** (works today): log in at floatplane.com in a browser,
|
|
copy the value of the `sails.sid` cookie (DevTools → Application/Storage
|
|
→ Cookies), paste it into the settings page, press **Validate cookie**
|
|
(shows your username and subscriptions) and **Save**.
|
|
2. **Login with Floatplane** (OAuth device flow — the way Floatplane's own
|
|
apps and clients like Hydravion or Wasserflug log in). This needs a
|
|
client id issued by Floatplane; without one the button reports
|
|
`invalid_client`.
|
|
|
|
Step-by-step instructions, every setting explained and troubleshooting:
|
|
**[doc/usage.md](doc/usage.md)**.
|
|
|
|
## How it works (short)
|
|
|
|
- The channel lists creators → *All videos* / sub-channels → posts from
|
|
Floatplane's public listing API (ids `creator:…`, `all:…`, `channel:…`,
|
|
`post:…`, `cpost:…`).
|
|
- On play, the plugin fetches the post details with your session and hands
|
|
Jellyfin signed URLs to its own `Floatplane/Stream/…` endpoints.
|
|
- The stream endpoint asks Floatplane for the stream info (cached 6 h,
|
|
throttled to the ~2/min the API allows), downloads the HLS playlist and
|
|
rewrites it: the AES-128 key is fetched through the plugin with your
|
|
session, the video segments go straight to Floatplane's CDN. Jellyfin's
|
|
ffmpeg then stream-copies the result to the client.
|
|
- A scheduled task refreshes the catalogue and bumps the channel cache key
|
|
so Jellyfin re-lists the folders.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
git clone https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane.git
|
|
cd jellyfin-plugin-floatplane
|
|
dotnet test # 59 unit tests (models, HLS rewriter, API client, catalogue)
|
|
scripts/package.sh # → build/Floatplane_<ver>/ (DLL, meta.json, thumb.png), build/floatplane_<ver>.zip (+ .md5)
|
|
scripts/package.sh 1.2.3.0 https://example.com/dl # versioned package + build/manifest.json
|
|
```
|
|
|
|
- Needs the .NET 8 SDK; the test host also needs the ASP.NET Core 8 shared
|
|
runtime (Arch: `sudo pacman -S dotnet-sdk-8.0 aspnet-runtime-8.0`).
|
|
- The VS Code `build` task (`Ctrl+Shift+B`) runs `scripts/package.sh`.
|
|
- Local end-to-end test against a throw-away Jellyfin of the right version:
|
|
|
|
```bash
|
|
mkdir -p .jellyfin-test/config/data/plugins
|
|
cp -r build/Floatplane_0.2.0.0 .jellyfin-test/config/data/plugins/ # writable copy
|
|
docker run --rm -p 8096:8096 -v "$PWD/.jellyfin-test/config:/config" \
|
|
lscr.io/linuxserver/jellyfin:10.10.7ubu2404-ls80
|
|
# logs: .jellyfin-test/config/log/log_*.log — plugin status: Dashboard → Plugins
|
|
```
|
|
|
|
- Every push to `master` runs the tests and publishes the rolling `latest`
|
|
release (zip, md5, `manifest.json`, `install.sh`); a `vX.Y.Z` tag publishes
|
|
a versioned release.
|
|
|
|
More: [`doc/plan.md`](doc/plan.md) (milestones, roadmap),
|
|
[`doc/floatplane-api-notes.md`](doc/floatplane-api-notes.md) (the API as
|
|
observed), [`doc/research/`](doc/research/) (Jellyfin plugin + Floatplane
|
|
API research and reference sources), and the
|
|
[project wiki](https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/wiki).
|
|
|
|
## Credits & disclaimer
|
|
|
|
Unofficial, not affiliated with or endorsed by Floatplane Media Inc.
|
|
The plugin uses Floatplane's unofficial API documented by the community
|
|
([jamamp/FloatplaneAPI](https://github.com/jamamp/FloatplaneAPI)) and
|
|
borrows the channel + signed-proxy pattern from
|
|
[chaosflix-jellyfin](https://github.com/praetorianer777/chaosflix-jellyfin).
|
|
Use it with your own subscription, for personal viewing. The Floatplane
|
|
name and logo belong to Floatplane Media Inc.
|