Jellyfin music videos imported with no media streams — channels 402/403 fail to play #924
Closed
opened 2026-10-21 22:16:36 +02:00 by timothy
·
5 comments
No Branch/Tag Specified
main
renovate/meziantou.analyzer-3.x
renovate/nuget-sixlabors.imagesharp-vulnerability
913-scripted-playout-401
929-vuln-pkcs-imagesharp-v4
renovate/dotnet-monorepo
release/v26.15.0-notes
renovate/lucene.net
renovate/cliwrap-3.x
issue-806-guard-populations
scratch/767b-poisoned
scratch/767b-control
release/v26.14.0-notes
release/v26.14.0
renovate/sqlitepclraw.bundle_e_sqlite3-3.x
docs/510-skill-logo-bug-policy
fix/510-watermark-resolution-policy
fix/629-verdict-classifier-falseopens
fix/609-decisions-edit-token-scope
issue-135-clear-to-none
release/v26.12.0-notes
fix/409b-lastscan-api-parity
fix/401-updatechannel-mirror-422
fix/327-playlist-rename-validation
fix/410-scancancel-log-level
fix/409-447-librariesscreen-neverscanned
fix/338-zap-exit-code
fix/367-plex-budget-message
fix/310-debom-legacy-cs
ci/604-lane-rebalance
feat/388-design-mirror
feat/247-test-ownership
feat/247-primary-action
feat/357-player-owned-playback
feat/357-jellyfin-plugin-poc
fix/289-mcp-hardening
issue58-mcp
feat/244-channels-extract
ci/auto-bump-prod-compose
feat/multi-rerun-collections-api
feat/collections-api
feat/quick-wins
feat/185-docs-part2
feat/140-collections-screen
feat/146-channel-edit
feat/147-classic-ui-link
issue22-renovate-dashboard
feat/91-cutover
feat/63-composite-create
feat/65-library-browse
feat/85-epg
feat/86-schedule-editor
feat/109-dashboard-data
feat/99-session-tracking
fix/dockerfile-node-tag
feat/59-spa-foundation
docs/59-ui-redesign-brief
feat/102-json-guide
feat/111-schedule-durations
feat/104-artwork-upload
feat/103-media-sources-api
feat/playouts-read-api
feat/108-health-api
feat/105-picker-list-endpoints
issue-97-channel-state-api
issue42-jellyfin-musicvideos
issue46-rest-api-error-contract
dependabot/nuget/ErsatzTV.FFmpeg.Tests/multi-d307a2e06f
qsv-improvements
hdr-vulkan-cuda-test
v26.16.0
v26.15.0
v26.14.0
v26.13.0
v26.12.0
v26.11.0
v26.10.0
v26.9.0
v26.8.0
v26.7.0
blazor-final
v26.6.0
v26.5.0
v26.4.0
v26.3.1
v26.3.0
v26.2.0
v26.1.1
v26.1.0
v25.9.0
v25.8.0
v25.7.1
v25.7.0
v25.6.0
v25.5.0
v25.4.0
v25.3.1
v25.3.0
v25.2.0
v25.1.0
v0.8.8-beta
v0.8.7-beta
v0.8.6-beta
v0.8.5-beta
v0.8.4-beta
v0.8.3-beta
v0.8.2-beta
v0.8.1-beta
v0.8.0-beta
v0.7.9-beta
v0.7.8-beta
v0.7.7-beta
v0.7.6-beta
v0.7.5-beta
v0.7.4-beta
v0.7.3-beta
v0.7.2-beta
v0.7.1-beta
v0.7.0-beta
v0.6.9-beta
v0.6.8-beta
v0.6.7-beta
v0.6.6-beta
v0.6.5-beta
v0.6.4-beta
v0.6.3-beta
v0.6.2-beta
v0.6.1-beta
v0.6.0-beta
v0.5.8-beta
v0.5.7-beta
v0.5.6-beta
v0.5.5-beta
v0.5.4-beta
v0.5.3-beta
v0.5.2-beta
v0.5.1-beta
v0.5.0-beta
v0.4.5-alpha
v0.4.4-alpha
v0.4.3-alpha
v0.4.2-alpha
v0.4.1-alpha
v0.4.0-alpha
v0.3.8-alpha
v0.3.7-alpha
develop
v0.3.6-alpha
v0.3.5-alpha
v0.3.4-alpha
v0.3.3-alpha
v0.3.2-alpha
v0.3.1-alpha
v0.3.0-alpha
v0.2.5-alpha
v0.2.4-alpha
v0.2.3-alpha
v0.2.2-alpha
v0.2.1-alpha
v0.2.0-alpha
v0.1.5-alpha
v0.1.4-alpha
v0.1.3-alpha
v0.1.2-alpha
v0.1.1-alpha
v0.1.0-alpha
v0.0.62-alpha
v0.0.61-alpha
v0.0.60-alpha
v0.0.59-alpha
v0.0.58-alpha
v0.0.57-alpha
v0.0.56-alpha
v0.0.55-alpha
v0.0.54-alpha
v0.0.53-alpha
v0.0.52-alpha
v0.0.51-alpha
v0.0.50-alpha
v0.0.49-prealpha
v0.0.48-prealpha
v0.0.47-prealpha
v0.0.46-prealpha
v0.0.45-prealpha
v0.0.44-prealpha
v0.0.43-prealpha
v0.0.42-prealpha
v0.0.41-prealpha
v0.0.40-prealpha
v0.0.39-prealpha
v0.0.38-prealpha
v0.0.37-prealpha
v0.0.36-prealpha
v0.0.35-prealpha
v0.0.34-prealpha
v0.0.33-prealpha
v0.0.32-prealpha
v0.0.31-prealpha
v0.0.30-prealpha
v0.0.29-prealpha
v0.0.28-prealpha
v0.0.27-prealpha
v0.0.26-prealpha
v0.0.25-prealpha
v0.0.24-prealpha
v0.0.23-prealpha
v0.0.22-prealpha
v0.0.21-prealpha
v0.0.20-prealpha
v0.0.19-prealpha
v0.0.18-prealpha
v0.0.17-prealpha
v0.0.16-prealpha
v0.0.15-prealpha
v0.0.14-prealpha
v0.0.13-prealpha
v0.0.12-prealpha
v0.0.11-prealpha
v0.0.10-prealpha
v0.0.9-prealpha
v0.0.8-prealpha
v0.0.7-prealpha
v0.0.6-prealpha
v0.0.5-prealpha
v0.0.4-prealpha
v0.0.3-prealpha
v0.0.2-prealpha
v0.0.1-prealpha
Labels
Clear labels
ad-hoc
api
bug
ci-cd
content
dependencies
enhancement
frontend
in-progress
jellyfin
parked
priority: high
priority: low
priority: medium
review
security
One-off / ad-hoc work not tracked by a dedicated issue
REST API / HTTP endpoints
Something isn't working
Build, test, deploy pipeline
Channel content / schedules / playlists
Dependency updates (Renovate)
New feature or improvement
ChicoryTV React SPA frontend
Claimed by an active session — do not pick up
Jellyfin tuner / IPTV integration
Excluded from automatic queue pickup; work only when explicitly selected
Adversarial review finding
Security / vulnerability fix
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: timothy/ersatztv#924
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom
Channels 402 (Hip Hop & Soul) and 403 (Retro TV Music) won't play. Every HLS session start fails with:
Other channels (e.g. 100) are fine.
Evidence (prod DB on jazz, 2026-10-21)
jellyfin://e2c00f297a5f80af390f52f72e782147): 1520/1520 music-videoMediaVersionrows have zeroMediaStreamrows of any kind,Width=0,Height=0,DateUpdated=0001-01-01. Duration is populated.~/downloadswarm/ersatztv-backups/20260830T152422Z) shows the same 1520/0, so the problem has existed since at least then. It was not caused by today's 18:08 UTC scan.Root cause (code)
JellyfinApiClient.ProjectToMusicVideobuilds the version withStreams = [](line ~749). The movie projection does the same.MediaServerMovieLibraryScanner.UpdateStatisticshandles this: when the head version has no streams, it callsGetMediaServerStatistics, which fetches PlaybackInfo (andServerReturnsStatisticsWithMetadatacovers the other case).MediaServerMusicVideoLibraryScanner.UpdateStatistics(line ~318) just writesincoming.GetHeadVersion(), which is the empty projection, with no statistics fetch. Music videos therefore never get streams. The scanner was introduced in #496 (2026-07-25).Fix direction
GetMediaServerStatistics/ full metadata+statistics whenStreams.Count == 0) into the music-video scanner, then deep-scan library 8.SelectVideoStreamfail with a clear error (or skip the item) instead of a bareFirst()throw.Discovered from server-management while debugging "can't watch Live TV".
Done-when
MediaStreamrows andWidth/Heighton the headMediaVersionwhen the projection carries no streams (statistics fetched as the movie scanner does), for both new and updated itemsFFmpegStreamSelector.SelectVideoStreamon a version with no video stream fails with a clear, actionable error naming the media item, not a bareSequence contains no matching element; pinned by a testClaiming: branch
924-musicvideo-stream-stats, worktree/Users/timothy/orca/workspaces/ersatztv/wt-924(orchestrated session 99d1dedb). Four-way check clean 2026-10-21: no open PR referencing #924, no remote branch matching*924*, no prior claim comment.Correction to the issue body: on prod the Jellyfin "Music Videos" ErsatzTV library is id 16, not 8. There is no Library row with Id 8;
/api/v1/media-sourceslists Jellyfin "Music Videos" as library 16. The count is unchanged at 1520/1520 MusicVideo MediaVersions with zero MediaStream rows (measured by media-management on 2026-10-21 against imagesha256:c724d0ef…). The post-deploy repair isPOST /api/v1/libraries/16/scan?deep=true. Any reference to "library 8" in the branch or closing record should read 16.Closing record
PR: http://192.168.1.95:3000/timothy/ersatztv/pulls/928 (head
9d3989140f). Not closed here; the merge closes it.What changed: music-video scanner now reads statistics from the server (Jellyfin playback info) under the movie scanner's refresh condition and writes nothing when the server cannot answer; SelectVideoStream names the version, file and remediation. Decision record
scan.mediaserver-statistics-from-server.Other scanners: other-video (Plex only, ServerReturnsStatisticsWithMetadata) and TV (Jellyfin/Emby override, Plex with metadata) have no gap.
Follow-ups: prod deep-scan of library 16 -> timothy/media-management#88; etag-on-failed-statistics residual -> ersatztv#927.
Done-when evidence
dotnet test ErsatzTV.Tests --filter JellyfinMusicVideoLibraryScannerTests(ErsatzTV.Tests 2142 passed, 0 failed).ec862ce95message ("Other-video ... and TV ... have no such gap") and the decision record.f90d9ad24.dotnet test ErsatzTV.Core.Tests --filter FFmpegStreamSelectorTests(719 passed, 0 failed).od -A n -t x1 -N 3) shows 75 73 69 on all 5 touched .cs;dotnet format whitespace --verify-no-changes --includeclean; check-doc-narrative 0 warnings.Correction to the issue body: the prod "Music Videos" library is Library.Id 16, not 8. The 8 was the
LibraryPath.Id(pathjellyfin://e2c00f297a5f80af390f52f72e782147), which the diagnostic query printed under anIdcolumn. Use library 16 for the post-fix deep scan (POST /api/v1/libraries/16/scan?deep=true). As of 2026-10-27, library 16 holds 1419 active music videos plus 101 dedup removals (1520 rows total, matching the original count).Live outcome: v26.16.0 on prod, 2026-10-27
jazz-media(server-management): the runningersatztvimage issha256:6d698162a3cb5194f110b36ae5b02666472afb8187965bb6f45a2d8e04789bc0=:26.16.0, on .NET 10.0.14. The pre-deploy backup and migration smoke passed.POST /api/v1/libraries/16/scan?deep=true(media-management, 19:18Z). Library 16 State=0 music-video versions with zeroMediaStreamrows: 1419 → 0, and none lack a video stream. The only stream-less rows left are the 101 soft-trashed duplicates (State=1), as expected.avc1.4D4028HLS variant whose first segment returns200 video/mp2t(~1.1 MB). Re-measured independently from ersatztv after the media-management report.