Files
Woka_Native_iOS/WOKA/Theme/ViewModel/ThemeTwoVM.swift

356 lines
13 KiB
Swift
Raw Normal View History

//
// ThemeTwoVM.swift
// WOKA
//
// Created by MacBook Pro on 27/05/24.
//
import UIKit
import AVFoundation
import JWPlayerKit
2024-08-30 22:52:22 +05:30
import Alamofire
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!
2024-08-30 22:52:22 +05:30
let reachability = NetworkReachabilityManager()
let monitor = NWPathMonitor()
let queue = DispatchQueue.global(qos: .background)
var isNetworkMonitored = false
/*
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()
2024-08-08 18:47:13 +05:30
vc.liveTvView.addTapGesture { [weak self] in
PersistentStorage.shared.addOthersCount()
2024-08-08 18:47:13 +05:30
guard let self else{return}
self.playLiveTV()
}
}
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)
2024-07-25 01:03:19 +05:30
NotificationCenter.default.addObserver(self, selector: #selector(self.viewPush(notification:)), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeTwoPush), object: nil)
2024-08-21 01:56:53 +05:30
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
}
2024-08-19 23:43:40 +05:30
// MARK: - This will handle all clicks for modules
2024-08-21 01:56:53 +05:30
// This comes from Explore WOKA CLicks
2024-07-25 01:03:19 +05:30
@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)
2024-07-25 01:03:19 +05:30
}
}
// 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()
}
2024-08-21 01:56:53 +05:30
@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)
.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
2024-08-19 23:43:40 +05:30
if let streamID = AuthFunc.shareInstance.staticURLs?.liveData?.first?.id{
vc.vm.videoIDs = [streamID]
}
vc.modalPresentationStyle = .fullScreen
vc.modalTransitionStyle = .crossDissolve
// Present the PlayerVC
2024-08-21 01:56:53 +05:30
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("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852")
vc.avatarImage.imageURL(avatar)
}else{
vc.avatarImage.image = UIImage(named: "DefaultAvatar")
}
}
func setupAvPlayer(){
/*
Av Player Setup
*/
guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{
2024-08-19 23:43:40 +05:30
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}
2024-08-19 23:43:40 +05:30
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
2024-08-19 23:43:40 +05:30
playerLayer.frame = vc.liveTvView.bounds
vc.liveTvView.layer.addSublayer(playerLayer)
vc.liveTvView.bringSubviewToFront(vc.liveTVActivityIndicator)
vc.liveTvView.layoutIfNeeded()
avPlayer.play()
avPlayer.volume = 0
2024-08-19 23:43:40 +05:30
//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(){
2024-08-08 18:47:13 +05:30
// 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
}
}
2024-08-19 23:43:40 +05:30
// 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
}
}