Clean up stale Continue Watching entries
🏗️ Build Plugin / build (push) Successful in 1m43s
🧪 Test Plugin / test (push) Successful in 34s
🚀 Release Plugin / build-and-release (push) Successful in 51s
Nightly Build / nightly-build (push) Failing after 50s

Livestreams and ended broadcasts accumulated in every user's resume row
because Jellyfin saves a playback position for channel items regardless
of whether the position means anything. A livestream has nothing to
return to, so the entry stayed pinned forever.

Two parts:

- PlaybackResumeGuard, an IHostedService on ISessionManager.PlaybackStopped.
  Jellyfin saves the resume point before raising the event, so the guard
  zeroes it afterwards for livestreams. Stops new entries at the source.
- ResumeCleanupService plus a daily 4 AM task (after the 3 AM expiration
  check) for the existing backlog. Clears livestreams, resume points older
  than N days, positions under N seconds and playback past N% of runtime,
  each threshold configurable.

Only plugin-owned items are touched, matched by the SRF provider ID with a
fallback to the owning channel ID so recordings are covered too. Clearing
sets PlaybackPositionTicks to 0 and leaves Played false: nothing is deleted
and the item stays unwatched.

Config page gains the thresholds plus "Clean Up Stale Entries Now" and
"Clear All SRF Play Entries" buttons, backed by MaintenanceController
under RequiresElevation.

Also folds the duplicated urn.Contains("livestream") check in
MediaSourceFactory and RecordingService into UrnHelper.IsLivestreamUrn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 18:55:41 +02:00
co-authored by Claude Opus 5
parent a9db0aa09c
commit 390146e8d4
13 changed files with 766 additions and 2 deletions
+11
View File
@@ -22,6 +22,7 @@ Then install "SRF Play" from the plugin catalog.
- **Live Sports Streaming** - Watch scheduled sports events (skiing, Formula 1, football, tennis, etc.)
- Support for all Swiss broadcasting units (SRF, RTS, RSI, RTR, SWI)
- Automatic content expiration handling
- Continue Watching cleanup — ended livestreams and abandoned playback don't pile up in the resume row
- Latest and trending content discovery
- Quality selection (Auto lets CDN decide, SD prefers 480p/360p, HD prefers 1080p/720p)
- HLS streaming support with Akamai token authentication
@@ -137,6 +138,16 @@ The compiled plugin will be in `bin/Debug/net8.0/`
- **Proxy Address**: Proxy server URL (e.g., http://proxy.example.com:8080)
- **Proxy Username**: Optional authentication username
- **Proxy Password**: Optional authentication password
- **Continue Watching Cleanup**: Stops stale SRF Play entries accumulating in the resume row
- **Clean up stale resume points**: Enables the daily "Clean Up SRF Play Continue Watching" task (4 AM)
- **Never keep a resume point for livestreams**: Clears the position the moment a livestream stops
- **Maximum Resume Point Age**: Clear entries untouched for this many days (default 30, 0 disables)
- **Minimum Resume Position**: Clear entries at or below this position (default 60s, 0 disables)
- **Finished Threshold**: Clear entries at or beyond this share of the runtime (default 92%, 0 disables)
Clearing a resume point only resets the playback position. Nothing is deleted, the item stays
unwatched, and only SRF Play items are ever touched. The plugin config page also has
**Clean Up Stale Entries Now** and **Clear All SRF Play Entries** buttons for running it on demand.
For detailed proxy setup instructions, see [PROXY_SETUP_GUIDE.md](PROXY_SETUP_GUIDE.md).