# 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. ![Home screen with the Floatplane tile, Continue Watching and Recently Added](doc/img/home.png) ## 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. ![Creator folder: All videos first, then the sub-channels](doc/img/creator-folder.png) ## 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_.zip` from the [releases](https://gitea.brasse-pc.eu/brasse/jellyfin-plugin-floatplane/releases), unzip it into `/plugins/Floatplane_/` 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_/ (DLL, meta.json, thumb.png), build/floatplane_.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.