PublishVideoView.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. //
  2. // PublishVideoView.swift
  3. // RainbowPlanet
  4. //
  5. // Created by Christopher on 2019/6/19.
  6. // Copyright © 2019 RainbowPlanet. All rights reserved.
  7. //
  8. import UIKit
  9. import RxSwift
  10. import RxCocoa
  11. import JXSegmentedView
  12. enum BtnActionType {
  13. case back // 返回
  14. case reverse // 翻转
  15. case music // 音乐
  16. case filter // 滤镜
  17. case delete // 回删
  18. case confirm // 确定
  19. }
  20. class PublishVideoView: BaseView {
  21. typealias BtnClickClosure = (_ btnType: BtnActionType) -> Void
  22. var btnClickClosure : BtnClickClosure?
  23. typealias VideoClosure = (_ isRecord: Int) -> Void
  24. var videoClosure : VideoClosure?
  25. var maxDuration: CGFloat? {
  26. didSet {
  27. progressView.maxDuration = maxDuration!
  28. }
  29. }
  30. var minDuration: CGFloat? {
  31. didSet {
  32. progressView.minDuration = minDuration!
  33. }
  34. }
  35. // 是否正在录制
  36. @objc var recording: Bool = false
  37. override func setupViews() {
  38. self.backgroundColor = kffffffColor
  39. addSubview(progressView)
  40. addSubview(backButton)
  41. addSubview(recordButton)
  42. addSubview(segmentedView)
  43. addSubview(controlBackView)
  44. controlBackView.addSubview(reverseButton)
  45. controlBackView.addSubview(musicButton)
  46. controlBackView.addSubview(filterButton)
  47. addSubview(timeBackView)
  48. timeBackView.addSubview(timeDotView)
  49. timeBackView.addSubview(timeLabel)
  50. addSubview(selBackView)
  51. selBackView.addSubview(confirmButton)
  52. selBackView.addSubview(delButton)
  53. addSubview(previewView)
  54. insertSubview(previewView, at: 0)
  55. }
  56. override func setupLayouts() {
  57. backButton.snp.makeConstraints { (make) in
  58. make.top.equalTo(55)
  59. make.left.equalTo(5)
  60. make.width.equalTo(40)
  61. make.height.equalTo(40)
  62. }
  63. recordButton.snp.makeConstraints { (make) in
  64. make.bottom.equalTo(-56)
  65. make.centerX.equalToSuperview()
  66. make.width.equalTo(100)
  67. make.height.equalTo(100)
  68. }
  69. segmentedView.snp.makeConstraints { (make) in
  70. make.height.equalTo(40)
  71. make.left.equalTo(14)
  72. make.right.equalTo(-14)
  73. make.bottom.equalTo(recordButton.snp.top).offset(-21)
  74. }
  75. /***** 翻转、音乐、滤镜 *****/
  76. controlBackView.snp.makeConstraints { (make) in
  77. make.top.equalTo(64)
  78. make.right.equalTo(-15)
  79. make.width.equalTo(44)
  80. }
  81. reverseButton.snp.makeConstraints { (make) in
  82. make.top.left.right.equalToSuperview()
  83. make.height.equalTo(46)
  84. }
  85. reverseButton.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.top, imageTitleSpace: 4)
  86. musicButton.snp.makeConstraints { (make) in
  87. make.top.equalTo(reverseButton.snp.bottom).offset(20)
  88. make.left.right.equalToSuperview()
  89. make.height.equalTo(46)
  90. }
  91. musicButton.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.top, imageTitleSpace: 4)
  92. filterButton.snp.makeConstraints { (make) in
  93. make.top.equalTo(musicButton.snp.bottom).offset(20)
  94. make.left.right.equalToSuperview()
  95. make.height.equalTo(46)
  96. make.bottom.equalToSuperview()
  97. }
  98. filterButton.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.top, imageTitleSpace: 4)
  99. /***** 拍摄时长 *****/
  100. timeBackView.snp.makeConstraints { (make) in
  101. make.bottom.equalTo(recordButton.snp.top).offset(-20)
  102. make.centerX.equalToSuperview()
  103. make.height.equalTo(20)
  104. }
  105. timeDotView.snp.makeConstraints { (make) in
  106. make.left.equalToSuperview()
  107. make.centerY.equalToSuperview()
  108. make.size.equalTo(8)
  109. }
  110. timeLabel.snp.makeConstraints { (make) in
  111. make.left.equalTo(timeDotView.snp.right).offset(4)
  112. make.top.bottom.equalToSuperview()
  113. make.width.equalTo(40)
  114. make.right.equalToSuperview()
  115. }
  116. /***** 回删、确定 *****/
  117. selBackView.snp.makeConstraints { (make) in
  118. make.bottom.equalTo(-83)
  119. make.right.equalTo(-24*kScaleWidth)
  120. make.height.equalTo(50)
  121. }
  122. confirmButton.snp.makeConstraints { (make) in
  123. make.top.bottom.right.equalToSuperview()
  124. make.width.equalTo(30)
  125. }
  126. confirmButton.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.top, imageTitleSpace: 4)
  127. delButton.snp.makeConstraints { (make) in
  128. make.right.equalTo(confirmButton.snp.left).offset(-30*kScaleWidth)
  129. make.top.bottom.equalToSuperview()
  130. make.width.equalTo(30)
  131. make.left.equalToSuperview()
  132. }
  133. delButton.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.top, imageTitleSpace: 4)
  134. /***** 预览视图 *****/
  135. previewView.snp.makeConstraints { (make) in
  136. make.edges.equalToSuperview()
  137. }
  138. }
  139. // MARK: - 创建视图控件
  140. //1.初始化JXSegmentedViewx
  141. lazy var segmentedView: JXSegmentedView = {
  142. let segmentedView = JXSegmentedView()
  143. segmentedView.delegate = self
  144. segmentedView.dataSource = segmentedDataSource
  145. segmentedView.selectItemAt(index: 2)
  146. segmentedView.defaultSelectedIndex = 2
  147. segmentedView.backgroundColor = kRGBAColor(r: 0, g: 0, b: 0, a: 0.2)
  148. segmentedView.cornerRadius = 20
  149. segmentedView.masksToBounds = true
  150. return segmentedView
  151. }()
  152. //2.初始化dataSource
  153. private lazy var segmentedDataSource: JXSegmentedTitleDataSource = {
  154. let segmentedDataSource = JXSegmentedTitleDataSource()
  155. segmentedDataSource.isTitleColorGradientEnabled = true
  156. segmentedDataSource.isItemSpacingAverageEnabled = true
  157. segmentedDataSource.isTitleZoomEnabled = true
  158. segmentedDataSource.titleNormalColor = kffffffColor
  159. segmentedDataSource.titleSelectedColor = k333333Color
  160. segmentedDataSource.titleNormalFont = kRegularFont14!
  161. segmentedDataSource.titleSelectedFont = kBoldFont22
  162. segmentedDataSource.titles = ["极慢","慢","标准","快","极快"]
  163. //reloadData(selectedIndex:)方法一定要调用,方法内部会刷新数据源数组
  164. segmentedDataSource.reloadData(selectedIndex: 2)
  165. return segmentedDataSource
  166. }()
  167. //3.初始化指示器indicator
  168. private lazy var indicator: JXSegmentedIndicatorBackgroundView = {
  169. let indicator = JXSegmentedIndicatorBackgroundView()
  170. // indicator.indicatorColors = [k62CC74Color,.white,.white]
  171. indicator.indicatorHeight = 40
  172. return indicator
  173. }()
  174. lazy var backButton: UIButton = {
  175. let backButton = UIButton(type: UIButton.ButtonType.custom)
  176. backButton.setImage(kImage(name: "video_btn_close_white"), for: UIControl.State.normal)
  177. backButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  178. if let btnClickClosure = self?.btnClickClosure {
  179. btnClickClosure(BtnActionType.back)
  180. }
  181. }).disposed(by: disposeBag)
  182. return backButton
  183. }()
  184. // MARK:放置"翻转、音乐、滤镜"のView
  185. lazy var controlBackView: UIView = {
  186. let controlBackView = UIView()
  187. return controlBackView
  188. }()
  189. private lazy var reverseButton: UIButton = {
  190. let reverseButton = UIButton(type: UIButton.ButtonType.custom)
  191. reverseButton.setImage(kImage(name: "video_ico_overturn"), for: UIControl.State.normal)
  192. reverseButton.setTitle("翻转", for: UIControl.State.normal)
  193. reverseButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
  194. reverseButton.titleLabel?.font = kRegularFont12
  195. reverseButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  196. if let btnClickClosure = self?.btnClickClosure {
  197. btnClickClosure(BtnActionType.reverse)
  198. }
  199. }).disposed(by: disposeBag)
  200. return reverseButton
  201. }()
  202. private lazy var musicButton: UIButton = {
  203. let musicButton = UIButton(type: UIButton.ButtonType.custom)
  204. musicButton.setImage(kImage(name: "video_ico_music"), for: UIControl.State.normal)
  205. musicButton.setTitle("音乐", for: UIControl.State.normal)
  206. musicButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
  207. musicButton.titleLabel?.font = kRegularFont12
  208. musicButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  209. if let btnClickClosure = self?.btnClickClosure {
  210. btnClickClosure(BtnActionType.music)
  211. }
  212. }).disposed(by: disposeBag)
  213. return musicButton
  214. }()
  215. private lazy var filterButton: UIButton = {
  216. let filterButton = UIButton(type: UIButton.ButtonType.custom)
  217. filterButton.setImage(kImage(name: "video_ico_filter"), for: UIControl.State.normal)
  218. filterButton.setTitle("滤镜", for: UIControl.State.normal)
  219. filterButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
  220. filterButton.titleLabel?.font = kRegularFont12
  221. filterButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  222. if let btnClickClosure = self?.btnClickClosure {
  223. btnClickClosure(BtnActionType.filter)
  224. }
  225. }).disposed(by: disposeBag)
  226. return filterButton
  227. }()
  228. // MARK:放置"拍摄时长Label"のView
  229. lazy var timeBackView: UIView = {
  230. let timeBackView = UIView()
  231. return timeBackView
  232. }()
  233. private lazy var timeDotView: UIView = {
  234. let timeDotView = UIView()
  235. timeDotView.backgroundColor = kFF5E5EColor
  236. timeDotView.cornerRadius = 4
  237. timeDotView.masksToBounds = true
  238. return timeDotView
  239. }()
  240. private lazy var timeLabel: UILabel = {
  241. let timeLabel = UILabel()
  242. timeLabel.textColor = kffffffColor
  243. timeLabel.font = kRegularFont14
  244. timeLabel.textAlignment = .left
  245. timeLabel.numberOfLines = 1
  246. return timeLabel
  247. }()
  248. // MARK:放置"回删、确定"のView
  249. lazy var selBackView: UIView = {
  250. let selBackView = UIView()
  251. return selBackView
  252. }()
  253. private lazy var delButton: UIButton = {
  254. let delButton = UIButton(type: UIButton.ButtonType.custom)
  255. delButton.setImage(kImage(name: "video_btn_delete"), for: UIControl.State.normal)
  256. delButton.setTitle("回删", for: UIControl.State.normal)
  257. delButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
  258. delButton.titleLabel?.font = kRegularFont12
  259. delButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  260. if let btnClickClosure = self?.btnClickClosure {
  261. btnClickClosure(BtnActionType.delete)
  262. }
  263. }).disposed(by: disposeBag)
  264. return delButton
  265. }()
  266. private lazy var confirmButton: UIButton = {
  267. let confirmButton = UIButton(type: UIButton.ButtonType.custom)
  268. confirmButton.setImage(kImage(name: "video_btn_submit"), for: UIControl.State.normal)
  269. confirmButton.setTitle("确定", for: UIControl.State.normal)
  270. confirmButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
  271. confirmButton.titleLabel?.font = kRegularFont12
  272. confirmButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  273. if let btnClickClosure = self?.btnClickClosure {
  274. btnClickClosure(BtnActionType.confirm)
  275. }
  276. }).disposed(by: disposeBag)
  277. return confirmButton
  278. }()
  279. // MARK:progressView
  280. lazy var progressView: QUProgressView = {
  281. let progressView = QUProgressView(frame: CGRect(x: 14, y: kSafeStatusBarHeight-20+40, width: kScreenWidth-28, height: 5))
  282. progressView.showBlink = false
  283. progressView.showNoticePoint = true
  284. progressView.backgroundColor = kRGBAColor(r: 0/255.0, g: 0/255.0, b: 0/255.0, a: 0.3)
  285. progressView.cornerRadius = 2
  286. progressView.masksToBounds = true
  287. progressView.colorProgress = kffffffColor
  288. progressView.colorNotice = UIColor.red
  289. progressView.colorSepatorPoint = k62CC74Color
  290. return progressView
  291. }()
  292. // MARK:录制のButton
  293. private lazy var recordButton: UIButton = {
  294. let recordButton = UIButton(type: UIButton.ButtonType.custom)
  295. recordButton.setImage(kImage(name: "video_btn_shoot"), for: UIControl.State.normal)
  296. recordButton.setImage(kImage(name: "video_btn_pause"), for: UIControl.State.selected)
  297. recordButton.rx.tap.subscribe(onNext: { [weak self] (data) in
  298. recordButton.isSelected = !recordButton.isSelected
  299. if let videoClosure = self?.videoClosure {
  300. let isRecord: Int = recordButton.isSelected == true ? 1 : 0
  301. videoClosure(isRecord)
  302. }
  303. }).disposed(by: disposeBag)
  304. return recordButton
  305. }()
  306. // MARK:预览View
  307. lazy var previewView: UIView = {
  308. let previewView = UIView()
  309. return previewView
  310. }()
  311. }
  312. // MARK: - 视图状态处理
  313. extension PublishVideoView {
  314. // 刷新进度条进度
  315. func recordingPercent(percent: CGFloat) {
  316. progressView.updateProgress(percent)
  317. // if recording {
  318. let d: Int = Int(percent)
  319. let m: Int = Int(d / 60)
  320. let s: Int = Int(d % 60)
  321. timeLabel.text = String(format: "%02d:%02d", m, s)
  322. // }
  323. if percent == 0 {
  324. progressView.reset()
  325. timeLabel.text = ""
  326. }
  327. }
  328. /**
  329. * 显示默认视图
  330. */
  331. func preRecordViewShow() {
  332. backButton.isHidden = false
  333. recordButton.isHidden = false
  334. progressView.isHidden = false
  335. controlBackView.isHidden = false
  336. segmentedView.isHidden = false
  337. timeBackView.isHidden = true
  338. selBackView.isHidden = true
  339. }
  340. /**
  341. * 显示正在拍摄视图
  342. */
  343. func recordingViewShow() {
  344. backButton.isHidden = false
  345. recordButton.isHidden = false
  346. progressView.isHidden = false
  347. controlBackView.isHidden = true
  348. segmentedView.isHidden = true
  349. timeBackView.isHidden = false
  350. selBackView.isHidden = true
  351. }
  352. /**
  353. * 显示暂停拍摄视图
  354. */
  355. func pauseViewShow() {
  356. backButton.isHidden = false
  357. recordButton.isHidden = false
  358. progressView.isHidden = false
  359. controlBackView.isHidden = false
  360. segmentedView.isHidden = false
  361. timeBackView.isHidden = true
  362. selBackView.isHidden = false
  363. }
  364. /**
  365. * 显示编辑音乐视图
  366. */
  367. func editMusicViewShow() {
  368. backButton.isHidden = true
  369. recordButton.isHidden = true
  370. progressView.isHidden = true
  371. controlBackView.isHidden = true
  372. segmentedView.isHidden = true
  373. selBackView.isHidden = true
  374. }
  375. }
  376. extension PublishVideoView : JXSegmentedViewDelegate {
  377. // 点击选中的情况才会调用该方法
  378. func segmentedView(_ segmentedView: JXSegmentedView, didClickSelectedItemAt index: Int) {
  379. print("----选中\(index)")
  380. }
  381. /// 是否允许点击选中目标index的item
  382. func segmentedView(_ segmentedView: JXSegmentedView, canClickItemAt index: Int) -> Bool {
  383. return true
  384. }
  385. }