// // Swiftfin is subject to the terms of the Mozilla Public // License, v2.0. If a copy of the MPL was not distributed with this // file, you can obtain one at https://mozilla.org/MPL/2.0/. // // Copyright (c) 2025 Jellyfin & Jellyfin Contributors // import Foundation import JellyfinAPI // TODO: the video player needs to be slightly refactored anyways, so I'm fine // with the channel retrieving method below and is mainly just for reference // for how I should probably handle getting the channels of programs elsewhere. final class LiveVideoPlayerManager: VideoPlayerManager { @Published var program: ChannelProgram? init(item: BaseItemDto, mediaSource: MediaSourceInfo, program: ChannelProgram? = nil) { self.program = program super.init() Task { do { logger.info("LiveVideoPlayerManager: Starting playback setup for channel: \(item.displayTitle)") let viewModel = try await item.liveVideoPlayerViewModel(with: mediaSource, logger: logger) await MainActor.run { logger.info("LiveVideoPlayerManager: Successfully created view model, setting currentViewModel") self.currentViewModel = viewModel } } catch { logger.error("LiveVideoPlayerManager: Failed to create video player view model - \(error.localizedDescription)") // TODO: Need to display error to user - VideoPlayerManager doesn't have error property } } } init(program: BaseItemDto) { super.init() Task { do { logger.info("LiveVideoPlayerManager: Getting channel for program: \(program.displayTitle)") guard let channel = try await self.getChannel(for: program), let mediaSource = channel.mediaSources?.first else { let errorMsg = "No channel or media source for program" logger.error("LiveVideoPlayerManager: \(errorMsg)") // TODO: Need to display error to user - VideoPlayerManager doesn't have error property return } logger.info("LiveVideoPlayerManager: Found channel, creating view model") let viewModel = try await program.liveVideoPlayerViewModel(with: mediaSource, logger: logger) await MainActor.run { logger.info("LiveVideoPlayerManager: Successfully created view model") self.currentViewModel = viewModel } } catch { logger.error("LiveVideoPlayerManager: Failed to set up playback - \(error.localizedDescription)") // TODO: Need to display error to user - VideoPlayerManager doesn't have error property } } } private func getChannel(for program: BaseItemDto) async throws -> BaseItemDto? { var parameters = Paths.GetItemsByUserIDParameters() parameters.fields = .MinimumFields parameters.ids = [program.channelID ?? ""] let request = Paths.getItemsByUserID( userID: userSession.user.id, parameters: parameters ) let response = try await userSession.client.send(request) return response.value.items?.first } }