// // PlayerVC.swift // WOKA // // Created by MacBook Pro on 30/05/24. import UIKit import JWPlayerKit import AVKit class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { @IBOutlet weak var backButton: UIButton! var previousScale: CGFloat = 1.0 var contentType : VideoContentType? var config: JWPlayerConfiguration! var dismissTapped: (() -> Void)? var videoIndex : Int? override var prefersStatusBarHidden: Bool { return true } // func rotateToLandsScapeDevice(){ // let appDelegate = UIApplication.shared.delegate as! AppDelegate // appDelegate.myOrientation = .landscapeRight // if #available(iOS 16.0, *) { //// let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene // appDelegate.window?.windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: UIInterfaceOrientationMask.landscapeRight), errorHandler: { error in // print(error) // }) // } else { // UIDevice.current.setValue(UIInterfaceOrientationMask.landscapeRight.rawValue, forKey: "orientation") // } // UIView.setAnimationsEnabled(true) // } // // func rotateToPortraitScapeDevice(){ // let appDelegate = UIApplication.shared.delegate as! AppDelegate // appDelegate.myOrientation = .portrait // if #available(iOS 16.0, *) { // let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene // windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: UIInterfaceOrientationMask.portrait), errorHandler: { error in // print(error) // }) // } else { // UIDevice.current.setValue(UIInterfaceOrientationMask.portrait.rawValue, forKey: "orientation") // } // UIView.setAnimationsEnabled(true) // } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: nil) { _ in let isPortrait = size.width < size.height if isPortrait { print("Device is in portrait mode") } else { print("Device is in landscape mode") } } } override func viewDidLoad() { super.viewDidLoad() // self.rotateToLandsScapeDevice() rotateView(to: .pi / 2) // Example: 90 degrees rotation self.view.bringSubviewToFront(backButton) } func rotateView(to angle: CGFloat) { // Apply rotation to the view's transform view.transform = CGAffineTransform(rotationAngle: angle) } @objc func applicationDidBecomeActive() { // self.setDeviceOrientation(orientation: .landscapeRight) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) player.configurePlayer(with: config) self.delegate = self //Disable Picture in Picture playerView.allowsPictureInPicturePlayback = false playerView.captionStyle = .none } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) player.stop() } @IBAction func backBtnTapped(_ sender: UIButton) { // self.transitionToFullScreen(animated: true) self.interfaceBehavior = .hidden self.player.stop() if contentType == .liveStream{ self.dismissTapped?() } self.dismiss(animated: true) } // MARK: - JWPlayerViewControllerDelegate override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) { super.jwplayer(player, didFinishLoadingWithTime: loadTime) print("LoadTime", loadTime) if let videoIndex , contentType == .webSeries, videoIndex != 0{ player.nextUpPlaylistIndex = videoIndex player.next() self.videoIndex = nil } } override func jwplayerIsReady(_ player: JWPlayer) { super.jwplayerIsReady(player) switch contentType { case .liveStream: player.play() case .webSeries: if videoIndex == 0{ player.seek(to: 0) }else{ // player.nextUpPlaylistIndex = videoIndex ?? 0 // player.next() } case .trailer,.songs: break // player.play() case .continueWatching,.audioBooks, .games: player.seek(to: 0) player.play() case nil: break } print("IsReady") } override func jwplayer(_ player: JWPlayer, failedWithSetupError code: UInt, message: String) { super.jwplayer(player, failedWithSetupError: code, message: message) print("Setup Error: \(code) - \(message)") } override func jwplayer(_ player: JWPlayer, failedWithError code: UInt, message: String) { super.jwplayer(player, failedWithError: code, message: message) print("Error: \(code) - \(message)") self.player.configurePlayer(with: config) self.player.play() } override func jwplayer(_ player: JWPlayer, encounteredWarning code: UInt, message: String) { super.jwplayer(player, encounteredWarning: code, message: message) //Handle the reconnecting of video here print("Warning: \(code) - \(message)") } override func jwplayer(_ player: JWPlayer, encounteredAdError code: UInt, message: String) { super.jwplayer(player, encounteredAdError: code, message: message) print("Ad Error: \(code) - \(message)") } override func jwplayer(_ player: JWPlayer, encounteredAdWarning code: UInt, message: String) { super.jwplayer(player, encounteredAdWarning: code, message: message) print("Ad Warning: \(code) - \(message)") } override func jwplayer(_ player: JWPlayer, isBufferingWithReason reason: JWBufferReason) { super.jwplayer(player, isBufferingWithReason: reason) // player.play() print("Buffering Reason:", reason) } override func jwplayer(_ player: JWPlayer, didPauseWithReason reason: JWPauseReason) { super.jwplayer(player, didPauseWithReason: reason) // Implement custom behavior } } // MARK: - Full Screen Handling extension PlayerVC { func playerViewControllerWillGoFullScreen(_ controller: JWPlayerViewController) -> JWFullScreenViewController? { print("playerViewControllerWillGoFullScreen") // controller.player.stop() // self.player.stop() // controller.dismissFullScreen(animated: true) // self.rotateToPortraitScapeDevice() self.interfaceBehavior = .hidden self.player.stop() controller.player.stop() controller.dismissFullScreen(animated: true) if contentType == .liveStream{ self.dismissTapped?() } self.dismiss(animated: true) // self.player.stop() // Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { _ in // DispatchQueue.main.async { [weak self] in // guard let self else{return} // if contentType == .liveStream{ // self.dismissTapped?() // } // self.dismiss(animated: true) // } // } return nil } func playerViewControllerDidGoFullScreen(_ controller: JWPlayerViewController) { print("playerViewControllerDidGoFullScreen") // self.interfaceBehavior = .hidden // self.player.stop() // controller.player.stop() // controller.dismissFullScreen(animated: true) //// self.player.stop() // Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { _ in // DispatchQueue.main.async { [weak self] in // guard let self else{return} // if contentType == .liveStream{ // self.dismissTapped?() // } // self.dismiss(animated: true) // } // } return } func playerViewControllerWillDismissFullScreen(_ controller: JWPlayerViewController) { print("playerViewControllerWillDismissFullScreen") // self.setDeviceOrientation(orientation: .portrait) // Timer.scheduledTimer(withTimeInterval: 0.4, repeats: false) { _ in // controller.dismissFullScreen(animated: false) { // self.dismissTapped?() // } // } // self.rotateToPotraitScapeDevice() // self.dismiss // self.setDeviceOrientation(orientation: .portrait) // Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in // controller.dismiss(animated: false) { // } // self.setDeviceOrientation(orientation: .portrait) // } } func playerViewControllerDidDismissFullScreen(_ controller: JWPlayerViewController) { print("playerViewControllerDidDismissFullScreen") // self.dismissTapped?() // Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in // self.player.stop() // controller.dismiss(animated: true) // } // self.navigationController?.popViewController(animated: true) } } // MARK: - JWPlayerViewController Delegate Functions extension PlayerVC { func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, controlBarVisibilityChanged isVisible: Bool, frame: CGRect) { self.backButton.isHidden = !isVisible } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, sizeChangedFrom oldSize: CGSize, to newSize: CGSize) { // Handle size change if necessary } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, screenTappedAt position: CGPoint) { // Handle screen tap if necessary } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedMenuOpenedWithItems items: [JWPlayerKit.JWPlayerItem], withMethod method: JWPlayerKit.JWRelatedInteraction) { print("Related items:", items) } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedMenuClosedWithMethod method: JWRelatedInteraction) { print("Related menu closed") } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedItemBeganPlaying item: JWPlayerKit.JWPlayerItem, atIndex index: Int, withMethod method: JWPlayerKit.JWRelatedMethod) { print("Item ", item) } } // MARK: - Orientation Handling // //extension UIViewController { // // func setDeviceOrientation(orientation: UIInterfaceOrientationMask) { // if #available(iOS 16.0, *) { // let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene // windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) // } else { // UIDevice.current.setValue(orientation.toUIInterfaceOrientation.rawValue, forKey: "orientation") // } // } //} // //extension UIInterfaceOrientationMask { // var toUIInterfaceOrientation: UIInterfaceOrientation { // switch self { // case .portrait: // return .portrait // case .portraitUpsideDown: // return .portraitUpsideDown // case .landscapeRight: // return .landscapeRight // case .landscapeLeft: // return .landscapeLeft // default: // return .unknown // } // } //}