MVPlayViewController.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. //
  2. // MVPlayViewController.swift
  3. // MusicVideoPlus
  4. //
  5. // Created by SanW on 2021/6/22.
  6. //
  7. import BFFramework
  8. import UIKit
  9. import WechatOpenSDK
  10. class MVPlayViewController: PQBaseViewController {
  11. var itemsList: [PQVideoListModel] = Array<PQVideoListModel>.init()
  12. var pageNum: Int = 1
  13. var currentIndex: IndexPath?
  14. var currentActionBtn: UIButton? // 记录上次点击按钮
  15. var currentVideoData: PQVideoListModel? // 记录上次点击数据
  16. var isRequesting: Bool = false // 是否正在请求数据
  17. var isPlayEnd: Bool = false // 是否播放结束
  18. lazy var leftBtn: UIButton = {
  19. let leftBtn = UIButton(type: .custom)
  20. leftBtn.frame = CGRect(x: 0, y: cDevice_iPhoneStatusBarHei, width: cDefaultMargin * 4, height: cDefaultMargin * 4)
  21. leftBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -5, right: 0)
  22. leftBtn.tintColor = UIColor.white
  23. leftBtn.setImage(UIImage().BF_Image(named: "icon_detail_back").withRenderingMode(.alwaysTemplate), for: .normal)
  24. leftBtn.addTarget(self, action: #selector(backBtnClick), for: .touchUpInside)
  25. return leftBtn
  26. }()
  27. lazy var collectionView: UICollectionView = {
  28. let layout = UICollectionViewFlowLayout()
  29. layout.minimumLineSpacing = 0
  30. layout.sectionInset = UIEdgeInsets.zero
  31. layout.minimumInteritemSpacing = 0
  32. layout.itemSize = view.frame.size
  33. let collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
  34. collectionView.scrollsToTop = false
  35. collectionView.isPagingEnabled = true
  36. collectionView.showsVerticalScrollIndicator = false
  37. collectionView.register(MVPlayControlViewCell.self, forCellWithReuseIdentifier: String(describing: MVPlayControlViewCell.self))
  38. collectionView.delegate = self
  39. collectionView.dataSource = self
  40. if #available(iOS 11.0, *) {
  41. collectionView.contentInsetAdjustmentBehavior = .never
  42. } else {
  43. automaticallyAdjustsScrollViewInsets = false
  44. }
  45. collectionView.addRefreshView(type: .REFRESH_TYPE_HEADER) { [weak self] isRefresh in
  46. self?.loadRequestData(isRefresh: isRefresh)
  47. }
  48. // MJRefreshBackNormalFooter 不会附在上面
  49. // MJRefreshAutoFooter 不会便宜
  50. let footer = MJRefreshBackNormalFooter.init {[weak self] in
  51. self?.loadRequestData(isRefresh: false)
  52. }
  53. footer.setTitle("暂时没有更多了", for: .noMoreData)
  54. footer.setTitle("精彩内容正在加载中...", for: .refreshing)
  55. collectionView.mj_footer = footer
  56. return collectionView
  57. }()
  58. override func viewDidLoad() {
  59. super.viewDidLoad()
  60. PQSingletoVideoPlayer.shared.stopPlayer()
  61. view.addSubview(collectionView)
  62. view.addSubview(leftBtn)
  63. if itemsList.count <= 0 {
  64. loadRequestData()
  65. }
  66. if currentIndex != nil, itemsList.count > (currentIndex?.item ?? 0) {
  67. collectionView.contentOffset = CGPoint(x: 0, y: CGFloat(currentIndex?.item ?? 0) * view.frame.size.height)
  68. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { [weak self] in
  69. self?.scrollViewDidEndDecelerating(self!.collectionView)
  70. }
  71. }
  72. PQSingletoVideoPlayer.shared.playStatusBloc = { [weak self] status in
  73. if status == .PQVIDEO_PLAY_STATUS_END {
  74. self?.isPlayEnd = true
  75. if ((self?.currentIndex?.item ?? 0) + 1) < (self?.itemsList.count ?? 0) {
  76. // self?.collectionView.scrollToItem(at: IndexPath(item: (self?.currentIndex?.item ?? 0) + 1, section: 0), at: .top, animated: false)
  77. self?.collectionView.contentOffset = CGPoint(x: 0, y: CGFloat((self?.currentIndex?.item ?? 0) + 1) * (self!.collectionView.frame.height))
  78. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { [weak self] in
  79. self?.scrollViewDidEndDecelerating(self!.collectionView)
  80. }
  81. } else {
  82. (self?.collectionView.visibleCell() as? MVPlayControlViewCell)?.tagClick()
  83. self?.loadRequestData(isRefresh: false)
  84. }
  85. if (self?.currentIndex?.item ?? 0) >= ((self?.itemsList.count ?? 0) - 2) {
  86. self?.loadRequestData(isRefresh: false)
  87. }
  88. }else if status == .PQVIDEO_PLAY_STATUS_BEGIN{
  89. self?.isPlayEnd = false
  90. }
  91. }
  92. PQSingletoVideoPlayer.shared.progressBloc = { [weak self] _, playProgress, duration in
  93. (self?.collectionView.visibleCell() as? MVPlayControlViewCell)?.updateProgress(progress: playProgress / duration)
  94. }
  95. PQNotification.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)
  96. PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
  97. PQNotification.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
  98. }
  99. override func viewDidAppear(_ animated: Bool) {
  100. super.viewDidAppear(animated)
  101. PQSingletoVideoPlayer.shared.resumePlayer()
  102. }
  103. override func viewDidDisappear(_ animated: Bool) {
  104. super.viewDidDisappear(animated)
  105. PQSingletoVideoPlayer.shared.pausePlayer()
  106. }
  107. /// 请求网络数据
  108. /// - Parameter isRefresh: <#isRefresh description#>
  109. /// - Returns: <#description#>
  110. func loadRequestData(isRefresh: Bool = true,isAutoPlay:Bool = false) {
  111. if isRequesting {
  112. return
  113. }
  114. isRequesting = true
  115. if isRefresh {
  116. pageNum = 1
  117. } else {
  118. pageNum = pageNum + 1
  119. }
  120. MVMineViewModel.userVideoListData(pageNum: pageNum) { [weak self] videoList, _ in
  121. self?.isRequesting = false
  122. if videoList != nil, (videoList?.count ?? 0) > 0 {
  123. if isRefresh {
  124. self?.itemsList = videoList!
  125. } else {
  126. self?.itemsList = self!.itemsList + videoList!
  127. }
  128. self?.collectionView.reloadData()
  129. if self?.currentIndex == nil {
  130. self?.scrollViewDidEndDecelerating(self!.collectionView)
  131. }else if (self?.isPlayEnd ?? false), ((self?.currentIndex?.item ?? 0) + 1) < (self?.itemsList.count ?? 0) {
  132. self?.collectionView.contentOffset = CGPoint(x: 0, y: CGFloat((self?.currentIndex?.item ?? 0) + 1) * (self!.collectionView.frame.height))
  133. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { [weak self] in
  134. self?.scrollViewDidEndDecelerating(self!.collectionView)
  135. }
  136. }
  137. } else {
  138. self?.pageNum = (self?.pageNum ?? 1) - 1
  139. }
  140. // if isRefresh {
  141. // self?.collectionView.mj_header?.endRefreshing()
  142. // self?.collectionView.mj_footer?.resetNoMoreData()
  143. // } else {
  144. // self?.collectionView.mj_footer?.endRefreshing()
  145. // }
  146. // if (videoList?.count ?? 0) < 20 && videoList != nil {
  147. // self?.collectionView.mj_footer?.endRefreshingWithNoMoreData()
  148. // }
  149. }
  150. }
  151. deinit {
  152. PQNotification.removeObserver(self)
  153. PQSingletoVideoPlayer.shared.stopPlayer()
  154. }
  155. }
  156. extension MVPlayViewController: UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate {
  157. func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
  158. return itemsList.count
  159. }
  160. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  161. let itemData = itemsList[indexPath.item]
  162. let cell = MVPlayControlViewCell.playControlCell(collectionView: collectionView, indexPath: indexPath)
  163. cell.videoData = itemData
  164. cell.btnClickHandle = { [weak self] sender, videoData in
  165. self?.btnClickHandle(sender: sender, videoData: videoData)
  166. }
  167. return cell
  168. }
  169. func collectionView(_: UICollectionView, didSelectItemAt _: IndexPath) {}
  170. func scrollViewDidEndDecelerating(_: UIScrollView) {
  171. if itemsList.count <= 0 {
  172. PQSingletoVideoPlayer.shared.stopPlayer()
  173. return
  174. }
  175. let cell: MVPlayControlViewCell? = collectionView.visibleCell() as? MVPlayControlViewCell
  176. if cell == nil {
  177. return
  178. }
  179. let indexPath = collectionView.indexPath(for: cell!)
  180. if currentIndex != nil, currentIndex?.item == indexPath?.item,PQSingletoVideoPlayer.shared.playControllerView != nil {
  181. // PQSingletoVideoPlayer.shared.resumePlayer()
  182. return
  183. }
  184. currentIndex = indexPath
  185. let itemData = itemsList[indexPath?.item ?? 0]
  186. itemData.playProgress = 0
  187. cell?.pauseBtn.isSelected = false
  188. PQSingletoVideoPlayer.shared.configPlyer(videoData: itemData, controllerView: cell!.coverImageView, renderMode: .RENDER_MODE_FILL_EDGE)
  189. PQSingletoVideoPlayer.shared.resetPlayer()
  190. if (indexPath?.item ?? 0) >= itemsList.count - 2 {
  191. loadRequestData(isRefresh: false)
  192. }
  193. }
  194. /// 按钮点击处理
  195. /// - Parameters:
  196. /// - sender: <#sender description#>
  197. /// - videoData: <#videoData description#>
  198. /// - Returns: <#description#>
  199. func btnClickHandle(sender: UIButton, videoData: PQVideoListModel?) {
  200. switch sender.tag {
  201. case 1: // 暂停/播放
  202. if sender.isSelected {
  203. PQSingletoVideoPlayer.shared.pausePlayer()
  204. } else {
  205. PQSingletoVideoPlayer.shared.resumePlayer()
  206. }
  207. case 2: // 昵称
  208. break
  209. case 3: // 做同款
  210. let navVc: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController) as? UINavigationController
  211. (navVc?.viewControllers.first as? MVHomeController)?.jumpToDetailVc(type: 2, videoData: videoData)
  212. case 4: // 分享好友
  213. if !PQSingletoWXApiUtil.shared.isInstallWX() {
  214. cShowHUB(superView: nil, msg: "您还未安装微信客户端!")
  215. return
  216. }
  217. cShowHUB(superView: nil, msg: nil)
  218. let shareId = getUniqueId(desc: "\(videoData?.uniqueId ?? "")shareId")
  219. PQBaseViewModel.wxFriendShareInfo(videoId: (videoData?.uniqueId)!) { [weak self] imagePath, title, shareWeappRawId, msg in
  220. if msg != nil {
  221. cShowHUB(superView: nil, msg: "网络不佳哦")
  222. return
  223. }
  224. PQSingletoWXApiUtil.shared.share(type: 3, scene: Int32(WXSceneSession.rawValue), shareWeappRawId: shareWeappRawId, title: title, description: title, imageUrl: imagePath, path: videoData?.videoPath, videoId: (videoData?.uniqueId)!, pageSource: videoData?.pageSource ?? .sp_category, shareId: shareId).wxApiUtilHander = { _, _ in
  225. self?.currentActionBtn = sender
  226. self?.currentVideoData = videoData
  227. }
  228. cHiddenHUB(superView: nil)
  229. }
  230. case 5: // 分享朋友圈
  231. if !PQSingletoWXApiUtil.shared.isInstallWX() {
  232. cShowHUB(superView: nil, msg: "您还未安装微信客户端!")
  233. return
  234. }
  235. let shareId = getUniqueId(desc: "\(videoData?.uniqueId ?? "")shareId")
  236. PQBaseViewModel.h5ShareLinkInfo(videoId: videoData?.uniqueId ?? "", pageSource: videoData?.pageSource ?? .sp_category) { [weak self] path, _ in
  237. cHiddenHUB(superView: nil)
  238. if path != nil {
  239. PQSingletoWXApiUtil.shared.share(type: 1, scene: Int32(WXSceneTimeline.rawValue), title: BFLoginUserInfo.shared.isLogin() ? "\(BFLoginUserInfo.shared.nickName)made a music video for you" : "Music Video for U", description: "", imageUrl: videoData?.shareImgPath, path: path, videoId: (videoData?.uniqueId)!, pageSource: videoData?.pageSource ?? .sp_category, shareId: shareId).wxApiUtilHander = { _, _ in
  240. self?.currentActionBtn = sender
  241. self?.currentVideoData = videoData
  242. }
  243. } else {
  244. cShowHUB(superView: nil, msg: "网络不佳哦")
  245. }
  246. }
  247. default:
  248. break
  249. }
  250. }
  251. @objc func didBecomeActiveNotification() {
  252. if currentActionBtn != nil {
  253. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
  254. cShowHUB(superView: nil, msg: "分享成功")
  255. }
  256. if currentActionBtn?.tag == 4 {
  257. if currentVideoData?.shareCountFriend != nil, currentVideoData?.shareCountFriend ?? 0 > 0 {
  258. currentVideoData?.shareCountFriend = (currentVideoData?.shareCountFriend ?? 0) + 1
  259. } else {
  260. currentVideoData?.shareCountFriend = 1
  261. }
  262. } else if currentActionBtn?.tag == 5 {
  263. if currentVideoData?.shareCount != nil, currentVideoData?.shareCount ?? 0 > 0 {
  264. currentVideoData?.shareCount = (currentVideoData?.shareCount ?? 0) + 1
  265. } else {
  266. currentVideoData?.shareCount = 1
  267. }
  268. }
  269. currentActionBtn = nil
  270. currentVideoData = nil
  271. collectionView.reloadData()
  272. }
  273. }
  274. @objc func enterBackground() {
  275. BFLog(message: "进入到后台")
  276. let navVc: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController) as? UINavigationController
  277. if navVc?.visibleViewController is MVPlayViewController {
  278. (collectionView.visibleCell() as? MVPlayControlViewCell)?.pauseBtn.isSelected = true
  279. PQSingletoVideoPlayer.shared.stopPlayer(isRemove: false)
  280. }
  281. }
  282. @objc func willEnterForeground() {
  283. BFLog(message: "进入到前台")
  284. let navVc: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController) as? UINavigationController
  285. if navVc?.visibleViewController is MVPlayViewController {
  286. (collectionView.visibleCell() as? MVPlayControlViewCell)?.pauseBtn.isSelected = false
  287. PQSingletoVideoPlayer.shared.startPlayr()
  288. }
  289. }
  290. override open var preferredStatusBarStyle: UIStatusBarStyle {
  291. return .lightContent
  292. }
  293. }