140 lines
5.6 KiB
Markdown
140 lines
5.6 KiB
Markdown
# Nextcloud/WebDAV Jellyfin Plugin Plan
|
||
|
||
Below is a high-level plan for a Jellyfin plugin that integrates Nextcloud/WebDAV sources as library content.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
subgraph Plugin Core
|
||
A[PluginConfiguration<br/>– holds URL, creds, paths]
|
||
B[Plugin<br/>– BasePlugin<Config>]
|
||
C[IPluginServiceRegistrator<br/>– registers services]
|
||
D[IHostedService<br/>– hook on startup]
|
||
end
|
||
|
||
subgraph Services
|
||
E[WebDavClientService<br/>– wraps WebDav.Client]
|
||
F[RemoteLibraryProvider<br/>– implements virtual folder scanning]
|
||
G[CachingLayer<br/>– buffer / temporary file cache]
|
||
H[StreamingController<br/>– ControllerBase for proxying streams]
|
||
end
|
||
|
||
subgraph Jellyfin Core
|
||
I[ILibraryManager<br/>– library registration]
|
||
J[Scan Engine<br/>– calls provider to enumerate items]
|
||
K[HTTP Pipeline<br/>– routes to controllers]
|
||
end
|
||
|
||
A --> B
|
||
B --> C
|
||
C --> E
|
||
C --> F
|
||
E --> F
|
||
F --> J
|
||
F --> G
|
||
G --> H
|
||
H --> K
|
||
D --> I
|
||
I --> J
|
||
```
|
||
|
||
## 1. Skeleton & Setup
|
||
- Copy the `jellyfin-plugin-template` and rename to `Jellyfin.Plugin.Nextcloud`.
|
||
- Update project metadata: plugin ID, name, version in `.csproj`.
|
||
- Add NuGet reference to `WebDav.Client`.
|
||
|
||
## 2. Configuration & Dependency Injection
|
||
- Define `PluginConfiguration` with URL, credentials, root path, and cache settings.
|
||
- Implement `Plugin : BasePlugin<PluginConfiguration>` to override `Name`, `Id`, and inject DI.
|
||
- Create `IPluginServiceRegistrator` to register services:
|
||
- `WebDavClientService` (singleton)
|
||
- `RemoteLibraryProvider` (scanning)
|
||
- `StreamingController` (ASP.NET Controller)
|
||
- Register virtual folder with `ILibraryManager.RegisterVirtualFolder` on startup.
|
||
|
||
## 3. Scanning Proof-of-Concept (M2)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
subgraph Plugin Core
|
||
Cfg[PluginConfiguration<br/>– holds URL, creds, rootPath, cache settings]
|
||
Reg[ServiceRegistrator<br/>– registers DI & virtual folder]
|
||
end
|
||
|
||
subgraph Scanning POC
|
||
WCS[WebDavClientService<br/>– list, HEAD for size]
|
||
RLP[RemoteLibraryProvider<br/>– implements scanning]
|
||
MI[MediaInfoParser<br/>– extract duration]
|
||
Items[BaseItem list]
|
||
end
|
||
|
||
Cfg --> Reg
|
||
Reg --> WCS
|
||
Reg --> RLP
|
||
WCS --> RLP
|
||
RLP --> MI
|
||
RLP --> Items
|
||
Items --> ScanEngine[Jellyfin Scan Engine]
|
||
```
|
||
|
||
**POC Interface Choice:**
|
||
Use an `IHostedService` (the existing `WebDavSyncService`) to sync remote content into a local cache directory, then register that directory via `ILibraryManager.AddVirtualFolder`. This leverages the built‑in file system scan engine for enumeration and HEAD/partial reads for metadata retrieval.
|
||
|
||
### 3.1 Dependency Injection & Registration
|
||
- Add `RemoteLibraryProvider` to DI with `serviceCollection.AddSingleton<RemoteLibraryProvider>();`.
|
||
- On startup in a hosted service, call `ILibraryManager.RegisterVirtualFolder("Nextcloud", providerInstance)` to hook into Jellyfin's scan pipeline.
|
||
|
||
### 3.2 Plugin Configuration
|
||
- Ensure `PluginConfiguration` exposes:
|
||
- `WebDavUrl`, `Username`, `Password`
|
||
- `RootPath`, `CacheDirectory`, `CacheSizeMb`
|
||
|
||
### 3.3 RemoteLibraryProvider Implementation
|
||
- Inject `WebDavClientService`, `PluginConfiguration`, and `ILogger<RemoteLibraryProvider>` in the constructor.
|
||
- Implement `GetItemsAsync(BaseItem parent, CancellationToken ct)`:
|
||
1. Call `webDav.ListAsync(cfg.RootPath + parent.Path)` to enumerate remote children.
|
||
2. For directories: create `new BaseItem { Name = dirName, IsFolder = true, Id = GenerateId(path) }`.
|
||
3. For video files:
|
||
- Use `webDav.HeadAsync(path)` to get `Content-Length` for size.
|
||
- Download a small buffer and parse with `MediaInfoParser.Parse(stream)` to get `Duration`.
|
||
- Create `new BaseItem { Name = fileName, RunTimeTicks = durationTicks, MediaSources = { new MediaSourceInfo { Size = size } }, Id = GenerateId(path) }`.
|
||
4. Return the list of `BaseItem`s.
|
||
|
||
### 3.4 Logging & Diagnostics
|
||
- Log total items found per folder and individual metadata (size, duration) for verification.
|
||
|
||
### 3.5 Manual Validation
|
||
- Deploy locally, configure plugin with test Nextcloud credentials.
|
||
- Restart Jellyfin and trigger a library scan.
|
||
- Verify in logs that the `RemoteLibraryProvider` runs and emits items with correct size and duration.
|
||
## 4. Streaming & Caching
|
||
- Create `StreamingController : ControllerBase` with endpoint `/WebDav/Stream/{itemId}`.
|
||
- Map `itemId` to remote path and stream via `WebDavClientService.GetStream`.
|
||
- Implement `CachingLayer` to buffer chunks and write to temp files to prevent stalls.
|
||
|
||
## 5. Admin UI
|
||
- Define `configPage.html` as an embedded resource and implement `IHasWebPages` in `Plugin.cs` to return a `PluginPageInfo` for the settings page.
|
||
- Update `build.yaml` to include a `pages` section:
|
||
```yaml
|
||
pages:
|
||
- name: WebDAV
|
||
embeddedResourcePath: Jellyfin.Plugin.Webdav.Configuration.configPage.html
|
||
```
|
||
- Rebuild the plugin so that MSBuild generates a `plugin.json` manifest containing the pages definition.
|
||
- Deploy the `plugin.json`, DLL, and dependencies to Jellyfin’s `plugins` folder.
|
||
- Restart Jellyfin to verify the “WebDAV” settings page appears under Admin → Plugins.
|
||
|
||
## 6. Testing & Validation
|
||
- Unit-test `WebDavClientService` using a test Nextcloud instance or mock.
|
||
- Deploy plugin locally; verify library shows Nextcloud virtual folders.
|
||
- Test playback to ensure smooth streaming.
|
||
|
||
## 7. Documentation & Release
|
||
- Write README with installation, configuration, and troubleshooting guidance.
|
||
- Bump version, package plugin (`.nupkg`), and publish to GitHub Releases.
|
||
|
||
### Milestones
|
||
- **M1**: Plugin skeleton & DI wiring
|
||
- **M2**: Scanning proof-of-concept
|
||
- **M3**: Streaming proxy & caching
|
||
- **M4**: Admin UI & settings page
|
||
- **M5**: Testing, documentation, release |