367 lines
14 KiB
Swift
367 lines
14 KiB
Swift
//
|
|
// ThemeTwoVM.swift
|
|
// WOKA
|
|
//
|
|
// Created by MacBook Pro on 27/05/24.
|
|
//
|
|
|
|
import UIKit
|
|
import AVFoundation
|
|
import JWPlayerKit
|
|
import Alamofire
|
|
import GoogleMobileAds
|
|
|
|
struct Theme2Struct{
|
|
let imageName : String
|
|
let text : String
|
|
}
|
|
|
|
class ThemeTwoVM{
|
|
|
|
weak var vc : ThemeTwoVC!
|
|
var liveStreamURL = "https://d3volyx7jx7oal.cloudfront.net/master.m3u8"
|
|
var avPlayer : AVPlayer!
|
|
var playerItem: AVPlayerItem!
|
|
var playerLayer: AVPlayerLayer!
|
|
|
|
let reachability = NetworkReachabilityManager()
|
|
let monitor = NWPathMonitor()
|
|
let queue = DispatchQueue.global(qos: .background)
|
|
var isNetworkMonitored = false
|
|
var bannerView = GADBannerView()
|
|
|
|
/*
|
|
Static cell data
|
|
*/
|
|
var cellData = [Theme2Struct(imageName: "WokaFMT2", text: "WOKA FM"),
|
|
Theme2Struct(imageName: "LiveTVT2", text: "LIVE TV"),
|
|
Theme2Struct(imageName: "WebSeriesT2", text: "WEB SERIES"),
|
|
Theme2Struct(imageName: "GamesT2", text: "GAMES"),
|
|
Theme2Struct(imageName: "AudioBooksT2", text: "AUDIO BOOKS"),
|
|
Theme2Struct(imageName: "KaraokeT2", text: "KARAOKE"),
|
|
Theme2Struct(imageName: "ShopT2", text: "SHOP")]
|
|
|
|
func initView(){
|
|
setupCell()
|
|
setupAvPlayer()
|
|
setUserData()
|
|
|
|
handleNotificationCenter()
|
|
vc.liveTvView.addTapGesture { [weak self] in
|
|
PersistentStorage.shared.addOthersCount()
|
|
CommonNwCallTheme.shareInstance.checkUniqueUser()
|
|
guard let self else{return}
|
|
self.playLiveTV()
|
|
}
|
|
|
|
if let adsData = AuthFunc.shareInstance.adsData, let themeTwoAD = adsData.result?.filter({$0.slug == AdsEnum.themeTwo.rawValue}).first, themeTwoAD.googleAd != nil{
|
|
// Show google ads if its configured from backend.
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in
|
|
guard let self else{return}
|
|
AdReusable.sharedInstance.setupBannerAd(bannerView: bannerView, in: vc.adView, adUnitID: K.GoogleAdIDs.splashBanner1, viewController: self.vc, height: 8, width: 15)
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
private func handleNotificationCenter(){
|
|
NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
|
|
NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
|
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)
|
|
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
|
|
}
|
|
|
|
// MARK: - This will handle all clicks for modules
|
|
|
|
// This comes from Explore WOKA CLicks
|
|
@objc func viewPush(notification: Notification){
|
|
if let userInfo = notification.userInfo, let action = userInfo["action"] as? TopViewPush {
|
|
checkType(action: action)
|
|
}
|
|
}
|
|
|
|
// Made a common func to check which module to push
|
|
func checkType(action : TopViewPush){
|
|
switch action {
|
|
case .webseries:
|
|
let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.webSeriesVC) as! WebSeriesVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .audioBooks:
|
|
let sb = UIStoryboard(name: K.StoryBoard.audioBooks, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.AudioBooks.audioBookHomeVC) as! AudioBookHomeVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .games:
|
|
let sb = UIStoryboard(name: K.StoryBoard.Games, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Games.gamesListVC) as! GamesListVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .karaoke:
|
|
let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.karaokeListingVC) as! KaraokeListingVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .shop:
|
|
let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.shopListingVC) as! ShopListingVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .liveTV:
|
|
playLiveTV()
|
|
case .blogs:
|
|
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.blogsVC) as! BlogsVC
|
|
vc.navigationController?.pushViewController(vcPush, animated: true)
|
|
case .radio:
|
|
let sb = UIStoryboard(name: K.StoryBoard.wokaFM, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WokaFM.wokaFMVC) as! WokaFMVC
|
|
vcPush.modalPresentationStyle = .overCurrentContext
|
|
vcPush.modalTransitionStyle = .crossDissolve
|
|
vc.present(vcPush, animated: true)
|
|
}
|
|
}
|
|
|
|
// MARK: - Notification Center Handlers
|
|
|
|
@objc func reloadTheme(){
|
|
self.vc.delegate?.didPressSwitchButton(from: self.vc)
|
|
}
|
|
|
|
@objc func appDidEnterBackground() {
|
|
// Code to execute when the app enters the background
|
|
print("App entered background")
|
|
self.avPlayer.pause()
|
|
}
|
|
|
|
@objc func appWillEnterForeground() {
|
|
// Code to execute when the app enters the foreground
|
|
print("App will enter foreground")
|
|
self.avPlayer.play()
|
|
}
|
|
|
|
@objc func handleRouteChange(_ notification: Notification) {
|
|
guard let userInfo = notification.userInfo,
|
|
let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
|
|
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
|
|
return
|
|
}
|
|
|
|
switch reason {
|
|
case .oldDeviceUnavailable:
|
|
// Headphones unplugged, avoid pausing if desired
|
|
avPlayer?.play() // Resume playing if paused
|
|
|
|
case .newDeviceAvailable:
|
|
// Headphones plugged in, you may want to take specific actions if needed
|
|
avPlayer?.play() // Resume playing if paused
|
|
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
// MARK: - Live TV
|
|
|
|
func playLiveTV(){
|
|
Utilities.startProgressHUD(msg: "Loading...")
|
|
print("tapped")
|
|
let vc = self.vc.storyboard?.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC
|
|
|
|
guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
|
|
self.vc.toast(msg: "Issue with live streaming", time: 2)
|
|
return
|
|
}
|
|
var url = String()
|
|
var title = String()
|
|
|
|
if AuthFunc.shareInstance.languageSelected == .english{
|
|
url = liveStreamData.liveURL?.hdURLEn ?? ""
|
|
title = liveStreamData.name?.titleEn ?? ""
|
|
}else{
|
|
url = liveStreamData.liveURL?.hdURLHin ?? ""
|
|
title = liveStreamData.name?.titleHin ?? ""
|
|
}
|
|
|
|
do {
|
|
// Ensure the liveStreamURL is valid
|
|
guard let liveStreamURL = URL(string: url) else {
|
|
print("Invalid live stream URL")
|
|
Utilities.dismissProgressHUD()
|
|
return
|
|
}
|
|
|
|
let videoSourceBuilder = try JWVideoSourceBuilder()
|
|
// .defaultVideo(true)
|
|
.file(liveStreamURL)
|
|
.label(title)
|
|
.build()
|
|
|
|
// Create a JWPlayerItem
|
|
let item = try JWPlayerItemBuilder()
|
|
// .file(liveStreamURL)
|
|
.videoSources([videoSourceBuilder])
|
|
.title(title)
|
|
.mediaId(K.MediaIDs.liveStreamMediaID)
|
|
.build()
|
|
|
|
// Create a JWPlayerConfiguration
|
|
let config = try JWPlayerConfigurationBuilder()
|
|
.playlist(items: [item])
|
|
.preload(JWPreload(rawValue: 20) ?? .none)
|
|
.autostart(true)
|
|
.build()
|
|
|
|
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
|
|
|
|
// Present the PlayerVC
|
|
self.vc.present(vc, animated: true) { [weak self] in
|
|
guard let self else{return}
|
|
stopLiveStream()
|
|
}
|
|
} catch {
|
|
print("Error creating JWPlayer configuration: \(error)")
|
|
Utilities.dismissProgressHUD()
|
|
}
|
|
|
|
// Dismiss the progress HUD after the view controller presentation
|
|
Utilities.dismissProgressHUD()
|
|
}
|
|
|
|
func tapped(){
|
|
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
|
|
self.startLiveStream()
|
|
self.vc.liveTvView.layoutIfNeeded()
|
|
}
|
|
print("Sadasd")
|
|
}
|
|
|
|
func startLiveStream(){
|
|
avPlayer.play()
|
|
avPlayer.volume = 0
|
|
}
|
|
|
|
func stopLiveStream(){
|
|
avPlayer.pause()
|
|
}
|
|
|
|
func setUserData(){
|
|
guard let data = AuthFunc.shareInstance.userData else{return}
|
|
//set the first name as the name
|
|
/*
|
|
Check User Type,
|
|
Dont show username if the user type is guest
|
|
*/
|
|
switch data.userType{
|
|
case "1": // child
|
|
vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
|
|
vc.notificationBtn.isHidden = false
|
|
case "2" : // adult
|
|
vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
|
|
vc.notificationBtn.isHidden = false
|
|
case "3": // Guest
|
|
vc.nameLabel.text = ""
|
|
vc.notificationBtn.isHidden = true
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
|
|
if let avatar = data.avtarURL{
|
|
vc.avatarImage.imageURL(avatar,color: .white, type: .homeAvatar)
|
|
}else{
|
|
vc.avatarImage.image = UIImage(named: "DefaultAvatar")
|
|
}
|
|
}
|
|
|
|
func setupAvPlayer(){
|
|
/*
|
|
Av Player Setup
|
|
*/
|
|
guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
|
|
vc.toast(msg: "Issue with live streaming", time: 2)
|
|
return
|
|
}
|
|
var url = String()
|
|
|
|
if AuthFunc.shareInstance.languageSelected == .english{
|
|
url = liveStreamData.liveURL?.hdURLEn ?? ""
|
|
}else{
|
|
url = liveStreamData.liveURL?.hdURLHin ?? ""
|
|
}
|
|
|
|
guard let streamURL = URL(string: url) else{return}
|
|
startStopActivity(isStart: true)
|
|
playerItem = AVPlayerItem(url: streamURL)
|
|
|
|
// Create AVPlayer with the stream URL
|
|
avPlayer = AVPlayer(playerItem: playerItem)
|
|
// avPlayer.isMuted = true
|
|
|
|
// Create AVPlayerLayer
|
|
playerLayer = AVPlayerLayer(player: avPlayer)
|
|
playerLayer.videoGravity = .resizeAspectFill // You can set different videoGravity as per your need
|
|
|
|
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(){
|
|
|
|
// playerLayer.frame = self.vc.liveTvView.bounds
|
|
|
|
guard let data = AuthFunc.shareInstance.userData else{return}
|
|
//set the first name as the name
|
|
/*
|
|
Check User Type,
|
|
Dont show username if the user type is guest
|
|
*/
|
|
switch data.userType{
|
|
case "1": // child
|
|
vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
|
|
case "2" : // adult
|
|
vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first
|
|
case "3": // Guest
|
|
vc.nameLabel.text = ""
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
|
|
}
|
|
|
|
// 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(){
|
|
vc.collectionView.register(UINib(nibName: K.CellIdentifier.Theme.homeExploreCell, bundle: nil), forCellWithReuseIdentifier: K.CellIdentifier.Theme.homeExploreCell)
|
|
vc.collectionView.delegate = vc.self
|
|
vc.collectionView.dataSource = vc.self
|
|
}
|
|
}
|