added new checks for avplayer
This commit is contained in:
@@ -2746,14 +2746,13 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = WOKA/WOKA.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 4;
|
||||
CURRENT_PROJECT_VERSION = 6;
|
||||
DEVELOPMENT_TEAM = 4S9A74ZB6H;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WOKA/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WOKA;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Give Permissions for Karaoke";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard;
|
||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||
@@ -2786,14 +2785,13 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = WOKA/WOKA.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 4;
|
||||
CURRENT_PROJECT_VERSION = 6;
|
||||
DEVELOPMENT_TEAM = 4S9A74ZB6H;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WOKA/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WOKA;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Give Permissions for Karaoke";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard;
|
||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
<string>$(API_KEY_ID)</string>
|
||||
<key>API_KEY_PASS</key>
|
||||
<string>$(API_KEY_PASS)</string>
|
||||
<key>NSUserNotificationsUsageDescription</key>
|
||||
<string>You need to allow for notifications to keep you updated about the content.</string>
|
||||
<key>STAGING_URL</key>
|
||||
<string>$(STAGING_URL)</string>
|
||||
<key>UIAppFonts</key>
|
||||
@@ -41,7 +43,7 @@
|
||||
<string>audio</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>NSUserNotificationsUsageDescription</key>
|
||||
<string>You need to allow for notifications to keep you updated about the content.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Give Permissions for Karaoke</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -862,3 +862,21 @@ extension SideMenuController: UIGestureRecognizerDelegate {
|
||||
return abs(velocity.y / velocity.x) < preferences.basic.panGestureSensitivity
|
||||
}
|
||||
}
|
||||
|
||||
func topVC(in rootViewController: UIViewController) -> UIViewController? {
|
||||
if let sideMenuController = rootViewController as? SideMenuController {
|
||||
// The main content is managed by contentViewController in SideMenuController
|
||||
if let mainViewController = sideMenuController.contentViewController {
|
||||
return topVC(in: mainViewController)
|
||||
}
|
||||
} else if let tabBarController = rootViewController as? UITabBarController, let selectedVC = tabBarController.selectedViewController{
|
||||
return topVC(in: selectedVC)
|
||||
} else if let navigationController = rootViewController as? UINavigationController, let visibleVC = navigationController.visibleViewController {
|
||||
return topVC(in: visibleVC)
|
||||
} else if let presentedViewController = rootViewController.presentedViewController {
|
||||
return topVC(in: presentedViewController)
|
||||
} else {
|
||||
return rootViewController
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -562,16 +562,16 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="U0W-18-4oe">
|
||||
<rect key="frame" x="0.0" y="45" width="393" height="222"/>
|
||||
<rect key="frame" x="0.0" y="45.000000000000014" width="393" height="223.33333333333337"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Coming Soon on WOKA" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D2p-c5-usH" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="373" height="22"/>
|
||||
<rect key="frame" x="10" y="9.9999999999999982" width="373" height="23.333333333333329"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UKc-92-GPa">
|
||||
<rect key="frame" x="10" y="42" width="373" height="180"/>
|
||||
<rect key="frame" x="10" y="43.333333333333343" width="373" height="180"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="MasilaComingSoon" translatesAutoresizingMaskIntoConstraints="NO" id="Kj9-jH-Y88">
|
||||
<rect key="frame" x="7" y="7" width="359" height="140"/>
|
||||
@@ -605,7 +605,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MASILA" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="biB-gs-Rgq">
|
||||
<rect key="frame" x="7" y="152" width="359" height="21.666666666666657"/>
|
||||
<rect key="frame" x="7" y="151.99999999999997" width="359" height="21"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -633,16 +633,16 @@
|
||||
<edgeInsets key="layoutMargins" top="10" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Qcq-yj-AzB">
|
||||
<rect key="frame" x="0.0" y="267" width="393" height="209"/>
|
||||
<rect key="frame" x="0.0" y="268.33333333333331" width="393" height="208.33333333333331"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="BLOGS" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lW0-W4-2hl" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="373" height="24"/>
|
||||
<rect key="frame" x="10" y="9.9999999999999982" width="373" height="23.333333333333329"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="xup-gW-Kjh">
|
||||
<rect key="frame" x="10" y="39" width="373" height="170"/>
|
||||
<rect key="frame" x="10" y="38.333333333333371" width="373" height="170"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="170" id="fTZ-PQ-nXX"/>
|
||||
@@ -659,16 +659,16 @@
|
||||
<edgeInsets key="layoutMargins" top="10" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="pJu-fq-XmG">
|
||||
<rect key="frame" x="0.0" y="476" width="393" height="268"/>
|
||||
<rect key="frame" x="0.0" y="476.66666666666663" width="393" height="267.33333333333337"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="WOKA Songs" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FSJ-QT-rAW" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="373" height="24"/>
|
||||
<rect key="frame" x="10" y="9.9999999999999982" width="373" height="23.333333333333329"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="31Z-fz-1ec">
|
||||
<rect key="frame" x="10" y="44" width="373" height="224"/>
|
||||
<rect key="frame" x="10" y="43.333333333333371" width="373" height="224"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tableView>
|
||||
</subviews>
|
||||
@@ -775,9 +775,17 @@
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ksi-1c-xBG">
|
||||
<rect key="frame" x="0.0" y="134" width="393" height="220"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<subviews>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="large" translatesAutoresizingMaskIntoConstraints="NO" id="3yT-Xz-Xmu">
|
||||
<rect key="frame" x="178" y="91.666666666666657" width="37" height="37"/>
|
||||
<color key="color" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="ImageDarkBlue"/>
|
||||
<constraints>
|
||||
<constraint firstItem="3yT-Xz-Xmu" firstAttribute="centerX" secondItem="Ksi-1c-xBG" secondAttribute="centerX" id="FRZ-2O-djZ"/>
|
||||
<constraint firstAttribute="height" constant="220" id="ezY-uu-Vnb"/>
|
||||
<constraint firstItem="3yT-Xz-Xmu" firstAttribute="centerY" secondItem="Ksi-1c-xBG" secondAttribute="centerY" id="rP5-fU-dzt"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LiveHindi" translatesAutoresizingMaskIntoConstraints="NO" id="03W-c9-Rk6">
|
||||
@@ -1015,6 +1023,7 @@
|
||||
<connections>
|
||||
<outlet property="avatarImage" destination="4xI-oX-ffb" id="CJN-fs-BUe"/>
|
||||
<outlet property="collectionView" destination="4rq-xX-XRh" id="Z66-JF-bp2"/>
|
||||
<outlet property="liveTVActivityIndicator" destination="3yT-Xz-Xmu" id="qBm-dV-10P"/>
|
||||
<outlet property="liveTvView" destination="Ksi-1c-xBG" id="xcg-na-dB1"/>
|
||||
<outlet property="nameLabel" destination="Qn2-Bb-Ud6" id="t3V-Kr-Tkh"/>
|
||||
<outlet property="notificationBtn" destination="tl8-VA-AjQ" id="p7t-q6-5US"/>
|
||||
@@ -1312,6 +1321,9 @@
|
||||
<image name="SupportGirlImage" width="166" height="166"/>
|
||||
<image name="UpArrowMore" width="25" height="25"/>
|
||||
<image name="WebSeries" width="164" height="118.66666412353516"/>
|
||||
<namedColor name="ImageDarkBlue">
|
||||
<color red="0.035000000149011612" green="0.0" blue="0.36500000953674316" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<namedColor name="TextDarkBlue">
|
||||
<color red="0.10599999874830246" green="0.050999999046325684" blue="0.60399997234344482" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
@@ -1319,7 +1331,7 @@
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBrownColor">
|
||||
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import UIKit
|
||||
import Alamofire
|
||||
import AVFoundation
|
||||
|
||||
class ThemeOneVC: UIViewController {
|
||||
|
||||
@@ -42,6 +43,9 @@ class ThemeOneVC: UIViewController {
|
||||
|
||||
weak var delegate: ChildViewControllerDelegate?
|
||||
|
||||
|
||||
// MARK: - LifeCycle
|
||||
|
||||
deinit{
|
||||
timer?.invalidate()
|
||||
// Removing observers
|
||||
@@ -51,10 +55,10 @@ class ThemeOneVC: UIViewController {
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeOnePush), object: nil)
|
||||
if let playerItem = vm.playerItem{
|
||||
playerItem.removeObserver(self, forKeyPath: "status")
|
||||
playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
// playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
// playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
}
|
||||
if let playerLayer = vm.playerLayer, let avPlayer = vm.avPlayer {
|
||||
if let avPlayer = vm.avPlayer {
|
||||
avPlayer.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
avPlayer.pause()
|
||||
}
|
||||
@@ -171,51 +175,94 @@ extension ThemeOneVC{
|
||||
vm.avPlayer.addObserver(self, forKeyPath: "timeControlStatus", options: [.new, .old], context: nil)
|
||||
|
||||
// Observe buffering status
|
||||
vm.playerItem.addObserver(self, forKeyPath: "isPlaybackBufferEmpty", options: [.new, .old], context: nil)
|
||||
vm.playerItem.addObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp", options: [.new, .old], context: nil)
|
||||
// vm.playerItem.addObserver(self, forKeyPath: "isPlaybackBufferEmpty", options: [.new, .old], context: nil)
|
||||
// vm.playerItem.addObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp", options: [.new, .old], context: nil)
|
||||
}
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
//this will oberver if player loads the url or fails
|
||||
if keyPath == "status" {
|
||||
if vm.playerItem.status == .readyToPlay {
|
||||
print("Player is ready to play")
|
||||
print("Theme 2 Player is ready to play")
|
||||
vm.avPlayer.play()
|
||||
} else if vm.playerItem.status == .failed {
|
||||
print("Player failed to load")
|
||||
if !liveTVActivityIndicator.isAnimating{
|
||||
liveTVActivityIndicator.startAnimating()
|
||||
}
|
||||
}
|
||||
} else if keyPath == "timeControlStatus" {
|
||||
switch vm.avPlayer.timeControlStatus {
|
||||
case .playing:
|
||||
print("Player is playing")
|
||||
liveTVActivityIndicator.stopAnimating()
|
||||
case .paused:
|
||||
print("Player is paused")
|
||||
vm.avPlayer.play()
|
||||
liveTVActivityIndicator.stopAnimating()
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
print("Player is Buffering 1")
|
||||
if !(NetworkReachabilityManager()?.isReachable ?? false){
|
||||
if !NetworkReachibility.shared.isMonitoring{
|
||||
startMonitoring()
|
||||
}
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
}
|
||||
} else if keyPath == "isPlaybackBufferEmpty" {
|
||||
if vm.playerItem.isPlaybackBufferEmpty {
|
||||
print("Player is buffering 2")
|
||||
liveTVActivityIndicator.startAnimating()
|
||||
startMonitoring()
|
||||
}
|
||||
} else if keyPath == "isPlaybackLikelyToKeepUp" {
|
||||
if vm.playerItem.isPlaybackLikelyToKeepUp {
|
||||
print("Player is likely to keep up with the playback")
|
||||
print("Theme 2 Player failed to load")
|
||||
vm.setupAvPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
//this will give status of buffering, play pause.
|
||||
if keyPath == "timeControlStatus" {
|
||||
if let player = object as? AVPlayer {
|
||||
switch player.timeControlStatus {
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
print("Theme 2 Player Buffering...")
|
||||
vm.startStopActivity(isStart: true)
|
||||
case .playing:
|
||||
print("Theme 2 Player Playing")
|
||||
vm.startStopActivity(isStart: false)
|
||||
case .paused:
|
||||
print("Theme 2 Player Paused")
|
||||
|
||||
// check if app is in background return it
|
||||
if UIApplication.shared.applicationState == .background {return}
|
||||
if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController {
|
||||
if let topVC = topVC(in: rootViewController) {
|
||||
if topVC is HomeVC{
|
||||
vm.avPlayer.play()
|
||||
} else {
|
||||
print("The top view controller is not HomeVC")
|
||||
}
|
||||
} else {
|
||||
print("No top view controller found")
|
||||
}
|
||||
}
|
||||
|
||||
@unknown default:
|
||||
print("Theme 2 Player Unknown status")
|
||||
}
|
||||
}
|
||||
}
|
||||
// if keyPath == "status" {
|
||||
// if vm.playerItem.status == .readyToPlay {
|
||||
// print("Player is ready to play")
|
||||
// vm.avPlayer.play()
|
||||
// } else if vm.playerItem.status == .failed {
|
||||
// print("Player failed to load")
|
||||
// if !liveTVActivityIndicator.isAnimating{
|
||||
// liveTVActivityIndicator.startAnimating()
|
||||
// }
|
||||
// }
|
||||
// } else if keyPath == "timeControlStatus" {
|
||||
// switch vm.avPlayer.timeControlStatus {
|
||||
// case .playing:
|
||||
// print("Player is playing")
|
||||
// liveTVActivityIndicator.stopAnimating()
|
||||
// case .paused:
|
||||
// print("Player is paused")
|
||||
// vm.avPlayer.play()
|
||||
// liveTVActivityIndicator.stopAnimating()
|
||||
// case .waitingToPlayAtSpecifiedRate:
|
||||
// print("Player is Buffering 1")
|
||||
// if !(NetworkReachabilityManager()?.isReachable ?? false){
|
||||
// if !NetworkReachibility.shared.isMonitoring{
|
||||
// startMonitoring()
|
||||
// }
|
||||
// }
|
||||
// @unknown default:
|
||||
// break
|
||||
// }
|
||||
// } else if keyPath == "isPlaybackBufferEmpty" {
|
||||
// if vm.playerItem.isPlaybackBufferEmpty {
|
||||
// print("Player is buffering 2")
|
||||
// liveTVActivityIndicator.startAnimating()
|
||||
// startMonitoring()
|
||||
// }
|
||||
// } else if keyPath == "isPlaybackLikelyToKeepUp" {
|
||||
// if vm.playerItem.isPlaybackLikelyToKeepUp {
|
||||
// print("Player is likely to keep up with the playback")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import UIKit
|
||||
import AVFAudio
|
||||
import AVFoundation
|
||||
|
||||
class ThemeTwoVC: UIViewController {
|
||||
|
||||
@@ -17,11 +18,25 @@ class ThemeTwoVC: UIViewController {
|
||||
@IBOutlet weak var avatarImage: UIImageView!
|
||||
@IBOutlet weak var notificationBtn: UIButton!
|
||||
|
||||
@IBOutlet weak var liveTVActivityIndicator: UIActivityIndicatorView!
|
||||
|
||||
var vm = ThemeTwoVM()
|
||||
|
||||
deinit{
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeTwoPush), object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
// vm.avPlayer.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
// vm.playerItem.removeObserver(self, forKeyPath: "status")
|
||||
|
||||
if let playerItem = vm.playerItem{
|
||||
playerItem.removeObserver(self, forKeyPath: "status")
|
||||
}
|
||||
if let avPlayer = vm.avPlayer {
|
||||
avPlayer.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
avPlayer.pause()
|
||||
}
|
||||
}
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
@@ -78,6 +93,56 @@ class ThemeTwoVC: UIViewController {
|
||||
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
|
||||
}
|
||||
|
||||
// MARK: - Handler for AvPlayer
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
|
||||
//this will oberver if player loads the url or fails
|
||||
if keyPath == "status" {
|
||||
if vm.playerItem.status == .readyToPlay {
|
||||
print("Theme 1 Player is ready to play")
|
||||
vm.avPlayer.play()
|
||||
} else if vm.playerItem.status == .failed {
|
||||
print("Theme 1 Player failed to load")
|
||||
vm.setupAvPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
//this will give status of buffering, play pause.
|
||||
if keyPath == "timeControlStatus" {
|
||||
if let player = object as? AVPlayer {
|
||||
switch player.timeControlStatus {
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
print("Theme 1 Player Buffering...")
|
||||
vm.startStopActivity(isStart: true)
|
||||
case .playing:
|
||||
print("Theme 1 Player Playing")
|
||||
vm.startStopActivity(isStart: false)
|
||||
case .paused:
|
||||
print("Theme 1 Player Paused")
|
||||
|
||||
// check if app is in background return it
|
||||
if UIApplication.shared.applicationState == .background {return}
|
||||
if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController {
|
||||
if let topVC = topVC(in: rootViewController) {
|
||||
if topVC is HomeVC{
|
||||
vm.avPlayer.play()
|
||||
} else {
|
||||
print("The top view controller is not HomeVC")
|
||||
}
|
||||
} else {
|
||||
print("No top view controller found")
|
||||
}
|
||||
}
|
||||
|
||||
@unknown default:
|
||||
print("Theme 2 Player Unknown status")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - CollectionView DataSource Delegate
|
||||
|
||||
@@ -23,9 +23,7 @@ class ThemeOneVM{
|
||||
|
||||
var shouldAnimate = true
|
||||
let reachability = NetworkReachabilityManager()
|
||||
|
||||
// var jwPlayerViewController: JWPlayerViewController!
|
||||
|
||||
|
||||
func initView(){
|
||||
|
||||
AuthFunc.shareInstance.initTimePeriods()
|
||||
@@ -50,59 +48,6 @@ class ThemeOneVM{
|
||||
}
|
||||
|
||||
func setupAvPlayer(){
|
||||
// Ensure the liveStreamURL is valid
|
||||
// guard let liveStreamURL = URL(string: self.liveStreamURL) else {
|
||||
// print("Invalid live stream URL")
|
||||
// Utilities.dismissProgressHUD()
|
||||
// return
|
||||
// }
|
||||
// jwPlayerViewController = JWPlayerViewController()
|
||||
// do{
|
||||
// let videoSourceBuilder = try JWVideoSourceBuilder()
|
||||
// // .defaultVideo(true)
|
||||
// .file(liveStreamURL)
|
||||
// .label("Live Stream")
|
||||
// .build()
|
||||
//
|
||||
// // Create a JWPlayerItem
|
||||
// let item = try JWPlayerItemBuilder()
|
||||
// // .file(liveStreamURL)
|
||||
// .videoSources([videoSourceBuilder])
|
||||
// .build()
|
||||
//
|
||||
// // Create a JWPlayerConfiguration
|
||||
// let config = try JWPlayerConfigurationBuilder()
|
||||
// .playlist(items: [item])
|
||||
//// .preload(JWPreload(rawValue: 20) ?? .none)
|
||||
// .autostart(true)
|
||||
// .build()
|
||||
//
|
||||
//
|
||||
//
|
||||
// // Add JWPlayerViewController's view as a subview
|
||||
// self.vc.liveTvPlayer.addSubview(jwPlayerViewController.view)
|
||||
// jwPlayerViewController.view.frame = self.vc.liveTvPlayer.bounds
|
||||
//
|
||||
//// // Set up constraints
|
||||
//// jwPlayerViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
//// NSLayoutConstraint.activate([
|
||||
//// jwPlayerViewController.view.topAnchor.constraint(equalTo: self.vc.liveTvPlayer.topAnchor),
|
||||
//// jwPlayerViewController.view.leadingAnchor.constraint(equalTo: self.vc.liveTvPlayer.leadingAnchor),
|
||||
//// jwPlayerViewController.view.trailingAnchor.constraint(equalTo: self.vc.liveTvPlayer.trailingAnchor),
|
||||
//// jwPlayerViewController.view.bottomAnchor.constraint(equalTo: self.vc.liveTvPlayer.bottomAnchor)
|
||||
//// ])
|
||||
// jwPlayerViewController.player.volume = 0.0
|
||||
//
|
||||
// jwPlayerViewController.player.configurePlayer(with: config)
|
||||
// jwPlayerViewController.interfaceBehavior = .hidden
|
||||
//// self.vc.liveTvPlayer.addSubview(jwPlayerViewController.view)
|
||||
//// jwPlayerViewController.player.play()
|
||||
//
|
||||
// }catch{
|
||||
// print(error)
|
||||
// }
|
||||
|
||||
|
||||
/*
|
||||
Av Player Setup
|
||||
*/
|
||||
@@ -139,6 +84,20 @@ class ThemeOneVM{
|
||||
avPlayer.volume = 0
|
||||
}
|
||||
|
||||
// MARK: - start stop activity Indicator
|
||||
|
||||
func startStopActivity(isStart : Bool){
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
if isStart{
|
||||
vc.liveTVActivityIndicator.startAnimating()
|
||||
}else{
|
||||
vc.liveTVActivityIndicator.hidesWhenStopped = true
|
||||
vc.liveTVActivityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setUserData(){
|
||||
guard let data = AuthFunc.shareInstance.userData else{return}
|
||||
//set the first name as the name
|
||||
@@ -179,18 +138,34 @@ class ThemeOneVM{
|
||||
@objc func appDidEnterBackground() {
|
||||
// Code to execute when the app enters the background
|
||||
print("App entered background")
|
||||
if UIApplication.topViewController() == ThemeOneVC(){
|
||||
avPlayer.pause()
|
||||
handleBackground()
|
||||
if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController {
|
||||
if let topVC = topVC(in: rootViewController) {
|
||||
if topVC is HomeVC{
|
||||
avPlayer.pause()
|
||||
handleBackground()
|
||||
} else {
|
||||
print("The top view controller is not HomeVC")
|
||||
}
|
||||
} else {
|
||||
print("No top view controller found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
// Code to execute when the app enters the foreground
|
||||
print("App will enter foreground")
|
||||
if UIApplication.topViewController() == ThemeOneVC(){
|
||||
avPlayer.play()
|
||||
handleBackground()
|
||||
if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController {
|
||||
if let topVC = topVC(in: rootViewController) {
|
||||
if topVC is HomeVC{
|
||||
avPlayer.play()
|
||||
handleBackground()
|
||||
} else {
|
||||
print("The top view controller is not HomeVC")
|
||||
}
|
||||
} else {
|
||||
print("No top view controller found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class ThemeTwoVM{
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.viewPush(notification:)), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeTwoPush), object: nil)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - This will handle all clicks for modules
|
||||
|
||||
// This comes from Explore WOKA CLicks
|
||||
@@ -171,6 +171,9 @@ class ThemeTwoVM{
|
||||
vc.config = config
|
||||
vc.dismissTapped = self.tapped
|
||||
vc.contentType = .liveStream
|
||||
if let streamID = AuthFunc.shareInstance.staticURLs?.liveData?.first?.id{
|
||||
vc.vm.videoIDs = [streamID]
|
||||
}
|
||||
vc.modalPresentationStyle = .fullScreen
|
||||
vc.modalTransitionStyle = .crossDissolve
|
||||
|
||||
@@ -240,7 +243,7 @@ class ThemeTwoVM{
|
||||
Av Player Setup
|
||||
*/
|
||||
guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
|
||||
self.vc.toast(msg: "Issue with live streaming", time: 2)
|
||||
vc.toast(msg: "Issue with live streaming", time: 2)
|
||||
return
|
||||
}
|
||||
var url = String()
|
||||
@@ -252,7 +255,7 @@ class ThemeTwoVM{
|
||||
}
|
||||
|
||||
guard let streamURL = URL(string: url) else{return}
|
||||
|
||||
startStopActivity(isStart: true)
|
||||
playerItem = AVPlayerItem(url: streamURL)
|
||||
|
||||
// Create AVPlayer with the stream URL
|
||||
@@ -263,11 +266,16 @@ class ThemeTwoVM{
|
||||
playerLayer = AVPlayerLayer(player: avPlayer)
|
||||
playerLayer.videoGravity = .resizeAspectFill // You can set different videoGravity as per your need
|
||||
|
||||
playerLayer.frame = self.vc.liveTvView.bounds
|
||||
self.vc.liveTvView.layer.addSublayer(playerLayer)
|
||||
self.vc.liveTvView.layoutIfNeeded()
|
||||
playerLayer.frame = vc.liveTvView.bounds
|
||||
vc.liveTvView.layer.addSublayer(playerLayer)
|
||||
vc.liveTvView.bringSubviewToFront(vc.liveTVActivityIndicator)
|
||||
vc.liveTvView.layoutIfNeeded()
|
||||
avPlayer.play()
|
||||
avPlayer.volume = 0
|
||||
|
||||
//Add Observer after the player is setup
|
||||
avPlayer.addObserver(vc, forKeyPath: "timeControlStatus", options: [.new, .old], context: nil)
|
||||
playerItem.addObserver(vc, forKeyPath: "status", options: [.new, .old], context: nil)
|
||||
}
|
||||
|
||||
func setData(){
|
||||
@@ -294,6 +302,20 @@ class ThemeTwoVM{
|
||||
|
||||
}
|
||||
|
||||
// MARK: - start stop activity Indicator
|
||||
|
||||
func startStopActivity(isStart : Bool){
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
if isStart{
|
||||
vc.liveTVActivityIndicator.startAnimating()
|
||||
}else{
|
||||
vc.liveTVActivityIndicator.hidesWhenStopped = true
|
||||
vc.liveTVActivityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SetupCell
|
||||
|
||||
func setupCell(){
|
||||
|
||||
@@ -145,10 +145,10 @@ class WokaFMVC: UIViewController {
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "status" {
|
||||
if vm.playerItem.status == .readyToPlay {
|
||||
print("Player is ready to play")
|
||||
print("FM is ready to play")
|
||||
vm.player.play()
|
||||
} else if vm.playerItem.status == .failed {
|
||||
print("Player failed to load")
|
||||
print("FM failed to load")
|
||||
activityIndicator.stopAnimating()
|
||||
playBtn.setImage(UIImage(named: "Reload"), for: .normal)
|
||||
playBtn.isEnabled = true
|
||||
@@ -156,12 +156,12 @@ class WokaFMVC: UIViewController {
|
||||
} else if keyPath == "timeControlStatus" {
|
||||
switch vm.player.timeControlStatus {
|
||||
case .playing:
|
||||
print("Player is playing")
|
||||
print("FM is playing")
|
||||
activityIndicator.stopAnimating()
|
||||
playBtn.isEnabled = true
|
||||
playBtn.setImage(UIImage(named: "PauseButton"), for: .normal)
|
||||
case .paused:
|
||||
print("Player is paused")
|
||||
print("FM is paused")
|
||||
playBtn.setImage(UIImage(named: "PlayButton"), for: .normal)
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
activityIndicator.startAnimating()
|
||||
@@ -170,20 +170,20 @@ class WokaFMVC: UIViewController {
|
||||
if !(NetworkReachabilityManager()?.isReachable ?? false){
|
||||
startMonitoring()
|
||||
}
|
||||
print("Player is buffering 1 ")
|
||||
print("FM is buffering 1 ")
|
||||
@unknown default:
|
||||
break
|
||||
}
|
||||
} else if keyPath == "isPlaybackBufferEmpty" {
|
||||
if vm.playerItem.isPlaybackBufferEmpty {
|
||||
print("Player is buffering 2")
|
||||
print("FM is buffering 2")
|
||||
playBtn.isEnabled = false
|
||||
activityIndicator.startAnimating()
|
||||
startMonitoring()
|
||||
}
|
||||
} else if keyPath == "isPlaybackLikelyToKeepUp" {
|
||||
if vm.playerItem.isPlaybackLikelyToKeepUp {
|
||||
print("Player is likely to keep up with the playback")
|
||||
print("FM is likely to keep up with the playback")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user