mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
idk is this SharePlay?
This commit is contained in:
parent
50cd96bee7
commit
76e2b3ed3b
4 changed files with 108 additions and 3 deletions
|
|
@ -8,6 +8,7 @@
|
|||
import UIKit
|
||||
import AVKit
|
||||
import MediaPlayer
|
||||
import GroupActivities
|
||||
|
||||
class VideoPlayerViewController: UIViewController {
|
||||
let module: ScrapingModule
|
||||
|
|
@ -27,6 +28,8 @@ class VideoPlayerViewController: UIViewController {
|
|||
var mediaTitle: String = ""
|
||||
|
||||
private var currentArtwork: MPMediaItemArtwork?
|
||||
private var groupSession: GroupSession<WatchTogetherActivity>?
|
||||
private var messenger: GroupSessionMessenger?
|
||||
|
||||
init(module: ScrapingModule) {
|
||||
self.module = module
|
||||
|
|
@ -40,6 +43,7 @@ class VideoPlayerViewController: UIViewController {
|
|||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
setupSharePlay()
|
||||
setupNowPlaying()
|
||||
setupRemoteTransportControls()
|
||||
|
||||
|
|
@ -95,6 +99,80 @@ class VideoPlayerViewController: UIViewController {
|
|||
}
|
||||
}
|
||||
|
||||
private func setupSharePlay() {
|
||||
guard let streamUrl = streamUrl else { return }
|
||||
|
||||
let activity = WatchTogetherActivity(
|
||||
streamUrl: streamUrl,
|
||||
mediaTitle: mediaTitle,
|
||||
episodeNumber: episodeNumber
|
||||
)
|
||||
|
||||
Task {
|
||||
switch await activity.prepareForActivation() {
|
||||
case .activationPreferred:
|
||||
do {
|
||||
_ = try await activity.activate()
|
||||
Logger.shared.log("SharePlay session activated successfully", type: "General")
|
||||
} catch {
|
||||
Logger.shared.log("Failed to activate SharePlay: \(error)", type: "Error")
|
||||
}
|
||||
case .activationDisabled:
|
||||
Logger.shared.log("SharePlay activation disabled", type: "General")
|
||||
case .cancelled:
|
||||
Logger.shared.log("SharePlay activation cancelled", type: "General")
|
||||
@unknown default:
|
||||
Logger.shared.log("SharePlay activation unknown state", type: "Info")
|
||||
}
|
||||
}
|
||||
|
||||
Task {
|
||||
for await session in WatchTogetherActivity.sessions() {
|
||||
configureGroupSession(session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func configureGroupSession(_ session: GroupSession<WatchTogetherActivity>) {
|
||||
groupSession = session
|
||||
messenger = GroupSessionMessenger(session: session)
|
||||
|
||||
session.join()
|
||||
|
||||
Task {
|
||||
guard let messenger = messenger else { return }
|
||||
for await (timeString, _) in messenger.messages(of: String.self) {
|
||||
if let seconds = Double(timeString) {
|
||||
let time = CMTime(seconds: seconds, preferredTimescale: 600)
|
||||
await handlePlaybackMessage(time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player?.addPeriodicTimeObserver(
|
||||
forInterval: CMTime(seconds: 1, preferredTimescale: 600),
|
||||
queue: .main
|
||||
) { [weak self] time in
|
||||
guard let self = self else { return }
|
||||
Task {
|
||||
let timeString = String(time.seconds)
|
||||
try? await self.messenger?.send(timeString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handlePlaybackMessage(_ time: CMTime) async {
|
||||
await MainActor.run {
|
||||
guard let player = player else { return }
|
||||
let currentTime = player.currentTime()
|
||||
let difference = abs(CMTimeSubtract(time, currentTime).seconds)
|
||||
|
||||
if difference > 1.0 {
|
||||
player.seek(to: time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setupNowPlaying() {
|
||||
if let imageUrl = URL(string: episodeImageUrl) {
|
||||
URLSession.custom.dataTask(with: imageUrl) { [weak self] data, _, _ in
|
||||
|
|
@ -136,7 +214,7 @@ class VideoPlayerViewController: UIViewController {
|
|||
|
||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
||||
}
|
||||
|
||||
|
||||
let interval = CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
|
||||
player?.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] _ in
|
||||
self?.updateNowPlayingInfo()
|
||||
|
|
@ -170,6 +248,7 @@ class VideoPlayerViewController: UIViewController {
|
|||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
groupSession?.leave()
|
||||
if let playbackSpeed = player?.rate {
|
||||
UserDefaults.standard.set(playbackSpeed, forKey: "lastPlaybackSpeed")
|
||||
}
|
||||
|
|
@ -269,6 +348,7 @@ class VideoPlayerViewController: UIViewController {
|
|||
}
|
||||
|
||||
deinit {
|
||||
groupSession?.leave()
|
||||
player?.pause()
|
||||
if let timeObserverToken = timeObserverToken {
|
||||
player?.removeTimeObserver(timeObserverToken)
|
||||
|
|
|
|||
21
Sora/Utils/MediaPlayer/WatchTogether.swift
Normal file
21
Sora/Utils/MediaPlayer/WatchTogether.swift
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// VideoPlayer.swift
|
||||
// Sora
|
||||
//
|
||||
// Created by Francesco on 27/005/25.
|
||||
|
||||
import GroupActivities
|
||||
|
||||
struct WatchTogetherActivity: GroupActivity {
|
||||
let streamUrl: String
|
||||
let mediaTitle: String
|
||||
let episodeNumber: Int
|
||||
|
||||
var metadata: GroupActivityMetadata {
|
||||
var metadata = GroupActivityMetadata()
|
||||
metadata.type = .watchTogether
|
||||
metadata.title = mediaTitle
|
||||
metadata.subtitle = "Episode \(episodeNumber)"
|
||||
return metadata
|
||||
}
|
||||
}
|
||||
|
|
@ -28,8 +28,8 @@ struct SettingsViewAbout: View {
|
|||
Text("Sora")
|
||||
.font(.title)
|
||||
.bold()
|
||||
Text("Version \(version)")
|
||||
.font(.subheadline)
|
||||
Text("AKA Sulfur")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
130A810B2DE5F32400614732 /* WatchTogether.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130A810A2DE5F32400614732 /* WatchTogether.swift */; };
|
||||
130C6BFA2D53AB1F00DC1432 /* SettingsViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130C6BF92D53AB1F00DC1432 /* SettingsViewData.swift */; };
|
||||
13103E8B2D58E028000F0673 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E8A2D58E028000F0673 /* View.swift */; };
|
||||
13103E8E2D58E04A000F0673 /* SkeletonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13103E8D2D58E04A000F0673 /* SkeletonCell.swift */; };
|
||||
|
|
@ -88,6 +89,7 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
130A810A2DE5F32400614732 /* WatchTogether.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WatchTogether.swift; path = Sora/Utils/MediaPlayer/WatchTogether.swift; sourceTree = SOURCE_ROOT; };
|
||||
130C6BF82D53A4C200DC1432 /* Sora.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Sora.entitlements; sourceTree = "<group>"; };
|
||||
130C6BF92D53AB1F00DC1432 /* SettingsViewData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewData.swift; sourceTree = "<group>"; };
|
||||
13103E8A2D58E028000F0673 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -447,6 +449,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
13EA2BD02D32D97400C1EBD7 /* CustomPlayer */,
|
||||
130A810A2DE5F32400614732 /* WatchTogether.swift */,
|
||||
13DC0C452D302C7500D0F966 /* VideoPlayer.swift */,
|
||||
13EA2BD82D32D98400C1EBD7 /* NormalPlayer.swift */,
|
||||
);
|
||||
|
|
@ -610,6 +613,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */,
|
||||
130A810B2DE5F32400614732 /* WatchTogether.swift in Sources */,
|
||||
131270172DC13A010093AA9C /* DownloadManager.swift in Sources */,
|
||||
1327FBA72D758CEA00FC6689 /* Analytics.swift in Sources */,
|
||||
13DC0C462D302C7500D0F966 /* VideoPlayer.swift in Sources */,
|
||||
|
|
|
|||
Loading…
Reference in a new issue