too much things idk

Fixed many issues on the custom player
This commit is contained in:
cranci1 2025-03-04 10:38:27 +01:00
parent c243dea3a2
commit 9ef235169c
7 changed files with 152 additions and 43 deletions

View file

@ -0,0 +1,27 @@
//
// finTopView.swift
// Sulfur
//
// Created by Francesco on 04/03/25.
//
import UIKit
class findTopViewController {
static func findViewController(_ viewController: UIViewController) -> UIViewController {
if let presented = viewController.presentedViewController {
return findViewController(presented)
}
if let navigationController = viewController as? UINavigationController {
return findViewController(navigationController.visibleViewController ?? navigationController)
}
if let tabBarController = viewController as? UITabBarController,
let selected = tabBarController.selectedViewController {
return findViewController(selected)
}
return viewController
}
}

View file

@ -57,6 +57,10 @@ class CustomMediaPlayerViewController: UIViewController {
var sliderViewModel = SliderViewModel()
var isSliderEditing = false
var watchNextButtonNormalConstraints: [NSLayoutConstraint] = []
var watchNextButtonControlsConstraints: [NSLayoutConstraint] = []
var isControlsVisible = false
init(module: ScrapingModule,
urlString: String,
fullUrl: String,
@ -106,8 +110,9 @@ class CustomMediaPlayerViewController: UIViewController {
setupControls()
setupSubtitleLabel()
setupDismissButton()
setupSpeedButton()
setupMenuButton()
setupSpeedButton()
setupWatchNextButton()
addTimeObserver()
startUpdateTimer()
setupAudioSession()
@ -244,17 +249,6 @@ class CustomMediaPlayerViewController: UIViewController {
sliderHostView.heightAnchor.constraint(equalToConstant: 30)
])
watchNextButton = UIButton(type: .system)
watchNextButton.setTitle("Watch Next", for: .normal)
watchNextButton.setImage(UIImage(systemName: "forward.fill"), for: .normal)
watchNextButton.backgroundColor = .white
watchNextButton.layer.cornerRadius = 16
watchNextButton.setTitleColor(.black, for: .normal)
watchNextButton.addTarget(self, action: #selector(watchNextTapped), for: .touchUpInside)
watchNextButton.isHidden = true
controlsContainerView.addSubview(watchNextButton)
watchNextButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
playPauseButton.centerXAnchor.constraint(equalTo: controlsContainerView.centerXAnchor),
playPauseButton.centerYAnchor.constraint(equalTo: controlsContainerView.centerYAnchor),
@ -269,12 +263,7 @@ class CustomMediaPlayerViewController: UIViewController {
forwardButton.centerYAnchor.constraint(equalTo: playPauseButton.centerYAnchor),
forwardButton.leadingAnchor.constraint(equalTo: playPauseButton.trailingAnchor, constant: 30),
forwardButton.widthAnchor.constraint(equalToConstant: 40),
forwardButton.heightAnchor.constraint(equalToConstant: 40),
watchNextButton.trailingAnchor.constraint(equalTo: controlsContainerView.trailingAnchor, constant: -10),
watchNextButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -80),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
forwardButton.heightAnchor.constraint(equalToConstant: 40)
])
}
@ -288,9 +277,9 @@ class CustomMediaPlayerViewController: UIViewController {
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subtitleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
subtitleLabel.bottomAnchor.constraint(equalTo: sliderHostingController?.view.topAnchor ?? view.safeAreaLayoutGuide.bottomAnchor),
subtitleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 20),
subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -20)
subtitleLabel.bottomAnchor.constraint(equalTo: sliderHostingController?.view.bottomAnchor ?? view.safeAreaLayoutGuide.bottomAnchor),
subtitleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 36),
subtitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -36)
])
}
@ -323,9 +312,10 @@ class CustomMediaPlayerViewController: UIViewController {
controlsContainerView.addSubview(menuButton)
menuButton.translatesAutoresizingMaskIntoConstraints = false
guard let sliderView = sliderHostingController?.view else { return }
NSLayoutConstraint.activate([
menuButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -50),
menuButton.trailingAnchor.constraint(equalTo: speedButton.leadingAnchor),
menuButton.bottomAnchor.constraint(equalTo: sliderView.topAnchor),
menuButton.trailingAnchor.constraint(equalTo: sliderView.trailingAnchor),
menuButton.widthAnchor.constraint(equalToConstant: 40),
menuButton.heightAnchor.constraint(equalToConstant: 40)
])
@ -341,15 +331,46 @@ class CustomMediaPlayerViewController: UIViewController {
controlsContainerView.addSubview(speedButton)
speedButton.translatesAutoresizingMaskIntoConstraints = false
guard let sliderView = sliderHostingController?.view else { return }
NSLayoutConstraint.activate([
speedButton.bottomAnchor.constraint(equalTo: sliderView.topAnchor),
speedButton.trailingAnchor.constraint(equalTo: sliderView.trailingAnchor),
speedButton.bottomAnchor.constraint(equalTo: controlsContainerView.bottomAnchor, constant: -50),
speedButton.trailingAnchor.constraint(equalTo: menuButton.leadingAnchor),
speedButton.widthAnchor.constraint(equalToConstant: 40),
speedButton.heightAnchor.constraint(equalToConstant: 40)
])
}
func setupWatchNextButton() {
watchNextButton = UIButton(type: .system)
watchNextButton.setTitle("Watch Next", for: .normal)
watchNextButton.setImage(UIImage(systemName: "forward.fill"), for: .normal)
watchNextButton.tintColor = .black
watchNextButton.backgroundColor = .white
watchNextButton.layer.cornerRadius = 25
watchNextButton.setTitleColor(.black, for: .normal)
watchNextButton.addTarget(self, action: #selector(watchNextTapped), for: .touchUpInside)
watchNextButton.isHidden = true
watchNextButton.alpha = 0.8
view.addSubview(watchNextButton)
watchNextButton.translatesAutoresizingMaskIntoConstraints = false
watchNextButtonNormalConstraints = [
watchNextButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
watchNextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
]
watchNextButtonControlsConstraints = [
watchNextButton.trailingAnchor.constraint(equalTo: speedButton.leadingAnchor),
watchNextButton.bottomAnchor.constraint(equalTo: speedButton.bottomAnchor, constant: -5),
watchNextButton.heightAnchor.constraint(equalToConstant: 50),
watchNextButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
]
NSLayoutConstraint.activate(watchNextButtonControlsConstraints)
}
func updateSubtitleLabelAppearance() {
subtitleLabel.font = UIFont.systemFont(ofSize: CGFloat(subtitleFontSize))
subtitleLabel.textColor = subtitleUIColor()
@ -405,7 +426,6 @@ class CustomMediaPlayerViewController: UIViewController {
&& self.duration != 0 {
if UserDefaults.standard.bool(forKey: "hideNextButton") {
self.watchNextButton.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.watchNextButton.isHidden = true
}
@ -444,8 +464,22 @@ class CustomMediaPlayerViewController: UIViewController {
}
@objc func toggleControls() {
isControlsVisible.toggle()
UIView.animate(withDuration: 0.2) {
self.controlsContainerView.alpha = self.controlsContainerView.alpha == 0 ? 1 : 0
self.controlsContainerView.alpha = self.isControlsVisible ? 1 : 0
if self.isControlsVisible {
NSLayoutConstraint.deactivate(self.watchNextButtonNormalConstraints)
NSLayoutConstraint.activate(self.watchNextButtonControlsConstraints)
self.watchNextButton.alpha = 1.0
} else {
NSLayoutConstraint.deactivate(self.watchNextButtonControlsConstraints)
NSLayoutConstraint.activate(self.watchNextButtonNormalConstraints)
self.watchNextButton.alpha = 0.8
}
self.view.layoutIfNeeded()
}
}

View file

@ -148,4 +148,11 @@ class VideoPlayerViewController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
deinit {
player?.pause()
if let timeObserverToken = timeObserverToken {
player?.removeTimeObserver(timeObserverToken)
}
}
}

View file

@ -66,7 +66,7 @@ struct HomeView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(customMediaPlayer, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(customMediaPlayer, animated: true, completion: nil)
}
} else {
let videoPlayerViewController = VideoPlayerViewController(module: item.module)
@ -80,7 +80,7 @@ struct HomeView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(videoPlayerViewController, animated: true, completion: nil)
}
}
}) {

View file

@ -519,7 +519,7 @@ struct MediaInfoView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(customMediaPlayer, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(customMediaPlayer, animated: true, completion: nil)
}
return
default:
@ -541,7 +541,7 @@ struct MediaInfoView: View {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController {
rootVC.present(videoPlayerViewController, animated: true, completion: nil)
findTopViewController.findViewController(rootVC).present(videoPlayerViewController, animated: true, completion: nil)
}
}
}

