# 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
– holds URL, creds, paths] B[Plugin
– BasePlugin] C[IPluginServiceRegistrator
– registers services] D[IHostedService
– hook on startup] end subgraph Services E[WebDavClientService
– wraps WebDav.Client] F[RemoteLibraryProvider
– implements virtual folder scanning] G[CachingLayer
– buffer / temporary file cache] H[StreamingController
– ControllerBase for proxying streams] end subgraph Jellyfin Core I[ILibraryManager
– library registration] J[Scan Engine
– calls provider to enumerate items] K[HTTP Pipeline
– 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` 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
– holds URL, creds, rootPath, cache settings] Reg[ServiceRegistrator
– registers DI & virtual folder] end subgraph Scanning POC WCS[WebDavClientService
– list, HEAD for size] RLP[RemoteLibraryProvider
– implements scanning] MI[MediaInfoParser
– 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();`. - 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` 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