From ff6b01c429963798a5b7c602fa07cf415661f00d Mon Sep 17 00:00:00 2001 From: cranci1 <100066266+cranci1@users.noreply.github.com> Date: Mon, 23 Dec 2024 16:13:37 +0100 Subject: [PATCH] custom player --- .../UserInterfaceState.xcuserstate | Bin 68266 -> 67705 bytes Sora/Utils/CustomPlayer/CustomPlayer.swift | 85 +++++++++++++----- Sora/Utils/Player/VideoPlayerView.swift | 62 ++++++------- Sora/Views/AnimeViews/AnimeInfoView.swift | 25 +++++- .../EpisodeCell/CircularProgressBar.swift | 11 ++- .../AnimeViews/EpisodeCell/EpisodeCell.swift | 34 +++---- 6 files changed, 145 insertions(+), 72 deletions(-) diff --git a/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate b/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate index cf85bbffcbd3aff59fd266dc9c9eb045df8ee234..50b1dc3d02e92a6d8f79a1ae9beba211d291fdff 100644 GIT binary patch literal 67705 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 literal 68266 zcmeF4cX$-l_weV=ow{vW=)HFmdY6(=LJfr8!jdcy2-%oTr~-39u@?lfD;p3Y7HrtX z1}dm1AYTzw?1~i|Dz^9Bot=;n2+^NB&-+Kj-6T76`{$l}&bjB#&dkfnjua#%y~PoZ z=O`y|A}4V&=b6}aK`1|x9nPK9G?J1sXHZpx! zXmKd3fBdF>oWiN&(hGtGA)9P7q-va(^Kmt}np`ce4cC@y$F=7Yxg@Rw*OBYQrE){L zVcc+T1UHf!#ienhxiMTim&s*uA#N5oo14RBbA{XjZXvgbTg)xvR&f_|S8!Ky*K*f! zH*hy`8@MP}#NE$r;~wB1`jdj4iU%HPFr=8O4z_-*_H{3HD1{1f~$ z{0{yF{w017e}F&Cf5d;rf60H#|G=N%f8l?p7EPelXmwhH)}*y)ZCZ!crS)hd+LE@X ziL@K-PJ7Uvv=>dLDRdxBr9O>h?pu46^DtV#PQ+;aiTa~%n)abbHr?Mt~gJOhy~(R z;??3c;H6(18H7oQNH7hez$i$}zF z#rMSb#iQZ};)mi#;>Y4A;uqp~;&JhW_>1_r#7RWrB`SF(pVU-pCN-B@NG+vSQfsM= z)K+RIwU;_dJ*1veFR8yYKpH9ylZHzpq;b-CDOUX^UL;>9uaU2p*UIbU8|3x!jq*+M&GIes z9r9iBX8B(EK6$(RsQj4xto)pONPb5?EFY2ImEV)!mygOH$REld$)CyJ$luC8$v?|~ z%74j!E1aSzs?tbltTa)YD$SJUN(-f>(n@Kqv{4e3u1Ythk8*)BNExgQQBsxB${1y? zGEd1-<}0~MSjkf^RPvRGQlKnSRw%ZzTDerYR=G}Dqg=1tqTH%HtURJ@R~}U!Qyy2I zP@YttQl3_xQJz;`QFbePlsA=q$~($o(v|8o79`tThu$$yVT9GvRDV+cQ2$i_@<<-p)4H*J6 z&lR34J!?JdJokF;^W5**=6S&Lpywga!=6Vx+dYqZp7cELdD-)d=S|N(&wkHg&k@g$ zo}WBFdro+M@%-xf&2!T8yXOzjpI+isyaBJ~t>LZdt>taxZS3vo?d9$5?c=?`+t=IA z+uu9Do9s>T4)Koij`NQ9PWNVbXL#p$v%TP5>0RZ$*n5e0wf9o*W!}rZS9q`VUh7@& zz0rHS_YUu7@7>-l-Uqx7dUt#GcwhCt=6&6}*ZYR|P47PMe(wSA+urxRN4=kVKl6U; z{my&b`@Q!!?@6EOvwR7@YQE~e8orvoTE5!8I=;HThQ1cQcE0w$uD))*zP^6GiM~m` z$-XJRslI8x>Ano#3}4VU(>KdE-xu)}_%8A-^DXzS_Fd|`)3?DF^%eOx`ZoFQ@@@9r z?c3tp>buYPi0?_?Q@$5{JAJ!+ulx4;KJ$I<`@(n3_oeSE-`BoxeBb)M^Bwp7oihrg%)0{=k&Apc

(d` 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 diff --git a/Sora/Utils/CustomPlayer/CustomPlayer.swift b/Sora/Utils/CustomPlayer/CustomPlayer.swift index 5f09a12..5ed7488 100644 --- a/Sora/Utils/CustomPlayer/CustomPlayer.swift +++ b/Sora/Utils/CustomPlayer/CustomPlayer.swift @@ -12,7 +12,7 @@ struct CustomVideoPlayer: UIViewControllerRepresentable { let player: AVPlayer func makeUIViewController(context: Context) -> AVPlayerViewController { - let controller = CustomAVPlayerViewController() + let controller = NormalPlayer() controller.player = player controller.showsPlaybackControls = false player.play() @@ -24,16 +24,6 @@ struct CustomVideoPlayer: UIViewControllerRepresentable { } } -class CustomAVPlayerViewController: AVPlayerViewController { - override var supportedInterfaceOrientations: UIInterfaceOrientationMask { - if UserDefaults.standard.bool(forKey: "alwaysLandscape") { - return .landscape - } else { - return .all - } - } -} - struct CustomMediaPlayer: View { @State private var player: AVPlayer @State private var isPlaying = true @@ -41,13 +31,23 @@ struct CustomMediaPlayer: View { @State private var duration: Double = 0.0 @State private var showControls = false @State private var inactivityTimer: Timer? + @State private var timeObserverToken: Any? @Environment(\.presentationMode) var presentationMode - init(urlString: String) { + let fullUrl: String + let title: String + let episodeNumber: Int + let onWatchNext: () -> Void + + init(urlString: String, fullUrl: String, title: String, episodeNumber: Int, onWatchNext: @escaping () -> Void) { guard let url = URL(string: urlString) else { fatalError("Invalid URL string") } _player = State(initialValue: AVPlayer(url: url)) + self.fullUrl = fullUrl + self.title = title + self.episodeNumber = episodeNumber + self.onWatchNext = onWatchNext } var body: some View { @@ -63,6 +63,7 @@ struct CustomMediaPlayer: View { } } startUpdatingCurrentTime() + addPeriodicTimeObserver(fullURL: fullUrl) } .edgesIgnoringSafeArea(.all) .overlay( @@ -118,11 +119,30 @@ struct CustomMediaPlayer: View { VStack { Spacer() - if showControls { - VStack { + VStack { + Spacer() + HStack { Spacer() - HStack { - Spacer() + if duration - currentTime <= duration * 0.06 { + Button(action: { + player.pause() + presentationMode.wrappedValue.dismiss() + onWatchNext() + }) { + HStack { + Image(systemName: "forward.fill") + .foregroundColor(Color.black) + Text("Watch Next") + .font(.headline) + .foregroundColor(Color.black) + } + .padding() + .background(Color.white.opacity(0.8)) + .cornerRadius(32) + } + .padding(.trailing, 10) + } + if showControls { Menu { Menu("Playback Speed") { Button(action: { @@ -196,8 +216,10 @@ struct CustomMediaPlayer: View { .font(.system(size: 15)) } } - .padding(.trailing, 10) - + } + .padding(.trailing, 10) + + if showControls { MusicProgressSlider( value: $currentTime, inRange: 0...duration, @@ -211,8 +233,8 @@ struct CustomMediaPlayer: View { } } ) - .frame(height: 45) - .padding(.bottom, 10) + .frame(height: 45) + .padding(.bottom, 10) } } } @@ -222,6 +244,10 @@ struct CustomMediaPlayer: View { .onDisappear { player.pause() inactivityTimer?.invalidate() + if let timeObserverToken = timeObserverToken { + player.removeTimeObserver(timeObserverToken) + self.timeObserverToken = nil + } } } } @@ -235,6 +261,7 @@ struct CustomMediaPlayer: View { .foregroundColor(.white) .font(.system(size: 20)) } + .frame(width: 60, height: 60) .padding() Spacer() } @@ -249,4 +276,20 @@ struct CustomMediaPlayer: View { currentTime = player.currentTime().seconds } } -} + + private func addPeriodicTimeObserver(fullURL: String) { + let interval = CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) + timeObserverToken = player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { time in + guard let currentItem = player.currentItem, + currentItem.duration.seconds.isFinite else { + return + } + + let currentTime = time.seconds + let duration = currentItem.duration.seconds + + UserDefaults.standard.set(currentTime, forKey: "lastPlayedTime_\(fullURL)") + UserDefaults.standard.set(duration, forKey: "totalTime_\(fullURL)") + } + } +} \ No newline at end of file diff --git a/Sora/Utils/Player/VideoPlayerView.swift b/Sora/Utils/Player/VideoPlayerView.swift index 1d4f422..b6988cd 100644 --- a/Sora/Utils/Player/VideoPlayerView.swift +++ b/Sora/Utils/Player/VideoPlayerView.swift @@ -36,13 +36,13 @@ class VideoPlayerViewController: UIViewController { let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(fullUrl)") if lastPlayedTime > 0 { - let seekTime = CMTime(seconds: lastPlayedTime, preferredTimescale: 1) - self.player?.seek(to: seekTime) { _ in - self.player?.play() - } - } else { - self.player?.play() - } + let seekTime = CMTime(seconds: lastPlayedTime, preferredTimescale: 1) + self.player?.seek(to: seekTime) { _ in + self.player?.play() + } + } else { + self.player?.play() + } } override func viewDidAppear(_ animated: Bool) { @@ -51,28 +51,28 @@ class VideoPlayerViewController: UIViewController { } override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - if let timeObserverToken = timeObserverToken { - player?.removeTimeObserver(timeObserverToken) - self.timeObserverToken = nil - } - } - - func addPeriodicTimeObserver(fullURL: String) { - guard let player = self.player else { return } - - let interval = CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) - timeObserverToken = player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { time in - guard let currentItem = player.currentItem, - currentItem.duration.seconds.isFinite else { - return - } - - let currentTime = time.seconds - let duration = currentItem.duration.seconds - - UserDefaults.standard.set(currentTime, forKey: "lastPlayedTime_\(fullURL)") - UserDefaults.standard.set(duration, forKey: "totalTime_\(fullURL)") - } - } + super.viewDidDisappear(animated) + if let timeObserverToken = timeObserverToken { + player?.removeTimeObserver(timeObserverToken) + self.timeObserverToken = nil + } + } + + func addPeriodicTimeObserver(fullURL: String) { + guard let player = self.player else { return } + + let interval = CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) + timeObserverToken = player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { time in + guard let currentItem = player.currentItem, + currentItem.duration.seconds.isFinite else { + return + } + + let currentTime = time.seconds + let duration = currentItem.duration.seconds + + UserDefaults.standard.set(currentTime, forKey: "lastPlayedTime_\(fullURL)") + UserDefaults.standard.set(duration, forKey: "totalTime_\(fullURL)") + } + } } diff --git a/Sora/Views/AnimeViews/AnimeInfoView.swift b/Sora/Views/AnimeViews/AnimeInfoView.swift index fd64d97..96b9a0b 100644 --- a/Sora/Views/AnimeViews/AnimeInfoView.swift +++ b/Sora/Views/AnimeViews/AnimeInfoView.swift @@ -22,6 +22,8 @@ struct AnimeInfoView: View { @State var isLoading: Bool = true @State var showFullSynopsis: Bool = false @State var animeID: Int? + @State private var selectedEpisode: String = "" + @State private var selectedEpisodeNumber: Int = 0 @AppStorage("externalPlayer") private var externalPlayer: String = "Default" @@ -138,6 +140,8 @@ struct AnimeInfoView: View { EpisodeCell(episode: episodes[index], episodeID: index, imageUrl: anime.imageUrl, progress: progress, animeID: animeID ?? 0) .onTapGesture { + selectedEpisode = episodes[index] + selectedEpisodeNumber = index + 1 fetchEpisodeStream(urlString: episodeURL) } } @@ -185,7 +189,15 @@ struct AnimeInfoView: View { return } else if externalPlayer == "Custom" { DispatchQueue.main.async { - let customMediaPlayer = CustomMediaPlayer(urlString: streamUrl) + let customMediaPlayer = CustomMediaPlayer( + urlString: streamUrl, + fullUrl: fullURL, + title: anime.name, + episodeNumber: selectedEpisodeNumber, + onWatchNext: { + selectNextEpisode() + } + ) let hostingController = UIHostingController(rootView: customMediaPlayer) hostingController.modalPresentationStyle = .fullScreen Logger.shared.log("Opening custom media player with url: \(streamUrl)") @@ -212,6 +224,17 @@ struct AnimeInfoView: View { } } + private func selectNextEpisode() { + guard let currentEpisodeIndex = episodes.firstIndex(of: selectedEpisode) else { return } + let nextEpisodeIndex = currentEpisodeIndex + 1 + if nextEpisodeIndex < episodes.count { + selectedEpisode = episodes[nextEpisodeIndex] + selectedEpisodeNumber = nextEpisodeIndex + 1 + let nextEpisodeURL = "\(module.module[0].details.baseURL)\(episodes[nextEpisodeIndex])" + fetchEpisodeStream(urlString: nextEpisodeURL) + } + } + private func openSafariViewController(with urlString: String) { guard let url = URL(string: anime.href.hasPrefix("http") ? anime.href : "\(module.module[0].details.baseURL)\(anime.href)") else { Logger.shared.log("Unable to open the webpage") diff --git a/Sora/Views/AnimeViews/EpisodeCell/CircularProgressBar.swift b/Sora/Views/AnimeViews/EpisodeCell/CircularProgressBar.swift index 7bebbc0..078410e 100644 --- a/Sora/Views/AnimeViews/EpisodeCell/CircularProgressBar.swift +++ b/Sora/Views/AnimeViews/EpisodeCell/CircularProgressBar.swift @@ -24,8 +24,13 @@ struct CircularProgressBar: View { .rotationEffect(Angle(degrees: 270.0)) .animation(.linear, value: progress) - Text(String(format: "%.0f%%", min(progress, 1.0) * 100.0)) - .font(.system(size: 12)) + if progress >= 0.95 { + Image(systemName: "checkmark") + .font(.system(size: 12)) + } else { + Text(String(format: "%.0f%%", min(progress, 1.0) * 100.0)) + .font(.system(size: 12)) + } } } -} +} \ No newline at end of file diff --git a/Sora/Views/AnimeViews/EpisodeCell/EpisodeCell.swift b/Sora/Views/AnimeViews/EpisodeCell/EpisodeCell.swift index c245d73..b0145b6 100644 --- a/Sora/Views/AnimeViews/EpisodeCell/EpisodeCell.swift +++ b/Sora/Views/AnimeViews/EpisodeCell/EpisodeCell.swift @@ -78,21 +78,23 @@ struct EpisodeCell: View { } do { - if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], - let episodes = json["episodes"] as? [String: Any], - let episodeDetails = episodes["\(episodeID + 1)"] as? [String: Any], - let title = episodeDetails["title"] as? [String: String], - let image = episodeDetails["image"] as? String { - DispatchQueue.main.async { - self.episodeTitle = title["en"] ?? "" - self.episodeImageUrl = image - self.isLoading = false - } - } else { - print("Invalid response") - DispatchQueue.main.async { - self.isLoading = false - } + let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) + guard let json = jsonObject as? [String: Any], + let episodes = json["episodes"] as? [String: Any], + let episodeDetails = episodes["\(episodeID + 1)"] as? [String: Any], + let title = episodeDetails["title"] as? [String: String], + let image = episodeDetails["image"] as? String else { + print("Invalid response format") + DispatchQueue.main.async { + self.isLoading = false + } + return + } + + DispatchQueue.main.async { + self.episodeTitle = title["en"] ?? "" + self.episodeImageUrl = image + self.isLoading = false } } catch { print("Failed to parse JSON: \(error)") @@ -102,4 +104,4 @@ struct EpisodeCell: View { } }.resume() } -} \ No newline at end of file +}