View file

@ -31,6 +31,9 @@
133D7C942D2BE2640075467E /* JSController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133D7C8B2D2BE2640075467E /* JSController.swift */; };
133D7C972D2BE2AF0075467E /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 133D7C962D2BE2AF0075467E /* Kingfisher */; };
133F55BB2D33B55100E08EEA /* LibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133F55BA2D33B55100E08EEA /* LibraryManager.swift */; };
1359ED142D76F49900C13034 /* finTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1359ED132D76F49900C13034 /* finTopView.swift */; };
1359ED172D76FA6500C13034 /* FFmpeg-iOS-Lame in Frameworks */ = {isa = PBXBuildFile; productRef = 1359ED162D76FA6500C13034 /* FFmpeg-iOS-Lame */; };
1359ED1A2D76FA7D00C13034 /* Drops in Frameworks */ = {isa = PBXBuildFile; productRef = 1359ED192D76FA7D00C13034 /* Drops */; };
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */; };
136F21B92D5B8DD8006409AC /* AniList-MediaInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136F21B82D5B8DD8006409AC /* AniList-MediaInfo.swift */; };
136F21BC2D5B8F29006409AC /* AniList-DetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136F21BB2D5B8F29006409AC /* AniList-DetailsView.swift */; };
@ -44,7 +47,6 @@
13C0E5EC2D5F85F800E7F619 /* ContinueWatchingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C0E5EB2D5F85F800E7F619 /* ContinueWatchingItem.swift */; };
13CBA0882D60F19C00EFE70A /* VTTSubtitlesLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CBA0872D60F19C00EFE70A /* VTTSubtitlesLoader.swift */; };
13CBEFDA2D5F7D1200D011EE /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CBEFD92D5F7D1200D011EE /* String.swift */; };
13D842522D4523B800EBBFA6 /* Drops in Frameworks */ = {isa = PBXBuildFile; productRef = 13D842512D4523B800EBBFA6 /* Drops */; };
13D842552D45267500EBBFA6 /* DropManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D842542D45267500EBBFA6 /* DropManager.swift */; };
13D99CF72D4E73C300250A86 /* ModuleAdditionSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D99CF62D4E73C300250A86 /* ModuleAdditionSettingsView.swift */; };
13DC0C462D302C7500D0F966 /* VideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13DC0C452D302C7500D0F966 /* VideoPlayer.swift */; };
@ -81,6 +83,7 @@
133D7C892D2BE2640075467E /* Modules.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Modules.swift; sourceTree = "<group>"; };
133D7C8B2D2BE2640075467E /* JSController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSController.swift; sourceTree = "<group>"; };
133F55BA2D33B55100E08EEA /* LibraryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryManager.swift; sourceTree = "<group>"; };
1359ED132D76F49900C13034 /* finTopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = finTopView.swift; sourceTree = "<group>"; };
135CCBE12D4D1138008B9C0E /* SettingsViewPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewPlayer.swift; sourceTree = "<group>"; };
136F21B82D5B8DD8006409AC /* AniList-MediaInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-MediaInfo.swift"; sourceTree = "<group>"; };
136F21BB2D5B8F29006409AC /* AniList-DetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AniList-DetailsView.swift"; sourceTree = "<group>"; };
@ -110,7 +113,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
13D842522D4523B800EBBFA6 /* Drops in Frameworks */,
1359ED1A2D76FA7D00C13034 /* Drops in Frameworks */,
1359ED172D76FA6500C13034 /* FFmpeg-iOS-Lame in Frameworks */,
133D7C972D2BE2AF0075467E /* Kingfisher in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -266,6 +270,7 @@
children = (
1327FBA82D758DEA00FC6689 /* UIDevice+Model.swift */,
133D7C872D2BE2640075467E /* URLSession.swift */,
1359ED132D76F49900C13034 /* finTopView.swift */,
13CBEFD92D5F7D1200D011EE /* String.swift */,
13103E8A2D58E028000F0673 /* View.swift */,
);
@ -405,7 +410,8 @@
name = Sulfur;
packageProductDependencies = (
133D7C962D2BE2AF0075467E /* Kingfisher */,
13D842512D4523B800EBBFA6 /* Drops */,
1359ED162D76FA6500C13034 /* FFmpeg-iOS-Lame */,
1359ED192D76FA7D00C13034 /* Drops */,
);
productName = Sora;
productReference = 133D7C6A2D2BE2500075467E /* Sulfur.app */;
@ -436,7 +442,8 @@
mainGroup = 133D7C612D2BE2500075467E;
packageReferences = (
133D7C952D2BE2AF0075467E /* XCRemoteSwiftPackageReference "Kingfisher" */,
13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */,
1359ED152D76FA6500C13034 /* XCRemoteSwiftPackageReference "FFmpeg-iOS-Lame" */,
1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */,
);
productRefGroup = 133D7C6B2D2BE2500075467E /* Products */;
projectDirPath = "";
@ -467,6 +474,7 @@
135CCBE22D4D1138008B9C0E /* SettingsViewPlayer.swift in Sources */,
1327FBA72D758CEA00FC6689 /* Analytics.swift in Sources */,
13DC0C462D302C7500D0F966 /* VideoPlayer.swift in Sources */,
1359ED142D76F49900C13034 /* finTopView.swift in Sources */,
1399FAD62D3AB3DB00E97C31 /* Logger.swift in Sources */,
13B7F4C12D58FFDD0045714A /* Shimmer.swift in Sources */,
139935662D468C450065CEFF /* ModuleManager.swift in Sources */,
@ -646,6 +654,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Sora/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Sora;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -686,6 +695,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Sora/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Sora;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@ -742,12 +752,20 @@
version = 7.9.1;
};
};
13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */ = {
1359ED152D76FA6500C13034 /* XCRemoteSwiftPackageReference "FFmpeg-iOS-Lame" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kewlbear/FFmpeg-iOS-Lame";
requirement = {
branch = main;
kind = branch;
};
};
1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/omaralbeik/Drops.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.0;
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
@ -758,9 +776,14 @@
package = 133D7C952D2BE2AF0075467E /* XCRemoteSwiftPackageReference "Kingfisher" */;
productName = Kingfisher;
};
13D842512D4523B800EBBFA6 /* Drops */ = {
1359ED162D76FA6500C13034 /* FFmpeg-iOS-Lame */ = {
isa = XCSwiftPackageProductDependency;
package = 13D842502D4523B800EBBFA6 /* XCRemoteSwiftPackageReference "Drops" */;
package = 1359ED152D76FA6500C13034 /* XCRemoteSwiftPackageReference "FFmpeg-iOS-Lame" */;
productName = "FFmpeg-iOS-Lame";
};
1359ED192D76FA7D00C13034 /* Drops */ = {
isa = XCSwiftPackageProductDependency;
package = 1359ED182D76FA7D00C13034 /* XCRemoteSwiftPackageReference "Drops" */;
productName = Drops;
};
/* End XCSwiftPackageProductDependency section */

View file

@ -4,10 +4,28 @@
{
"package": "Drops",
"repositoryURL": "https://github.com/omaralbeik/Drops.git",
"state": {
"branch": "main",
"revision": "5824681795286c36bdc4a493081a63e64e2a064e",
"version": null
}
},
{
"package": "FFmpeg-iOS-Lame",
"repositoryURL": "https://github.com/kewlbear/FFmpeg-iOS-Lame",
"state": {
"branch": "main",
"revision": "1808fa5a1263c5e216646cd8421fc7dcb70520cc",
"version": null
}
},
{
"package": "FFmpeg-iOS-Support",
"repositoryURL": "https://github.com/kewlbear/FFmpeg-iOS-Support",
"state": {
"branch": null,
"revision": "a183ee6f79f21c940092a19c2cba756555422371",
"version": "1.7.0"
"revision": "be3bd9149ac53760e8725652eee99c405b2be47a",
"version": "0.0.2"
}
},
{