123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- //
- // INVideoExportController.swift
- // Introduce
- //
- // Created by 胡志强 on 2021/11/29.
- //
- import BFAnalyzeKit
- import BFCommonKit
- import BFRecordScreenKit
- import BFUIKit
- import Foundation
- import Photos
- import SwiftUI
- import UIKit
- class INVideoExportController: BFBaseViewController {
- var avplayerTimeObserver: NSKeyValueObservation?
- let backV : UIView = {
- let v = UIView()
- v.backgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
- return v
- }()
-
- let coverIV : UIImageView = {
- let iv = UIImageView()
- iv.backgroundColor = .black
- iv.alpha = 0.5
- iv.contentMode = .scaleAspectFit
- return iv
- }()
-
- var hasExportAll = false
- var hasExportOnly = false
- var hasSaveAll = false
- var hasSaveOnly = false
- var saveAllUlr = URL(fileURLWithPath: "aaa")
- var saveOnlyUlr = URL(fileURLWithPath: "aaa")
- var playViewFrame: CGRect = CGRect.zero
- var isExporting = false {
- didSet {
- if isExporting {
- avplayer.pause()
- }
- }
- }
- var enterBackgroundCancleExport = false
- // 预览播放进度
- var sliderView: BFVideoPlayerSliderView?
- // 合成进度指示条
- lazy var progressView: UIView = {
- let v = UIView()
- v.backgroundColor = ThemeStyleColor
- v.alpha = 0.5
- return v
- }()
- // 合成进度百分比lable
- lazy var progressL: UILabel = {
- let la = UILabel()
- la.textColor = .white
- la.textAlignment = .center
- la.text = "0%"
- la.font = UIFont.systemFont(ofSize: 28)
- la.shadowColor = .black
- la.shadowOffset = CGSize(width: 1, height: 1)
- return la
- }()
- // 播放进度显示
- lazy var playDurL: UILabel = {
- let la = UILabel()
- la.textAlignment = .center
- la.font = UIFont.systemFont(ofSize: 12, weight: .medium)
- la.textColor = .white
- la.layer.shadowOpacity = 0.4
- la.layer.shadowColor = UIColor.black.cgColor
- la.layer.shadowOffset = CGSize(width: 0, height: 2)
- la.layer.shadowRadius = 2
- la.text = "00:00/00:00"
- return la
- }()
-
- lazy var saveAllBtn: UIButton = {
- let btn = UIButton()
- btn.setImage(UIImage(named: "export_saveall_n"), for: .normal)
- btn.setImage(UIImage(named: "export_saveall_h"), for: .selected)
- btn.addTarget(self, action: #selector(saveAllAction(btn:)), for: .touchUpInside)
- return btn
- }()
- lazy var saveOnlyBtn: UIButton = {
- let btn = UIButton()
- btn.setImage(UIImage(named: "export_saveonly_n"), for: .normal)
- btn.setImage(UIImage(named: "export_saveonly_h"), for: .selected)
- btn.addTarget(self, action: #selector(saveOnlyAction(btn:)), for: .touchUpInside)
- return btn
- }()
- lazy var completeBtn: UIButton = {
- let btn = UIButton()
- btn.setTitle("回到首页", for: .normal)
- btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
- btn.setTitleColor(UIColor.hexColor(hexadecimal: "#6B6B6B"), for: .normal)
- btn.setTitleColor(.gray, for: .disabled)
- btn.addTarget(self, action: #selector(completeAction), for: .touchUpInside)
- btn.isHidden = true
- return btn
- }()
- lazy var saveToPhotoBtn: UIButton = {
- let btn = UIButton()
- btn.setTitle(" \("compose_save".BFLocale)", for: .normal)
- btn.setTitleColor(.white, for: .normal)
- btn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
- btn.setImage(UIImage(named: "export_btn"), for: .normal)
-
- // btn.backgroundColor = ThemeStyleColor
- btn.setBackgroundImage(UIImage(color: ThemeStyleColor), for: .normal)
- btn.setBackgroundImage(UIImage(color: UIColor.hexColor(hexadecimal: "#1C4D80")), for: .highlighted)
- btn.adjustsImageWhenHighlighted = false
- btn.adjustsImageWhenDisabled = false
- btn.isEnabled = false
- btn.alpha = 0.3
- btn.addCorner(roundingCorners: .allCorners, corner: 8)
- btn.addTarget(self, action: #selector(saveToPhotoNow), for: .touchUpInside)
- return btn
- }()
- lazy var bottomView: UIView = {
- let vv = UIView()
- vv.backgroundColor = .black
- // vv.isHidden = true
- return vv
- }()
-
- lazy var errorView : UIView = {
- let errbackV = UIView()
- errbackV.backgroundColor = .black
- errbackV.isHidden = true
-
- let titleL = UILabel()
- titleL.text = "compose_fail_compose".BFLocale
- titleL.font = UIFont.systemFont(ofSize: 36)
- titleL.textColor = .white
- titleL.textAlignment = .center
- errbackV.addSubview(titleL)
-
- let subTitleL = UILabel()
- subTitleL.text = "compose_retry4".BFLocale
- subTitleL.tag = 33000
- subTitleL.font = UIFont.systemFont(ofSize: 24)
- subTitleL.textColor = UIColor.hexColor(hexadecimal: "#A6A6A6")
- subTitleL.textAlignment = .center
- subTitleL.contentCompressionResistancePriority(for: NSLayoutConstraint.Axis.horizontal)
- subTitleL.numberOfLines = 0
- errbackV.addSubview(subTitleL)
-
- let retryBtn = UIButton()
- retryBtn.backgroundColor = ThemeStyleColor
- retryBtn.setTitle("compose_retry".BFLocale, for: .normal)
- retryBtn.tag = 33001
- retryBtn.setTitleColor(.white, for: .normal)
- retryBtn.addCorner(corner:5)
- retryBtn.addTarget(self, action: #selector(retryAction(sender:)), for: .touchUpInside)
- errbackV.addSubview(retryBtn)
-
- retryBtn.snp.makeConstraints { make in
- make.width.equalTo(245)
- make.height.equalTo(50)
- make.centerX.equalToSuperview()
- make.centerY.equalToSuperview().offset(10)
- }
- subTitleL.snp.makeConstraints { make in
- make.left.right.equalToSuperview()
- make.bottom.equalTo(retryBtn.snp.top).offset(-30)
- }
- titleL.snp.makeConstraints { make in
- make.left.right.equalToSuperview()
- make.height.equalTo(70)
- make.bottom.equalTo(subTitleL.snp.top)
- }
-
-
- return errbackV
- }()
- var playerLayer: AVPlayerLayer!
- lazy var avplayer: AVPlayer = {
- let avplayer = AVPlayer()
- avplayerTimeObserver = avplayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 10), queue: DispatchQueue.global()) { [weak self, weak avplayer] time in
- // 进度监控
- if let item = avplayer?.currentItem, !(self?.sliderView?.isDragingProgressSlder ?? false) {
- DispatchQueue.main.async { [weak self, weak avplayer] in
- if avplayer?.currentItem?.status != .readyToPlay {
- self?.playDurL.text = "00:00/00:00"
- self?.sliderView?.progress = 0
- }else{
- self?.playDurL.text = String(format: "%@ / %@", CMTimeGetSeconds(time).formatDurationToHMS(), CMTimeGetSeconds(item.duration).formatDurationToHMS())
- self?.sliderView?.progress = CMTimeGetSeconds(item.currentTime()) / CMTimeGetSeconds(item.duration)
- }
- }
- }
- } as? NSKeyValueObservation
- NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avplayer.currentItem, queue: .main) { [weak avplayer, weak self] _ in
- avplayer?.seek(to: CMTime.zero)
- self?.sliderView?.playEnd()
- // self?.changeToOriginalFrame()
- }
- return avplayer
- }()
- lazy var export: BFRecordExport = {
- let export = BFRecordExport()
- export.progress = { [weak self] progress in
- DispatchQueue.main.async { [weak self] in
- if let sself = self {
- // let width = export.data?.first?.width ?? 0
- sself.progressL.text = String(format: "%d%%", Int(progress * 100))
- sself.progressView.snp.updateConstraints { make in
- make.width.equalTo(sself.playerLayer.bounds.width * CGFloat(progress))
- }
- }
- }
- }
- export.exportCompletion = { [weak self] error, url in
- DispatchQueue.main.async { [weak self] in
- guard let sself = self else {
- return
- }
- UIApplication.shared.isIdleTimerDisabled = false
- sself.resetViewStatus()
- sself.coverIV.isHidden = true
- sself.progressView.snp.updateConstraints { make in
- make.width.equalTo(0)
- }
- sself.progressL.text = "0%"
- if let fileUrl = url {
- sself.sliderView?.isHidden = false
- sself.playDurL.isHidden = false
- sself.sliderView?.playStart()
- sself.completeBtn.isHidden = false
- let item = AVPlayerItem(url: fileUrl)
- sself.avplayer.replaceCurrentItem(with: item)
- usleep(1000)
- sself.avplayer.play()
- sself.playerLayer.borderColor = ThemeStyleColor.cgColor
- if sself.saveAllBtn.isSelected {
- sself.saveAllUlr = fileUrl
- sself.hasExportAll = true
- }
- if sself.saveOnlyBtn.isSelected {
- sself.saveOnlyUlr = fileUrl
- sself.hasExportOnly = true
- }
- // 添加播放进度视图
- self?.addVideoSliderView()
- }else {
- if let l = sself.errorView.viewWithTag(33000) as? UILabel, let err = error as NSError?,let b = sself.errorView.viewWithTag(33001) as? UIButton {
- switch err.code {
- case ExportError.FileNotExist.rawValue :
- l.text = "compose_fail_delete".BFLocale
- b.setTitle("compose_retry2".BFLocale, for: .normal)
- case ExportError.DiskNoSpace.rawValue :
- l.text = "compose_fail_storage".BFLocale + (err.userInfo["msg"] as! String)
- b.setTitle("compose_retry".BFLocale, for: .normal)
- case ExportError.VoiceLost.rawValue :
- l.text = "compose_fail_records".BFLocale
- b.setTitle("compose_retry".BFLocale, for: .normal)
- default:
- l.text = "compose_retry4".BFLocale
- b.setTitle("compose_retry".BFLocale, for: .normal)
- }
- l.sizeToFit()
- }
- sself.errorView.isHidden = false
- }
- }
- // 合成成功上报
- BFEventTrackAdaptor.baseReportUpload(businessType: nil, objectType: .ot_composeSuccess, pageSource: .sp_composePage, commonParams: commonParams())
- }
- return export
- }()
- deinit {
- avplayerTimeObserver?.invalidate()
- NotificationCenter.default.removeObserver(self)
- }
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
-
-
- PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
- PQNotification.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
-
- //进入活跃状态
- PQNotification.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
-
- //进入非活跃状态
- PQNotification.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
- showNavigation()
- // 曝光上报
- BFEventTrackAdaptor.baseReportUpload(businessType: .bt_pageView, objectType: nil, pageSource: .sp_composePage, commonParams: commonParams())
- }
- @objc func didBecomeActive(){
- BFLog(message: "进入活跃状态")
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton ,!isExporting {
- sbtn.isSelected = false
- avplayer.play()
- }
- }
-
- @objc func willResignActive(){
- BFLog(message: "进入非活跃状态")
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton , !isExporting{
- sbtn.isSelected = true
- avplayer.pause()
- }
- }
-
-
- @objc func enterBackground() {
- BFLog(message: "进入到后台")
-
- if isExporting {
- enterBackgroundCancleExport = true
- self.export.cancelExport()
- }else{
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton {
- sbtn.isSelected = true
- avplayer.pause()
- }
- }
- }
- @objc func willEnterForeground() {
- BFLog(message: "进入到前台")
- if enterBackgroundCancleExport {
- export.startExprot(synthesisAll: saveAllBtn.isSelected)
- enterBackgroundCancleExport = false
- }else {
- //重启播放器
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton {
- sbtn.isSelected = false
- avplayer.play()
- }
- }
- }
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
- PQNotification.removeObserver(self)
- UIApplication.shared.isIdleTimerDisabled = false
- }
- override func backBtnClick() {
- if isExporting {
- whetherCancelExport (msg: "savemode_changes".BFLocale){
- self.export.cancelExport()
- super.backBtnClick()
- }
- return
- }
- if !(hasExportAll || hasExportOnly) {}
- export.cancelExport()
- super.backBtnClick()
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- view.backgroundColor = .black
- navHeadImageView?.backgroundColor = .clear
- leftButton(image: nil, imageName: nil, tintColor: UIColor.white)
- addSubviews()
- // 默认保留录音合成
- saveAllBtn.isSelected = true
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
- self?.exportNow()
- }
- }
- func addSubviews() {
- view.addSubview(bottomView)
- view.addSubview(backV)
- view.addSubview(errorView)
- playerLayer = AVPlayerLayer(player: avplayer)
- playerLayer.borderWidth = 2
- playerLayer.borderColor = UIColor.hexColor(hexadecimal: "#1A1A1A").cgColor
- backV.layer.addSublayer(playerLayer)
- backV.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(playAction)))
-
- backV.addSubview(coverIV)
- backV.addSubview(playDurL)
- backV.addSubview(progressView)
- backV.addSubview(progressL)
-
- bottomView.addSubview(saveAllBtn)
- bottomView.addSubview(saveOnlyBtn)
- bottomView.addSubview(saveToPhotoBtn)
- bottomView.addSubview(completeBtn)
-
- errorView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
- coverIV.snp.makeConstraints { make in
- make.bottom.centerX.equalToSuperview()
- make.width.equalTo(coverIV.snp.height).multipliedBy(cScreenWidth / cScreenHeigth)
- make.height.equalToSuperview().offset(-1 * cDevice_iPhoneNavBarAndStatusBarHei + 30)
- }
-
- playDurL.snp.makeConstraints { make in
- make.width.centerX.equalTo(coverIV)
- make.top.equalTo(coverIV).offset(5)
- make.height.equalTo(20)
- }
-
- progressView.snp.makeConstraints { make in
- make.top.left.bottom.equalTo(coverIV)
- make.width.equalTo(0)
- }
- progressL.snp.makeConstraints { make in
- make.width.centerX.centerY.equalTo(coverIV)
- make.height.equalTo(28)
- }
-
- backV.snp.makeConstraints { make in
- make.left.right.top.equalToSuperview()
- make.bottom.equalTo(bottomView.snp.top)
- }
- bottomView.snp.makeConstraints { make in
- make.left.right.equalToSuperview()
- if #available(iOS 11.0, *) {
- make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom)
- } else {
- make.bottom.equalToSuperview()
- }
- }
- completeBtn.snp.makeConstraints { make in
- // make.left.equalTo(16)
- // make.right.equalTo(-16)
- make.centerX.equalToSuperview()
- make.bottom.equalToSuperview().offset(-7)
- make.height.equalTo(20)
- }
- saveToPhotoBtn.snp.makeConstraints { make in
- make.left.right.equalTo(completeBtn)
- make.height.equalTo(46)
- make.bottom.equalTo(completeBtn.snp.top).offset(-25)
- }
- saveAllBtn.snp.makeConstraints { make in
- make.left.equalTo(completeBtn)
- make.bottom.equalTo(saveToPhotoBtn.snp.top).offset(-15)
- make.height.equalTo(70)
- make.width.equalTo(164)
- make.top.equalTo(28)
- make.centerX.equalToSuperview().offset(-82 - 6.5)
- }
- saveOnlyBtn.snp.makeConstraints { make in
- // make.left.equalTo(saveAllBtn.snp.right).offset(16)
- make.top.height.width.equalTo(saveAllBtn)
- make.left.equalTo(saveAllBtn.snp.right).offset(13)
- make.right.equalTo(completeBtn)
- }
- // DispatchQueue.main.asyncAfter(deadline: .now() + 0) { [weak self] in
- // guard let sself = self else {
- // return
- // }
- //
- // }
- }
- override func viewDidLayoutSubviews() {
- super.viewDidLayoutSubviews()
- playerLayer.frame = coverIV.frame
- }
- /// 添加播放进度视图
- func addVideoSliderView() {
- if sliderView == nil {
- sliderView = BFVideoPlayerSliderView(frame: CGRect(x: (backV.frame.width - playerLayer.frame.width) / 2, y: backV.frame.height - 60, width: playerLayer.frame.width, height: 50),isShowFullScreen: false)
- sliderView?.playerBtn.setImage(UIImage(named: "play_0"), for: .normal)
- sliderView?.playerBtn.setImage(UIImage(named: "play_1"), for: .selected)
- sliderView?.playerBtn.imageEdgeInsets = UIEdgeInsets(top: 1, left: 7, bottom: 0, right: 0)
- sliderView?.valueChangeBloc = { [weak self,weak sliderView] sender in
- let cmtime = CMTime(value: CMTimeValue(Float64(sender.value) * Float64(self?.avplayer.currentItem?.asset.duration.seconds ?? 0) * 1000.0), timescale: CMTimeScale(1000.0))
- BFLog(message: "cmtime == \(cmtime),\(cmtime.seconds)")
- self?.avplayer.seek(to: cmtime, toleranceBefore: CMTime(seconds: 1, preferredTimescale: 1000), toleranceAfter: CMTime(seconds: 1, preferredTimescale: 1000))
- sliderView?.playStart()
- self?.avplayer.play()
- }
- sliderView?.slideBeginDrag = { [weak self] in
- self?.avplayer.pause()
- }
- sliderView?.btnClickBloc = { [weak self] sender in
- // 按钮点击
- if sender.tag == 1 {
- self?.play(sender: sender)
- } else if sender.tag == 2 {
- if sender.isSelected {
- self?.changeToFullScreen()
- } else {
- self?.changeToOriginalFrame()
- }
- }
- }
- }
- sliderView?.duration = avplayer.currentItem?.asset.duration.seconds ?? 0
- if sliderView?.superview == nil {
- backV.addSubview(sliderView!)
- }
- }
- func resetViewStatus() {
- isExporting = false
- // sself.bottomView.isHidden = false
-
- saveAllBtn.setImage(UIImage(named: "export_saveall_n"), for: .normal)
- saveOnlyBtn.setImage(UIImage(named: "export_saveonly_n"), for: .normal)
-
- saveToPhotoBtn.isEnabled = true
- saveToPhotoBtn.alpha = 1
- completeBtn.isEnabled = true
- progressView.isHidden = true
- progressView.snp.updateConstraints { make in
- make.width.equalTo(0)
- }
- progressL.isHidden = true
- progressL.text = "0%"
- }
- // MARK: - 按钮事件
- @objc func retryAction(sender:UIButton){
- if sender.currentTitle == "compose_retry2".BFLocale {
- export.cancelExport()
- navigationController?.popToRootViewController(animated: true)
- } else {
- errorView.isHidden = true
- exportNow()
- }
- }
-
- func exportNow() {
- if isExporting {
- cShowHUB(superView: nil, msg: "compose_loading".BFLocale)
- return
- }
- isExporting = true
- coverIV.isHidden = false
- playerLayer.borderColor = UIColor.hexColor(hexadecimal: "#1A1A1A").cgColor
- avplayer.replaceCurrentItem(with: nil)
- // bottomView.isHidden = true
-
- if saveAllBtn.isSelected {
- // saveAllBtn.setImage(UIImage(named: "export_saveall_h"), for: .disabled)
- saveAllBtn.setImage(UIImage(named: "export_saveall_h"), for: .normal)
- saveOnlyBtn.setImage(UIImage(named: "export_saveonly_n"), for: .normal)
- }else{
- // saveAllBtn.setImage(UIImage(named: "export_saveall_n"), for: .disabled)
- saveAllBtn.setImage(UIImage(named: "export_saveall_n"), for: .normal)
- saveOnlyBtn.setImage(UIImage(named: "export_saveonly_h"), for: .normal)
- }
-
- saveToPhotoBtn.isEnabled = false
- saveToPhotoBtn.alpha = 0.3
- completeBtn.isEnabled = false
-
- progressView.isHidden = false
- progressL.isHidden = false
- sliderView?.isHidden = true
- playDurL.isHidden = true
-
- DispatchQueue.global().async {[weak self] in
- self?.export.startExprot(synthesisAll: self?.saveAllBtn.isSelected ?? true)
- }
-
- UIApplication.shared.isIdleTimerDisabled = true
- // 开始合成上报
- BFEventTrackAdaptor.baseReportUpload(businessType: nil, objectType: .ot_startCompose, pageSource: .sp_composePage, commonParams: commonParams())
- }
- @objc func saveToPhotoNow() {
- if (saveAllBtn.isSelected && hasSaveAll) || saveOnlyBtn.isSelected && hasSaveOnly {
- cShowHUB(superView: nil, msg: "compose_tips_saved".BFLocale)
- return
- }
- if let url = (avplayer.currentItem?.asset as? AVURLAsset)?.url {
- PHPhotoLibrary.shared().performChanges {
- PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
- } completionHandler: { [weak self] isFinished, _ in
- guard let sself = self else {
- return
- }
- if isFinished {
- DispatchQueue.main.async {
- cShowHUB(superView: nil, msg: "compose_tips_successfully".BFLocale, style: 1)
- }
- if sself.saveAllBtn.isSelected {
- sself.hasSaveAll = true
- } else if sself.saveOnlyBtn.isSelected {
- sself.hasSaveOnly = true
- }
- }
- }
- }
- // 点击保存至相册上报
- BFEventTrackAdaptor.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_saveToAblum, pageSource: .sp_composePage, extParams: ["saveMode": saveAllBtn.isSelected ? "saveAll" :"saveRecord"], commonParams: commonParams())
- }
- @objc func saveAllAction(btn: UIButton) {
- if btn.isSelected {
- return
- }
-
- if isExporting {
- whetherCancelExport {[weak self] in
- self?.export.cancelExport()
- self?.resetViewStatus()
- self?.saveAllAction(btn: btn)
- }
- return
- }
-
- btn.isSelected = true
- saveOnlyBtn.isSelected = false
- avplayer.pause()
-
- if !hasExportAll {
- exportNow()
- } else {
- coverIV.isHidden = true
- avplayer.pause()
- let item = AVPlayerItem(url: saveAllUlr)
- avplayer.replaceCurrentItem(with: item)
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton {
- sbtn.isSelected = false
- avplayer.play()
- sliderView?.duration = avplayer.currentItem?.asset.duration.seconds ?? 0
- }
- }
- }
- @objc func saveOnlyAction(btn: UIButton) {
- if btn.isSelected {
- return
- }
- if isExporting {
- whetherCancelExport {[weak self ] in
- self?.export.cancelExport()
- self?.resetViewStatus()
- self?.saveOnlyAction(btn: btn)
- }
- return
- }
-
- btn.isSelected = true
- saveAllBtn.isSelected = false
- avplayer.pause()
- if !hasExportOnly {
- exportNow()
- } else {
- coverIV.isHidden = true
- avplayer.pause()
- let item = AVPlayerItem(url: saveOnlyUlr)
- avplayer.replaceCurrentItem(with: item)
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton {
- sbtn.isSelected = false
- avplayer.play()
- sliderView?.duration = avplayer.currentItem?.asset.duration.seconds ?? 0
- }
- }
- }
-
- @objc func playAction(){
- if !isExporting {
- if let sbtn = sliderView?.viewWithTag(1) as? UIButton{
- sbtn.isSelected = !sbtn.isSelected
- if sbtn.isSelected {
- avplayer.pause()
- }else{
- avplayer.play()
- }
- }
- }
- }
- @objc func completeAction() {
- // MARK: 删除所有录制资源. 现在放在了选择相册展示时清理cache
- if (!hasSaveOnly && !saveOnlyUlr.absoluteString.contains("aaa"))
- || (!hasSaveAll && !saveAllUlr.absoluteString.contains("aaa")) {
-
- let alertController = UIAlertController(title: "compose_tips_changes".BFLocale,
- message: "", preferredStyle: .alert)
- let cancelAction = UIAlertAction(title: "option_cancel".BFLocale, style: .default){_ in
-
- }
- let okAction = UIAlertAction(title: "option_confirm".BFLocale, style: .default) {[weak self] action in
- guard let sself = self else {
- return
- }
- sself.export.cancelExport()
- sself.navigationController?.popToRootViewController(animated: true)
- }
- alertController.addAction(cancelAction)
- alertController.addAction(okAction)
- self.present(alertController, animated: true, completion: nil)
-
- //
- // let remindData = BFBaseModel()
- // remindData.summary = "合成的视频尚未保存到相册"
- // let alertV = BFRemindView(frame: view.bounds)
- // alertV.isBanned = true
- // alertV.confirmBtn.setTitle("不保存", for: .normal)
- // alertV.cancelBtn.setTitle("确认保存", for: .normal)
- // alertV.remindData = remindData
- // alertV.remindBlock = { [weak self] item, _ in
- // guard let sself = self else {
- // return
- // }
- // if item.tag == 1 { // 确定返回到上一层
- // if sself.hasExportOnly {
- // PHPhotoLibrary.shared().performChanges {
- // PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: sself.saveOnlyUlr)
- // } completionHandler: { _, _ in
- // }
- // }
- // if sself.hasExportAll {
- // PHPhotoLibrary.shared().performChanges {
- // PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: sself.saveAllUlr)
- // } completionHandler: { _, _ in
- // }
- // }
- // }
- //
- // sself.export.cancelExport()
- // sself.navigationController?.popToRootViewController(animated: true)
- // }
- // UIApplication.shared.keyWindow?.addSubview(alertV)
- } else {
- export.cancelExport()
- navigationController?.popToRootViewController(animated: true)
- }
- }
- @objc func play(sender: UIButton) {
- if isExporting {
- avplayer.pause()
- return
- }
- if avplayer.currentItem != nil {
- if avplayer.timeControlStatus == .playing || sender.isSelected {
- avplayer.pause()
- } else if avplayer.timeControlStatus == .paused {
- avplayer.play()
- }
- }
- }
- func whetherCancelExport(msg:String = "savemode_changes2".BFLocale, comfirm: (() -> Void)?) {
- let alertController = UIAlertController(title: msg,
- message: "", preferredStyle: .alert)
- let cancelAction = UIAlertAction(title: "option_cancel".BFLocale, style: .default, handler: nil)
- let okAction = UIAlertAction(title: "确定", style: .default) {[weak self] action in
- guard let sself = self else {
- return
- }
- sself.export.cancelExport()
- comfirm?()
- }
- alertController.addAction(cancelAction)
- alertController.addAction(okAction)
- self.present(alertController, animated: true, completion: nil)
-
-
- // let remindData = BFBaseModel()
- // remindData.summary = "正在合成中,是否取消?"
- // let alertV = BFRemindView(frame: view.bounds)
- // alertV.isBanned = true
- // alertV.confirmBtn.setTitle("继续合成", for: .normal)
- // alertV.cancelBtn.setTitle("取消合成", for: .normal)
- // alertV.remindData = remindData
- // alertV.remindBlock = { [weak self] item, _ in
- // guard let sself = self else {
- // return
- // }
- // if item.tag == 1 { // 确定返回到上一层
- // sself.export.cancelExport()
- // comfirm?()
- // }
- // }
- // UIApplication.shared.keyWindow?.addSubview(alertV)
- }
- }
- extension INVideoExportController {
- @objc func changeToOriginalFrame() {
- if !(sliderView?.isFullScreen ?? false) {
- isHiddenStatus = false // (0.0, 64.0, 375.0, 401.0)
- navHeadImageView?.isHidden = false
- backV.frame = CGRect(x: 0, y: navHeadImageView?.frame.maxY ?? 0, width: view.width, height: bottomView.frame.minY - (navHeadImageView?.frame.maxY ?? 0))
- let width = backV.height * (cScreenWidth / cScreenHeigth)
- playerLayer.frame = CGRect(x: (backV.width - width)/2, y: 0, width: width, height: backV.height)
- // playerLayer.frame = CGRect(x: 0, y: 0, width: view.width, height: bottomView.frame.minY - (navHeadImageView?.frame.maxY ?? 0))
- sliderView?.frame = CGRect(x: 0, y: backV.frame.height - 60, width: view.frame.width, height: 50)
- UIView.animate(withDuration: 0.2, animations: { [weak self] in
- self?.changeOrientation(orientation: .portrait)
- self?.backV.center = CGPoint(x: (self?.backV.width ?? 0) / 2, y: (self?.backV.height ?? 0) / 2 + (self?.navHeadImageView?.frame.maxY ?? 0))
- }) { [weak self] _ in
- }
- }
- }
- func changeToFullScreen() {
- if sliderView?.isFullScreen ?? false {
- isHiddenStatus = true
- navHeadImageView?.isHidden = true
- backV.frame = CGRect(x: 0, y: 0, width: view.frame.height, height: view.frame.width)
- let width = view.width * (cScreenWidth / cScreenHeigth)
- playerLayer.frame = CGRect(x: (view.height - width)/2, y: 0, width: width, height: backV.width)
- // playerLayer.frame = backV.bounds
- sliderView?.frame = CGRect(x: 0, y: backV.frame.height - 60, width: backV.frame.width, height: 50)
- UIView.animate(withDuration: 0.2, animations: { [weak self] in
- let orientation = UIDevice.current.orientation
- if orientation == .landscapeRight {
- self?.changeOrientation(orientation: .landscapeLeft)
- } else {
- self?.changeOrientation(orientation: .landscapeRight)
- }
- self?.backV.center = CGPoint(x: (self?.view.frame.width ?? 0) / 2, y: (self?.view.frame.height ?? 0) / 2)
- }) { [weak self] _ in
- }
- }
- }
- func changeOrientation(orientation: UIInterfaceOrientation) {
- UIView.animate(withDuration: 0.2, animations: { [weak self] in
- self?.backV.transform = self?.transformRotation(orientation: orientation) as! CGAffineTransform
- }) { [weak self] _ in
- }
- }
- @objc func transformRotation(orientation: UIInterfaceOrientation) -> CGAffineTransform {
- if orientation == .portrait {
- return .identity
- } else if orientation == .landscapeLeft {
- return CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
- } else if orientation == .landscapeRight {
- return CGAffineTransform(rotationAngle: CGFloat.pi / 2)
- }
- return .identity
- }
- }
|