From bc16262b20407ddb1d9563151672318c4ffb1fe3 Mon Sep 17 00:00:00 2001 From: Stephen Byatt <47413006+stephenb10@users.noreply.github.com> Date: Sat, 26 Jun 2021 19:13:03 +1000 Subject: [PATCH] Next up logic --- JellyfinPlayer/VideoPlayer.swift | 71 +++++++++++++++++++++++----- JellyfinPlayer/VideoUpNextView.swift | 23 ++++++--- 2 files changed, 77 insertions(+), 17 deletions(-) diff --git a/JellyfinPlayer/VideoPlayer.swift b/JellyfinPlayer/VideoPlayer.swift index 5e64a910..d4c3dd26 100644 --- a/JellyfinPlayer/VideoPlayer.swift +++ b/JellyfinPlayer/VideoPlayer.swift @@ -394,6 +394,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe titleLabel.text = "S\(String(manifest.parentIndexNumber ?? 0)):E\(String(manifest.indexNumber ?? 0)) “\(manifest.name ?? "")”" setupNextUpView() + upNextViewModel.delegate = self } if !UIDevice.current.orientation.isLandscape || UIDevice.current.orientation.isFlat { @@ -454,7 +455,13 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe mediaPlayer.delegate = self mediaPlayer.drawable = videoContentView + + setupMediaPlayer() + } + + func setupMediaPlayer() { + // Fetch max bitrate from UserDefaults depending on current connection mode let maxBitrate = Defaults[.inNetworkBandwidth] @@ -690,16 +697,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe } func setupNextUpView() { - // Get next episode item - TvShowsAPI.getEpisodes(seriesId: manifest.seriesId!, userId: SessionManager.current.user.user_id!, season: manifest.parentIndexNumber ?? 0, startIndex: manifest.indexNumber, limit: 1) - .sink(receiveCompletion: { completion in - print(completion) - }, receiveValue: { [self] response in - if let item = response.items?.first { - self.upNextViewModel.item = item - } - }) - .store(in: &cancellables) + getNextEpisode() // Create the swiftUI view let contentView = UIHostingController(rootView: VideoUpNextView(viewModel: upNextViewModel)) @@ -715,6 +713,57 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe smallView = upNextView.frame largeView = CGRect(x: 500, y: 90, width: 400, height: 270) } + + func getNextEpisode() { + TvShowsAPI.getEpisodes(seriesId: manifest.seriesId!, userId: SessionManager.current.user.user_id!, season: manifest.parentIndexNumber ?? 0, startIndex: manifest.indexNumber, limit: 1) + .sink(receiveCompletion: { completion in + print(completion) + }, receiveValue: { [self] response in + if let item = response.items?.first { + self.upNextViewModel.item = item + } + }) + .store(in: &cancellables) + } + + func setPlayerToNextUp() { + mediaPlayer.stop() + + ssTargetValueOffset = 0 + ssStartValue = 0 + + paused = true + lastTime = 0.0 + startTime = 0 + controlsAppearTime = 0 + isSeeking = false + + + remotePositionTicks = 0 + + selectedPlaybackSpeedIndex = 3 + selectedAudioTrack = -1 + selectedCaptionTrack = -1 + playSessionId = "" + lastProgressReportTime = 0 + subtitleTrackArray = [] + audioTrackArray = [] + + manifest = upNextViewModel.item! + playbackItem = PlaybackItem() + + upNextViewModel.item = nil + + upNextView.isHidden = true + shouldShowLoadingScreen = true + videoControlsView.isHidden = true + + titleLabel.text = "S\(String(manifest.parentIndexNumber ?? 0)):E\(String(manifest.indexNumber ?? 0)) “\(manifest.name ?? "")”" + + setupMediaPlayer() + getNextEpisode() + } + } // MARK: - GCKGenericChannelDelegate @@ -912,7 +961,7 @@ extension PlayerViewController: VLCMediaPlayerDelegate { delegate?.hideLoadingView(self) if manifest.type == "Episode" && upNextViewModel.item != nil{ - if time > 0.95 { + if time > 0.98 { upNextView.isHidden = false } else { upNextView.isHidden = true diff --git a/JellyfinPlayer/VideoUpNextView.swift b/JellyfinPlayer/VideoUpNextView.swift index f3dd5771..a85be5af 100644 --- a/JellyfinPlayer/VideoUpNextView.swift +++ b/JellyfinPlayer/VideoUpNextView.swift @@ -13,6 +13,7 @@ import JellyfinAPI class UpNextViewModel: ObservableObject { @Published var largeView: Bool = false @Published var item: BaseItemDto? = nil + var delegate: PlayerViewController? func episodeAndSeasonNumber() -> String { if let pID = item?.parentIndexNumber, let id = item?.indexNumber { @@ -27,6 +28,13 @@ class UpNextViewModel: ObservableObject { } return "" } + + func nextUp() { + if delegate != nil { + delegate?.setPlayerToNextUp() + } + } + } struct VideoUpNextView: View { @@ -35,14 +43,12 @@ struct VideoUpNextView: View { var body: some View { - Button(action: { - print("Next episode") - }, label: { - + Button(action: viewModel.nextUp, label: { VStack(alignment: viewModel.largeView ? .leading : .center) { Text("Up Next") .foregroundColor(.white) .font(viewModel.largeView ? .title : .body) + .shadow(radius: 10) image @@ -52,7 +58,7 @@ struct VideoUpNextView: View { .foregroundColor(.white) .font(.title) .lineLimit(1) - + .shadow(radius: 10) } } @@ -65,7 +71,12 @@ struct VideoUpNextView: View { ImageView(src: url) .frame(maxWidth: .infinity) .aspectRatio(CGSize(width: 16, height: 9), contentMode: .fit) - .overlay(overlayIndicator, alignment: .topTrailing)) + .overlay(overlayIndicator, alignment: .topTrailing) + .cornerRadius(5) + .shadow(radius: 10) + ) + + } else { return AnyView(EmptyView())