Files
plezy/lib/utils/downloaded_version_match.dart
T
edde746 fd4291aafb fix(playback): play the downloaded version when offline close #1440
Plain Play requests the default media version (index 0 or the saved
preference), but the offline resolvers rejected the single downloaded
row when a non-default version was downloaded, then threw "No video
URL available" with no client to fall back to.

Three-part fix sharing one matcher (downloadedVersionMatches):
- getPlaybackData falls back to the downloaded version when there is no
  client to stream from; the result now carries the effective
  mediaIndex/mediaSourceId so cached media info and the committed
  session describe the file actually played.
- navigateToVideoPlayer seeds the selection from the download record
  for isOffline plays with no explicit version, covering the external
  player branch and offline-library plays with a reachable server.
- PlaybackSession.fromContext prefers the result source id over the
  requested one, keeping in-player state in sync after a fallback.

Online pinning is untouched: with a live client an explicitly requested
non-downloaded version still streams from the server.
2026-07-03 10:19:55 +02:00

31 lines
1.1 KiB
Dart

import '../database/app_database.dart';
/// Single source of truth for "does this downloaded row satisfy a version
/// request".
///
/// Source-id comparison wins when both sides have one — Jellyfin merged
/// versions can reorder between item fetches, so the stable id is the only
/// trustworthy discriminator there. Otherwise fall back to the media index.
/// A null [requestedMediaIndex] means "any version" (the caller has no
/// version opinion, e.g. external-player launches keyed by item only).
bool downloadedVersionMatches(
DownloadedMediaItem row, {
int? requestedMediaIndex,
String? requestedMediaSourceId,
}) {
final downloadedSourceId = row.mediaSourceId;
final requestedSourceId = requestedMediaSourceId?.trim();
final comparedBySourceId =
requestedSourceId != null &&
requestedSourceId.isNotEmpty &&
downloadedSourceId != null &&
downloadedSourceId.isNotEmpty;
if (comparedBySourceId) {
return downloadedSourceId == requestedSourceId;
}
if (requestedMediaIndex == null) {
return true;
}
return row.mediaIndex == requestedMediaIndex;
}