Files
plezy/lib/services/live_session_tracker.dart
edde746 a7527718df refactor(services): delete dead branches, write-only fields, and test-only cache/service surface
plex_client.selectStreams' allParts=false branch, download_manager's both-branches-true conditional and unscoped getAllPinnedMetadata tail, playback_source_resolver.preferOffline, and update_service's unreachable catches had no reachable path; PlaybackSession.result/streamHeaders, PlaybackContext.clientScopeId, FileInfoStreams.audioStream, PrefsRepairOutcome.settingsReset/sessionsSalvaged, and JellyfinLiveSessionTracker.playSessionId were write-only; PlexConnection.directUrl, PlexServer.isOnline plus its parse-and-persist presence field, SafStorageService.createDirectory, FullscreenStateManager.stopMonitoring/dispose, the play_queue_launcher re-export shim, track-selection's constant params, and PlexApiCache.unpinForOffline/isPinnedRatingKey (matching the earlier Jellyfin removal) were dead API.
2026-08-17 19:02:25 +02:00

52 lines
1.8 KiB
Dart

import '../utils/app_logger.dart';
import '../utils/session_identifier.dart';
import 'jellyfin_client.dart';
import 'playback_report_session.dart';
/// Lightweight state machine for Jellyfin live TV playback heartbeats.
///
/// Delegates start/progress/stop ordering to [PlaybackReportSession] so live
/// heartbeats follow the same terminal-state rules as normal playback. The
/// Plex live path keeps its bespoke capture-buffer flow inline at the call
/// site; this tracker only covers Jellyfin's `/Sessions/Playing*` flow.
class JellyfinLiveSessionTracker {
JellyfinLiveSessionTracker({String? playSessionId, this.mediaSourceId, this.liveStreamId, this.playMethod})
: _playSessionId = playSessionId ?? generateSessionIdentifier();
final String _playSessionId;
final String? mediaSourceId;
final String? liveStreamId;
final String? playMethod;
PlaybackReportSession? _session;
/// Send the appropriate heartbeat for [state] (`'playing'`, `'paused'`,
/// or `'stopped'`). Errors are swallowed — heartbeats are best-effort.
Future<void> report({
required JellyfinClient client,
required String itemId,
required String state,
required Duration position,
required Duration duration,
}) async {
try {
final session = _session ??= PlaybackReportSession(
client: client,
itemId: itemId,
playSessionId: _playSessionId,
playMethod: playMethod,
liveStreamId: liveStreamId,
);
await session.report(
PlaybackReportSnapshot(
state: state,
position: position,
duration: duration,
resolveStreamSelection: () => PlaybackStreamSelection(mediaSourceId: mediaSourceId),
),
);
} catch (e) {
appLogger.d('Jellyfin live progress report failed', error: e);
}
}
}