INIntroduceController.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. //
  2. // INIntrocudeController.swift
  3. // Introduce
  4. //
  5. // Created by 胡志强 on 2021/11/29.
  6. // 制作录音,预览页面
  7. import BFCommonKit
  8. import BFRecordScreenKit
  9. import Foundation
  10. import Photos
  11. import UIKit
  12. import BFAnalyzeKit
  13. import BFUIKit
  14. class INIntroduceController: BFBaseViewController {
  15. lazy var stripSwithView : BFStripSwithView = {
  16. let v = BFStripSwithView(frame: .zero, items: 0, space: 4)
  17. v.itemClickHandle = { [weak self] _, index in
  18. guard let wself = self else { return }
  19. wself.recordScreenVC.updateContentOffset(index: index)
  20. }
  21. return v
  22. }()
  23. let exportBtn = UIButton()
  24. var assets: [PHAsset]?
  25. let recordUid = getRandomStringOfLength(length: 16)
  26. let recordScreenVC = BFRecordScreenController()
  27. lazy var addMaterialBtn : UIButton = {
  28. let btn = UIButton()
  29. btn.setImage(UIImage(named: "dl_add"), for: .normal)
  30. btn.addTarget(self, action: #selector(addmaterial), for: .touchUpInside)
  31. return btn
  32. }()
  33. // MARK: - VC生命周期
  34. override func viewWillAppear(_ animated: Bool) {
  35. super.viewWillAppear(animated)
  36. showNavigation()
  37. PQNotification.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
  38. PQNotification.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
  39. }
  40. override func viewWillDisappear(_ animated: Bool) {
  41. super.viewWillDisappear(animated)
  42. PQNotification.removeObserver(self)
  43. cHiddenHUB(superView: nil)
  44. }
  45. @objc internal func keyboardWillHide(_: Notification?) {
  46. navHeadImageView?.isHidden = false
  47. }
  48. @objc internal func keyboardWillShow(_: Notification?) {
  49. navHeadImageView?.isHidden = true
  50. }
  51. override func viewDidLoad() {
  52. super.viewDidLoad()
  53. navHeadImageView?.backgroundColor = .clear
  54. navHeadImageView?.image = UIImage(named: "top_shadow")
  55. navHeadImageView?.contentMode = .scaleToFill
  56. leftButton(image: nil, imageName: nil, tintColor: .white)
  57. exportBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#389AFF")
  58. exportBtn.setTitle("option_export".BFLocale, for: .normal)
  59. exportBtn.addCorner(corner: 4)
  60. exportBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
  61. exportBtn.addTarget(self, action: #selector(exportAction), for: .touchUpInside)
  62. navHeadImageView?.addSubview(exportBtn)
  63. exportBtn.frame = CGRect(x: (navHeadImageView?.frame.width ?? 0) - 12 - 60, y: 0, width: 60, height: 36)
  64. exportBtn.center.y = backButton?.center.y ?? 0
  65. exportBtn.titleLabel?.adjustsFontSizeToFitWidth = true
  66. addChild(recordScreenVC)
  67. recordScreenVC.view.frame = view.frame
  68. view.addSubview(recordScreenVC.view)
  69. if let ass = assets {
  70. recordScreenVC.fetchMaterial(ass)
  71. }
  72. recordScreenVC.cleanScreen = {[weak self] ishiddenNav in
  73. guard let wself = self else { return }
  74. wself.navHeadImageView?.isHidden = ishiddenNav
  75. }
  76. recordScreenVC.changeItemHandle = { [weak self] index in
  77. guard let wself = self else { return }
  78. // 删除了一条
  79. if index == -3 {
  80. wself.resetStripSwithView(wself.recordScreenVC.itemModels.count)
  81. }else{
  82. wself.stripSwithView.changeSwitchStatus(index: index)
  83. }
  84. }
  85. recordScreenVC.recordEndHandle = {model in
  86. // 录音完成时上报
  87. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_speekButton, pageSource: .sp_speekPage,extParams: ["duration":Int(((model?.endCMTime.seconds ?? 0) - (model?.startCMTime.seconds ?? 0)) * 1000)],commonParams: commonParams())
  88. }
  89. recordScreenVC.subTitleBtnClickHandle = { isOn in
  90. // 点击字幕按钮上报
  91. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_captionsButton, pageSource: .sp_speekPage,extParams: ["isSubtitlesClose":isOn],commonParams: commonParams())
  92. }
  93. recordScreenVC.voiceBtnClickHandle = { voice in
  94. if(voice != nil){
  95. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_voiceChangerButton, pageSource: .sp_speekPage,extParams: ["voiceMode":voice?.voice ?? ""],commonParams: commonParams())
  96. }
  97. }
  98. navHeadImageView?.addSubview(stripSwithView)
  99. navHeadImageView?.addSubview(addMaterialBtn)
  100. stripSwithView.snp.makeConstraints { make in
  101. make.left.equalTo(backButton!.snp.right).offset(5)
  102. make.top.height.equalTo(backButton!)
  103. if (assets?.count ?? 0) > 1 {
  104. make.width.equalTo(cScreenWidth).priority(.high)
  105. }else{
  106. make.width.equalTo(0).priority(.high)
  107. }
  108. }
  109. addMaterialBtn.snp.makeConstraints { make in
  110. make.left.equalTo(stripSwithView.snp.right).offset(-2)
  111. make.top.height.equalTo(backButton!)
  112. if (assets?.count ?? 0) < 20 {
  113. make.width.equalTo(addMaterialBtn.snp.height)
  114. }else {
  115. make.width.equalTo(0)
  116. }
  117. make.right.lessThanOrEqualTo(exportBtn.snp.left).offset(-15)
  118. }
  119. if assets != nil, (assets?.count ?? 0) > 1 {
  120. stripSwithView.resetView(count: assets?.count ?? 0)
  121. } else if assets != nil,(assets?.count ?? 0) > 0 {
  122. // 曝光上报
  123. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_pageView, objectType: assets?.first?.mediaType == .video ? .ot_video: .ot_image, pageSource: .sp_speekPage, commonParams: commonParams())
  124. }
  125. // 已选素材上报
  126. if assets != nil ,(assets?.count ?? 0) > 0 {
  127. var materialTypeList:[String] = []
  128. assets?.forEach({ item in
  129. materialTypeList.append(item.mediaType == .video ? "video": "image")
  130. })
  131. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_pageView, objectType: .ot_addMaterialSuccess, pageSource: .sp_speekPage,extParams: ["materialTypeList":materialTypeList],commonParams: commonParams())
  132. }
  133. }
  134. // MARK: - Button action
  135. func updateAsset(_ phAssets:[PHAsset]) {
  136. recordScreenVC.fetchMaterial(phAssets)
  137. if recordScreenVC.itemModels.count >= 20 {
  138. addMaterialBtn.snp.remakeConstraints { make in
  139. make.left.equalTo(stripSwithView.snp.right).offset(-2)
  140. make.top.height.equalTo(backButton!)
  141. make.width.equalTo(0)
  142. make.right.lessThanOrEqualTo(exportBtn.snp.left).offset(-15)
  143. }
  144. }
  145. resetStripSwithView(recordScreenVC.itemModels.count)
  146. }
  147. func resetStripSwithView(_ count: Int){
  148. stripSwithView.resetView(count: count)
  149. DispatchQueue.main.async {[weak self] in
  150. guard let wself = self else { return }
  151. wself.stripSwithView.snp.updateConstraints { make in
  152. if count > 1 {
  153. make.width.equalTo(cScreenWidth).priority(.high)
  154. }else{
  155. make.width.equalTo(0).priority(.high)
  156. }
  157. }
  158. wself.stripSwithView.setNeedsLayout()
  159. wself.stripSwithView.layoutIfNeeded()
  160. }
  161. }
  162. @objc func addmaterial(){
  163. if recordScreenVC.itemModels.count >= 20{
  164. cShowHUB(superView: nil, msg: "option_tips_max20".BFLocale)
  165. return
  166. }
  167. if recordScreenVC.isNormalPlaying {
  168. recordScreenVC.pause()
  169. }
  170. let alee = BFActionSheetView()
  171. if recordScreenVC.itemModels.count > 0 && recordScreenVC.itemModels.last!.mediaType != .Camera {
  172. alee.addAction(title: "home_shoot".BFLocale, sheetStyle: .defalt) {[weak self] in
  173. guard let wself = self else { return }
  174. let phAsset = PHAsset()
  175. phAsset.title = "record.camera"
  176. wself.updateAsset([phAsset])
  177. }
  178. }
  179. alee.addAction(title: "home_choose".BFLocale, sheetStyle: .defalt) {[weak self] in
  180. guard let wself = self else { return }
  181. let vc = INPhotoVideosController()
  182. vc.maxMaterialNum = 20 - wself.recordScreenVC.itemModels.count
  183. vc.modalPresentationStyle = .fullScreen
  184. vc.nextBtnCallBack = {[weak self] phAssets in
  185. guard let wself = self else { return }
  186. wself.updateAsset(phAssets)
  187. }
  188. wself.navigationController?.present(vc, animated: true, completion: nil)
  189. }
  190. alee.addAction(title: "option_cancel".BFLocale, sheetStyle: .cancle, handler: nil)
  191. alee.show()
  192. // let alertv = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  193. // if let subview = alertv.view.subviews.first?.subviews.first?.subviews.first {
  194. // subview.backgroundColor = .black
  195. // }
  196. //
  197. // if recordScreenVC.itemModels.count > 0 && recordScreenVC.itemModels.last!.mediaType != .Camera {
  198. // let action = UIAlertAction(title: "拍摄录制", style: .default) {[weak self] action in
  199. // guard let wself = self else { return }
  200. //
  201. // let phAsset = PHAsset()
  202. // phAsset.title = "record.camera"
  203. // wself.updateAsset([phAsset])
  204. // }
  205. // alertv.addAction(action)
  206. // }
  207. //
  208. // let action1 = UIAlertAction(title: "从相册选择", style: .destructive) {[weak self] action in
  209. // guard let wself = self else { return }
  210. // let vc = INPhotoVideosController()
  211. // vc.maxMaterialNum = 20 - wself.recordScreenVC.itemModels.count
  212. // vc.modalPresentationStyle = .fullScreen
  213. // vc.nextBtnCallBack = {[weak self] phAssets in
  214. // guard let wself = self else { return }
  215. //
  216. // wself.updateAsset(phAssets)
  217. // }
  218. //
  219. // wself.navigationController?.present(vc, animated: true, completion: nil)
  220. // }
  221. // alertv.addAction(action1)
  222. //
  223. // let action2 = UIAlertAction(title: "取消", style: .cancel, handler: nil)
  224. // alertv.addAction(action2)
  225. //
  226. // self.present(alertv, animated: true, completion: nil)
  227. }
  228. override func backBtnClick() {
  229. let alertController = UIAlertController(title: "compose_tips_exit".BFLocale,
  230. message: "", preferredStyle: .alert)
  231. let cancelAction = UIAlertAction(title: "option_not exit".BFLocale, style: .default, handler: nil)
  232. let okAction = UIAlertAction(title: "option_exit".BFLocale, style: .cancel, handler: {[weak self]
  233. action in
  234. self?.recordScreenVC.backBtnClick()
  235. // self?.super_back()
  236. self?.navigationController?.popToRootViewController(animated: true)
  237. })
  238. okAction.setValue(UIColor.red, forKey:"titleTextColor")
  239. alertController.addAction(okAction)
  240. alertController.addAction(cancelAction)
  241. self.present(alertController, animated: true, completion: nil)
  242. }
  243. private func super_back() {
  244. super.backBtnClick()
  245. }
  246. @objc func exportAction() {
  247. recordScreenVC.isExportAction = true
  248. //add by ak 如果当前段有没有转完的发音人显示 Loadingview
  249. if(!recordScreenVC.voiceChangeStickerFinish(isShowLoadView: true)){
  250. return
  251. }
  252. let count = recordScreenVC.itemModels.reduce(0, { partialResult, model in
  253. model.voiceStickers.count + partialResult
  254. })
  255. if count == 0 {
  256. cShowHUB(superView: nil, msg: "compose_tips_export".BFLocale)
  257. return
  258. }
  259. recordScreenVC.pause()
  260. let controller = INVideoExportController()
  261. controller.export.data = recordScreenVC.itemModels
  262. //背景音乐
  263. controller.export.bgmModel = recordScreenVC.bgmModel
  264. controller.export.originSoundVolumn = recordScreenVC.originalVolume
  265. controller.export.originSoundInRecordVolumn = recordScreenVC.originalVolume * 0.6
  266. controller.recordUid = recordUid
  267. controller.coverIV.image = recordScreenVC.itemModels.first?.coverImg
  268. navigationController?.pushViewController(controller, animated: true)
  269. // 点击导出按钮上报
  270. BFEventTrackAdaptor.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_exportButton, pageSource: .sp_speekPage,commonParams: commonParams())
  271. }
  272. }