remove redundant restAPI
playback is controlled by state machine
This commit is contained in:
@@ -31,15 +31,15 @@ JellyLMS enables Jellyfin to stream audio to LMS, which acts as a multi-room spe
|
||||
│ │ Library │──┼────────►│ LmsApiClient │────────►│ │ Players │ │
|
||||
│ │ (Audio) │ │ │ │ │ │ (Zones) │ │
|
||||
│ └───────────┘ │ │ ┌───────────┐ │ │ └───────────┘ │
|
||||
│ │ │ │ Session │ │ │ │
|
||||
│ ┌───────────┐ │ │ │ Manager │ │ │ ┌───────────┐ │
|
||||
│ │ Queue │──┼────────►│ └───────────┘ │────────►│ │ Sync │ │
|
||||
│ │ │ │ │ │ │ │ Groups │ │
|
||||
│ └───────────┘ │ │ ┌───────────┐ │ │ └───────────┘ │
|
||||
│ │ │ │ REST API │ │ │ │
|
||||
│ ┌───────────┐ │ │ │Controller │ │ │ │
|
||||
│ │ Playback │──┼────────►│ └───────────┘ │ │ │
|
||||
│ │ Controls │ │ │ │ │ │
|
||||
│ │ │ │ Session │ │ │ │
|
||||
│ ┌───────────┐ │ │ │Controller │ │ │ ┌───────────┐ │
|
||||
│ │ Queue │──┼────────►│ │ (State │ │────────►│ │ Sync │ │
|
||||
│ │ │ │ │ │ Machine) │ │ │ │ Groups │ │
|
||||
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌───────────┐ │ │ ┌───────────┐ │ │ │
|
||||
│ │ Playback │──┼────────►│ │ REST API │ │ │ │
|
||||
│ │ Controls │ │ │ └───────────┘ │ │ │
|
||||
│ └───────────┘ │ └─────────────────┘ └─────────────────┘
|
||||
└─────────────────┘
|
||||
```
|
||||
@@ -48,8 +48,9 @@ JellyLMS enables Jellyfin to stream audio to LMS, which acts as a multi-room spe
|
||||
|
||||
- **Player Discovery**: Automatically discovers all LMS players/zones
|
||||
- **Multi-Room Sync**: Create and manage sync groups for synchronized playback across multiple rooms
|
||||
- **Playback Control**: Play, pause, stop, seek, and volume control forwarded to LMS
|
||||
- **Playback Control**: Play, pause, stop, seek, and volume control via Jellyfin's "Play On" (cast) interface
|
||||
- **Stream Bridging**: Generates audio stream URLs from Jellyfin for LMS to consume
|
||||
- **Robust State Machine**: Ensures proper sequencing of playback operations with automatic retry and timeout handling
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -76,9 +77,62 @@ Create and manage synchronized playback groups for multi-room audio:
|
||||
## Requirements
|
||||
|
||||
- Jellyfin Server 10.10.0 or later
|
||||
- .NET 8.0 Runtime
|
||||
- .NET 9.0 Runtime
|
||||
- Logitech Media Server (LMS) with JSON-RPC API enabled (default on port 9000)
|
||||
|
||||
## Playback Architecture
|
||||
|
||||
JellyLMS uses Jellyfin's native "Play On" (cast) interface to control LMS players. When you select an LMS player from Jellyfin's cast menu, playback is managed through a robust state machine that ensures reliable operation.
|
||||
|
||||
### State Machine
|
||||
|
||||
The playback controller uses a state machine to ensure proper sequencing of operations:
|
||||
|
||||
```
|
||||
┌────────┐
|
||||
│ Idle │ (device connected, no media)
|
||||
└───┬────┘
|
||||
│ Play command
|
||||
▼
|
||||
┌────────┐
|
||||
┌────►│Loading │◄────┐
|
||||
│ └───┬────┘ │
|
||||
│ │ │ Seek (HTTP streaming
|
||||
│ LMS confirms │ restarts stream)
|
||||
│ mode="play" │
|
||||
│ ▼ │
|
||||
┌───────┐ │ ┌────────┐ │
|
||||
│ Error │◄────┼─────│Playing │─────┘
|
||||
└───┬───┘ │ └───┬────┘
|
||||
│ │ │ Pause
|
||||
retry │ ▼
|
||||
│ │ ┌────────┐
|
||||
└─────────┼─────│ Paused │
|
||||
│ └───┬────┘
|
||||
│ │ Seek (native LMS)
|
||||
│ ▼
|
||||
│ ┌────────┐
|
||||
└─────│Seeking │
|
||||
└────────┘
|
||||
|
||||
From any state: Stop → Stopped
|
||||
```
|
||||
|
||||
### How Playback Works
|
||||
|
||||
1. **Cast Request**: User selects an LMS player from Jellyfin's "Play On" menu
|
||||
2. **Loading**: Plugin sends play command to LMS and transitions to Loading state
|
||||
3. **Confirmation**: Plugin polls LMS until playback is confirmed (mode="play")
|
||||
4. **Playing**: Playback is active; progress is synced between Jellyfin and LMS
|
||||
5. **Controls**: Play, pause, seek, and volume commands are forwarded to LMS
|
||||
|
||||
### Error Handling
|
||||
|
||||
The state machine includes automatic retry with exponential backoff:
|
||||
- **Timeout errors**: Auto-retry up to 2 times (500ms → 1s delay)
|
||||
- **Network errors**: Auto-retry up to 2 times
|
||||
- **LMS errors**: No retry, transition to Error state
|
||||
|
||||
## Installation
|
||||
|
||||
### Manual Installation
|
||||
@@ -101,7 +155,7 @@ cd jellyLMS
|
||||
dotnet build Jellyfin.Plugin.JellyLMS.sln -c Release
|
||||
|
||||
# The DLL will be in:
|
||||
# Jellyfin.Plugin.JellyLMS/bin/Release/net8.0/
|
||||
# Jellyfin.Plugin.JellyLMS/bin/Release/net9.0/
|
||||
```
|
||||
|
||||
## Configuration
|
||||
@@ -116,41 +170,45 @@ dotnet build Jellyfin.Plugin.JellyLMS.sln -c Release
|
||||
| Connection Timeout | Timeout for LMS API calls (seconds) | `10` |
|
||||
| Enable Auto Sync | Automatically sync players when creating groups | `true` |
|
||||
| Default Player | MAC address of the default player | (none) |
|
||||
| Use Direct File Path | Enable direct file access instead of HTTP streaming | `false` |
|
||||
|
||||
### Advanced Settings (State Machine)
|
||||
|
||||
| Setting | Description | Default |
|
||||
|---------|-------------|---------|
|
||||
| Loading Timeout | Max time to wait for LMS to start playback (seconds) | `5` |
|
||||
| Seek Timeout | Max time to wait for seek to complete (seconds) | `3` |
|
||||
| Transition Poll Interval | How often to poll LMS during state transitions (ms) | `300` |
|
||||
| Max Auto Retries | Number of automatic retries for transient failures | `2` |
|
||||
|
||||
3. Click "Test Connection" to verify connectivity to LMS
|
||||
4. Use "Discover Players" to see available LMS players
|
||||
|
||||
## API Endpoints
|
||||
|
||||
The plugin exposes REST API endpoints under `/JellyLms/`:
|
||||
The plugin exposes REST API endpoints under `/JellyLms/` for player and sync group management.
|
||||
|
||||
**Note:** Playback control (play, pause, seek, volume) is handled through Jellyfin's native "Play On" (cast) interface, not through REST endpoints.
|
||||
|
||||
### Players
|
||||
|
||||
- `GET /JellyLms/Players` - List all LMS players
|
||||
- `GET /JellyLms/Players/{mac}` - Get specific player details
|
||||
- `POST /JellyLms/Players/Refresh` - Refresh player list from LMS
|
||||
- `POST /JellyLms/Players/{mac}/PowerOn` - Power on a player
|
||||
- `POST /JellyLms/Players/{mac}/PowerOff` - Power off a player
|
||||
- `POST /JellyLms/Players/{mac}/Volume` - Set player volume
|
||||
|
||||
### Sync Groups
|
||||
|
||||
- `GET /JellyLms/SyncGroups` - List all sync groups
|
||||
- `POST /JellyLms/SyncGroups` - Create a new sync group
|
||||
- `DELETE /JellyLms/SyncGroups/{masterMac}` - Dissolve a sync group
|
||||
- `DELETE /JellyLms/SyncGroups/{masterMac}/Players/{slaveMac}` - Remove player from group
|
||||
- `DELETE /JellyLms/SyncGroups/Players/{mac}` - Remove player from its sync group
|
||||
|
||||
### Sessions
|
||||
### Utilities
|
||||
|
||||
- `GET /JellyLms/Sessions` - List active playback sessions
|
||||
- `POST /JellyLms/Sessions` - Start a new playback session
|
||||
- `POST /JellyLms/Sessions/{id}/Pause` - Pause playback
|
||||
- `POST /JellyLms/Sessions/{id}/Resume` - Resume playback
|
||||
- `POST /JellyLms/Sessions/{id}/Stop` - Stop playback
|
||||
- `POST /JellyLms/Sessions/{id}/Seek` - Seek to position
|
||||
- `POST /JellyLms/Sessions/{id}/Volume` - Set volume
|
||||
|
||||
### Status
|
||||
|
||||
- `GET /JellyLms/Status` - Get LMS connection status
|
||||
- `POST /JellyLms/TestConnection` - Test LMS connectivity
|
||||
- `GET /JellyLms/DiscoverPaths` - Discover file paths for direct file access configuration
|
||||
|
||||
## LMS Setup
|
||||
|
||||
@@ -218,15 +276,17 @@ Jellyfin.Plugin.JellyLMS/
|
||||
│ ├── PluginConfiguration.cs # Plugin settings
|
||||
│ └── configPage.html # Dashboard configuration UI
|
||||
├── Api/
|
||||
│ └── JellyLmsController.cs # REST API endpoints
|
||||
│ └── JellyLmsController.cs # REST API endpoints (players, sync groups)
|
||||
├── Services/
|
||||
│ ├── ILmsApiClient.cs # LMS API interface
|
||||
│ ├── LmsApiClient.cs # LMS JSON-RPC client
|
||||
│ ├── LmsPlayerManager.cs # Player discovery & sync
|
||||
│ └── LmsSessionManager.cs # Playback session management
|
||||
│ ├── LmsSessionController.cs # Playback control (ISessionController)
|
||||
│ ├── PlaybackStateMachine.cs # State machine for playback lifecycle
|
||||
│ └── LmsStatusPoller.cs # Polls LMS to confirm state transitions
|
||||
└── Models/
|
||||
├── LmsPlayer.cs # Player model
|
||||
├── LmsPlaybackSession.cs # Session state model
|
||||
├── LmsPlaybackSession.cs # Session state (incl. PlaybackState enum)
|
||||
└── LmsApiModels.cs # JSON-RPC DTOs
|
||||
```
|
||||
|
||||
@@ -237,7 +297,7 @@ Jellyfin.Plugin.JellyLMS/
|
||||
dotnet build Jellyfin.Plugin.JellyLMS.sln
|
||||
|
||||
# Copy to Jellyfin plugins directory
|
||||
cp Jellyfin.Plugin.JellyLMS/bin/Debug/net8.0/Jellyfin.Plugin.JellyLMS.dll \
|
||||
cp Jellyfin.Plugin.JellyLMS/bin/Debug/net9.0/Jellyfin.Plugin.JellyLMS.dll \
|
||||
~/.local/share/jellyfin/plugins/JellyLMS/
|
||||
|
||||
# Restart Jellyfin to load the plugin
|
||||
|
||||
Reference in New Issue
Block a user