mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-19 23:52:09 +00:00
sora player made working
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
This commit is contained in:
parent
4bb2d77c74
commit
972af358ca
6 changed files with 71 additions and 24 deletions
|
|
@ -28,7 +28,7 @@ struct AniListDetailsView: View {
|
|||
let animeID: Int
|
||||
@State private var mediaInfo: [String: Any]?
|
||||
@State private var isLoading: Bool = true
|
||||
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 16) {
|
||||
|
|
|
|||
|
|
@ -15,5 +15,6 @@ struct ContinueWatchingItem: Codable, Identifiable {
|
|||
let progress: Double
|
||||
let streamUrl: String
|
||||
let fullUrl: String
|
||||
let subtitles: String?
|
||||
let module: ScrapingModule
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,13 +57,15 @@ struct CustomMediaPlayer: View {
|
|||
@Environment(\.presentationMode) var presentationMode
|
||||
|
||||
let module: ScrapingModule
|
||||
let streamURL: String
|
||||
let fullUrl: String
|
||||
let title: String
|
||||
let episodeNumber: Int
|
||||
let episodeImageUrl: String
|
||||
let subtitlesURL: String?
|
||||
let onWatchNext: () -> Void
|
||||
|
||||
init(module: ScrapingModule, urlString: String, fullUrl: String, title: String, episodeNumber: Int, onWatchNext: @escaping () -> Void, subtitlesURL: String?) {
|
||||
init(module: ScrapingModule, urlString: String, fullUrl: String, title: String, episodeNumber: Int, onWatchNext: @escaping () -> Void, subtitlesURL: String?, episodeImageUrl: String) {
|
||||
guard let url = URL(string: urlString) else {
|
||||
fatalError("Invalid URL string")
|
||||
}
|
||||
|
|
@ -77,9 +79,11 @@ struct CustomMediaPlayer: View {
|
|||
_player = State(initialValue: AVPlayer(playerItem: AVPlayerItem(asset: asset)))
|
||||
|
||||
self.module = module
|
||||
self.streamURL = urlString
|
||||
self.fullUrl = fullUrl
|
||||
self.title = title
|
||||
self.episodeNumber = episodeNumber
|
||||
self.episodeImageUrl = episodeImageUrl
|
||||
self.onWatchNext = onWatchNext
|
||||
self.subtitlesURL = subtitlesURL ?? ""
|
||||
|
||||
|
|
@ -310,6 +314,24 @@ struct CustomMediaPlayer: View {
|
|||
player.removeTimeObserver(timeObserverToken)
|
||||
self.timeObserverToken = nil
|
||||
}
|
||||
|
||||
if let currentItem = player.currentItem, currentItem.duration.seconds > 0 {
|
||||
let currentTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(fullUrl)")
|
||||
let duration = currentItem.duration.seconds
|
||||
let progress = currentTime / duration
|
||||
let item = ContinueWatchingItem(
|
||||
id: UUID(),
|
||||
imageUrl: episodeImageUrl,
|
||||
episodeNumber: episodeNumber,
|
||||
mediaTitle: title,
|
||||
progress: progress,
|
||||
streamUrl: streamURL,
|
||||
fullUrl: fullUrl,
|
||||
subtitles: subtitlesURL,
|
||||
module: module
|
||||
)
|
||||
ContinueWatchingManager.shared.save(item: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -336,7 +358,10 @@ struct CustomMediaPlayer: View {
|
|||
|
||||
private func startUpdatingCurrentTime() {
|
||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
|
||||
currentTime = player.currentTime().seconds
|
||||
let newTime = player.currentTime().seconds
|
||||
DispatchQueue.main.async {
|
||||
self.currentTime = newTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,15 +376,14 @@ struct CustomMediaPlayer: View {
|
|||
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)")
|
||||
currentItem.duration.seconds.isFinite else { return }
|
||||
DispatchQueue.main.async {
|
||||
let currentTimeValue = time.seconds
|
||||
self.currentTime = currentTimeValue
|
||||
let duration = currentItem.duration.seconds
|
||||
UserDefaults.standard.set(currentTimeValue, forKey: "lastPlayedTime_\(fullURL)")
|
||||
UserDefaults.standard.set(duration, forKey: "totalTime_\(fullURL)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ class VideoPlayerViewController: UIViewController {
|
|||
progress: progress,
|
||||
streamUrl: streamUrl,
|
||||
fullUrl: fullUrl,
|
||||
subtitles: nil,
|
||||
module: module
|
||||
)
|
||||
ContinueWatchingManager.shared.save(item: item)
|
||||
|
|
|
|||
|
|
@ -146,17 +146,37 @@ struct HomeView: View {
|
|||
HStack(spacing: 8) {
|
||||
ForEach(continueWatchingItems) { item in
|
||||
Button(action: {
|
||||
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
|
||||
videoPlayerViewController.streamUrl = item.streamUrl
|
||||
videoPlayerViewController.fullUrl = item.fullUrl
|
||||
videoPlayerViewController.episodeImageUrl = item.imageUrl
|
||||
videoPlayerViewController.episodeNumber = item.episodeNumber
|
||||
videoPlayerViewController.mediaTitle = item.mediaTitle
|
||||
videoPlayerViewController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
|
||||
if UserDefaults.standard.string(forKey: "externalPlayer") == "Sora" {
|
||||
let customMediaPlayer = CustomMediaPlayer(
|
||||
module: item.module,
|
||||
urlString: item.streamUrl,
|
||||
fullUrl: item.fullUrl,
|
||||
title: item.mediaTitle,
|
||||
episodeNumber: item.episodeNumber,
|
||||
onWatchNext: { },
|
||||
subtitlesURL: item.subtitles,
|
||||
episodeImageUrl: item.imageUrl
|
||||
)
|
||||
let hostingController = UIHostingController(rootView: customMediaPlayer)
|
||||
hostingController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(hostingController, animated: true, completion: nil)
|
||||
}
|
||||
} else {
|
||||
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
|
||||
videoPlayerViewController.streamUrl = item.streamUrl
|
||||
videoPlayerViewController.fullUrl = item.fullUrl
|
||||
videoPlayerViewController.episodeImageUrl = item.imageUrl
|
||||
videoPlayerViewController.episodeNumber = item.episodeNumber
|
||||
videoPlayerViewController.mediaTitle = item.mediaTitle
|
||||
videoPlayerViewController.modalPresentationStyle = .fullScreen
|
||||
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let rootVC = windowScene.windows.first?.rootViewController {
|
||||
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
VStack(alignment: .leading) {
|
||||
|
|
|
|||
|
|
@ -486,7 +486,8 @@ struct MediaInfoView: View {
|
|||
onWatchNext: {
|
||||
selectNextEpisode()
|
||||
},
|
||||
subtitlesURL: subtitles
|
||||
subtitlesURL: subtitles,
|
||||
episodeImageUrl: selectedEpisodeImage
|
||||
)
|
||||
let hostingController = UIHostingController(rootView: customMediaPlayer)
|
||||
hostingController.modalPresentationStyle = .fullScreen
|
||||
|
|
|
|||
Loading…
Reference in a new issue