Преглед на файлове

Merge branch 'master' of https://git.yishihui.com/iOS/BFRecordScreenKit

wenweiwei преди 3 години
родител
ревизия
05bec83b13

+ 3 - 4
BFRecordScreenKit/Classes/BFRecordExport.swift

@@ -22,7 +22,7 @@ public enum ExportError: Int {
     case DiskNoSpace = -31006
 }
 
-let testFor = false
+let testFor = true
 
 public class BFRecordExport {
     public var progress: ((Float) -> Void)?
@@ -397,10 +397,9 @@ public class BFRecordExport {
                     let outSeconds = CMTimeGetSeconds(AVAsset(url: url).duration)
 
                     let exportEndTime = Date().timeIntervalSince1970
-//                    BFLog(1, message: "视频导出完成: \(String(describing: url)) 生成视频时长为:\(outSeconds) 总用时:\(exportEndTime - tempBeginExport)")
-                    print("生成视频时长为:\(outSeconds) 总用时:\(exportEndTime - tempBeginExport)")
+                    BFLog(1, message: "生成视频时长为:\(outSeconds) 总用时:\(exportEndTime - tempBeginExport)")
                     if testFor {
-                        cShowHUB(superView: nil, msg: (outSeconds == 0) ? "合成失败请重试。" : "总用时:\(exportEndTime - tempBeginExport)")
+                        cShowHUB(superView: nil, msg: (outSeconds == 0) ? "合成失败请重试。" : String(format: "总用时: %.2f", exportEndTime - tempBeginExport))
                     }
 
                     self?.exportCompletion?(nil, url)

+ 47 - 41
BFRecordScreenKit/Classes/BFVoiceRecordManager.swift

@@ -10,6 +10,8 @@ import BFMediaKit
 import Foundation
 
 class BFVoiceRecordManager: NSObject {
+    
+    let debugHeader:String = "debugHeaderManger"
     // 录音相关
     var audioRecorder: BFRecorderManager?
     // 录音结束回调
@@ -45,17 +47,19 @@ class BFVoiceRecordManager: NSObject {
     deinit{
         audioRecorder?.delegate = nil
     }
-
+ 
     /// 开始录音
     func startRecord() {
+        BFLog(2, message: "\(debugHeader)开始录音::: \(Date().timeIntervalSince1970)")
         if isStoping {
-            BFLog(2, message: "正在停止中,这次开始无效.")
+            AudioQueueRecoderDebugHandle?("正在停止中,这次开始无效.")
+            BFLog(2, message: "\(debugHeader)正在停止中,这次开始无效.")
             return
         }
         var recorderFilePath = exportAudiosDirectory
 
         if !directoryIsExists(dicPath: recorderFilePath) {
-            BFLog(message: "文件夹不存在 \(recorderFilePath)")
+            BFLog(message: "\(debugHeader)文件夹不存在 \(recorderFilePath)")
             createDirectory(path: recorderFilePath)
         }
         
@@ -64,27 +68,29 @@ class BFVoiceRecordManager: NSObject {
         let noiseFilePath = recorderFilePath.replacingOccurrences(of: ".pcm", with: "_noise.wav")
         voiceModel?.wavFilePath = noiseFilePath
 
-        BFLog(1, message: "开始录音 \(recorderFilePath)")
+        BFLog(1, message: "\(debugHeader)开始录音::: \(recorderFilePath)")
         audioRecorder?.startRecord(recorderFilePath)
     }
     
     func cancelTitleService() {
-        audioRecorder?.cancelRecord()
+        audioRecorder?.stopNui_dialog(true)
+        isStoping = false
+
     }
 
     /// 停止录制
     /// - Parameter isCancel: 是否为取消 ,取消操作会把录制的文件删除和字幕删除
     func stopRecord(isCancel: Bool) {
-        
-        //STATE_STOP
-        if(!(audioRecorder?.voiceRecorder.isStoped() ?? false)){
-            isStoping = true
-            mIsCancel = isCancel
-            audioRecorder?.stopRecord()
-        }else{
-            BFLog(2, message: "已经是停止状态")
-        }
-     
+        BFLog(2, message: "\(debugHeader)结束录音::: \(Date().timeIntervalSince1970)")
+
+        isStoping = true
+        mIsCancel = isCancel
+        //停止录音机录音
+        audioRecorder?.voiceRecorder.stop(true)
+        //停止字幕服务
+        audioRecorder?.stopNui_dialog(false)
+       
+
     }
 }
 
@@ -97,33 +103,33 @@ extension BFVoiceRecordManager: BFRecorderManagerDelegate {
     }
 
     public func recorderDidStop(_ outfile: String) {
-             if mIsCancel {
-                // 删除录制的原文件
-                deleteFile(outfile: outfile)
-                cancelRecordHandle?(nil)
-            } else {
-                var beginRecordTime1 = Date()
-
-                // 1转wav
-                let wavFilePath = outfile.replacingOccurrences(of: ".pcm", with: ".wav")
-                BFPcmToWaveTool().pcmToWav(inFileName: outfile, outFileName: wavFilePath)
-                BFLog(message: "转 WAV用时\(Date().timeIntervalSince(beginRecordTime1))")
-                // 删除录制的原文件
-                deleteFile(outfile: outfile)
-                // 2处理降噪
-                beginRecordTime1 = Date()
-                let noiseFilePath = wavFilePath.replacingOccurrences(of: ".wav", with: "_noise.wav")
-                BFLog(1, message: "降噪后地址:\(noiseFilePath) 原地址:\(wavFilePath)")
-                NXNoiseReduction().denoise(wavFilePath, outFile: noiseFilePath)
-                if let model = voiceModel {
-                    model.wavFilePath = noiseFilePath
-                    endRecordHandle?(model, nil)
-
-                    BFLog(message: "降噪用时\(Date().timeIntervalSince(beginRecordTime1))")
-                }
-                // 删除临时 wav 文件
-                deleteFile(outfile: wavFilePath)
+        if mIsCancel {
+            // 删除录制的原文件
+            deleteFile(outfile: outfile)
+            cancelRecordHandle?(nil)
+        } else {
+            var beginRecordTime1 = Date()
+
+            // 1转wav
+            let wavFilePath = outfile.replacingOccurrences(of: ".pcm", with: ".wav")
+            BFPcmToWaveTool().pcmToWav(inFileName: outfile, outFileName: wavFilePath)
+            BFLog(message: "\(debugHeader)转 WAV用时\(Date().timeIntervalSince(beginRecordTime1))")
+            // 删除录制的原文件
+            deleteFile(outfile: outfile)
+            // 2处理降噪
+            beginRecordTime1 = Date()
+            let noiseFilePath = wavFilePath.replacingOccurrences(of: ".wav", with: "_noise.wav")
+            BFLog(1, message: "\(debugHeader)降噪后地址:\(noiseFilePath) 原地址:\(wavFilePath)")
+            NXNoiseReduction().denoise(wavFilePath, outFile: noiseFilePath)
+            if let model = voiceModel {
+                model.wavFilePath = noiseFilePath
+                endRecordHandle?(model, nil)
+
+                BFLog(message: "\(debugHeader)降噪用时\(Date().timeIntervalSince(beginRecordTime1))")
             }
+            // 删除临时 wav 文件
+            deleteFile(outfile: wavFilePath)
+        }
  
         // 其它逻辑写在上面 保证最后关开关。
         isStoping = false

+ 43 - 26
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -387,7 +387,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
     // debug
     lazy var neoNuiDebugLabel: UILabel = {
-        let neoNuiDebugLabel = UILabel(frame: CGRect(x: 0, y: 100, width: 200, height: 24))
+        let neoNuiDebugLabel = UILabel(frame: CGRect(x: 0, y: 100, width: 300, height: 24))
         neoNuiDebugLabel.backgroundColor = .black
         neoNuiDebugLabel.textColor = .white
         neoNuiDebugLabel.textAlignment = .left
@@ -396,7 +396,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     lazy var audioQueueRecoderLabel: UILabel = {
-        let audioQueueRecoderLabel = UILabel(frame: CGRect(x: 0, y: 125, width: 200, height: 24))
+        let audioQueueRecoderLabel = UILabel(frame: CGRect(x: 0, y: 125, width: 300, height: 24))
         audioQueueRecoderLabel.backgroundColor = .black
         audioQueueRecoderLabel.textColor = .white
         audioQueueRecoderLabel.textAlignment = .left
@@ -463,7 +463,8 @@ public class BFRecordScreenController: BFBaseViewController {
 
         checkStatus()
         // mdf by ak 切换外放和请求权限分开 否则会导致首次安装时不能执行切换操作
-        try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: .defaultToSpeaker)
+        let options:AVAudioSession.CategoryOptions = [.defaultToSpeaker,.allowBluetooth]
+        try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: options)
 
         // add by ak 取 nsl token
         BFRecordScreenViewModel.getNlsAccessToken { [weak self] token, appkey in
@@ -493,7 +494,7 @@ public class BFRecordScreenController: BFBaseViewController {
             let header = dicResult?["header"] as? [String: Any]
             let payload = dicResult?["payload"] as? [String: Any]
 
-            BFLog(1, message: "识别结果:) \(payload?["result"]) ,taskId:\((header?["task_id"] as? String) ?? "taskId"), 识别时间:\(((payload?["begin_time"]) as? Int) ?? 0) ~ \(((payload?["time"]) as? Int) ?? 0) startTime:\(self?.recorderManager?.voiceModel?.startCMTime.seconds ?? 0.0)")
+            BFLog(1, message: "识别结果:) \(payload?["result"] ?? "") ,taskId:\((header?["task_id"] as? String) ?? "taskId"), 识别时间:\(((payload?["begin_time"]) as? Int) ?? 0) ~ \(((payload?["time"]) as? Int) ?? 0) startTime:\(self?.recorderManager?.voiceModel?.startCMTime.seconds ?? 0.0)")
 
             DispatchQueue.main.async {
                 // 1,保存字幕数据 begin_time是开始出现文字的时间,time 是结束文字出现的时间 单位都为毫秒,都是相对于录制音频数据整段时间。self.recorderManager.voiceModel?.startCMTime.seconds 为开始的录制的时间,开始和结束都要加上这个时差
@@ -530,14 +531,9 @@ public class BFRecordScreenController: BFBaseViewController {
                         return
                     }
                 }
-                var showText = ((payload?["result"]) as? String) ?? ""
-                if showText.count > subtitleMaxlength {
-                    showText = showText.substring(to: subtitleMaxlength)
-                    showText += "..."
-                }
+                let showText = ((payload?["result"]) as? String) ?? ""
                 newSubtitle.text = showText
 //                newSubtitle.audioFilePath = audioFilePath ?? ""
-
                 BFLog(1, message: "添加字幕数据 timelineIn \(newSubtitle.timelineIn.seconds) timelineOut \(newSubtitle.timelineOut.seconds) text: \(newSubtitle.text) 音频路径为:\(audioFilePath ?? "bb") 传入的地址:\(self?.recorderManager?.voiceModel?.wavFilePath ?? "aa")")
 
                 newSubtitle.setting = self?.subtitleSettingView.subtitle.setting ?? BFSubTitileSettingModel()
@@ -694,13 +690,14 @@ public class BFRecordScreenController: BFBaseViewController {
         subtitleSettingView.subtitleSettingCallBack = { [weak self] subtitileModel in
 
             self?.setSubtitleStyle(settingModel: subtitileModel.setting)
+            //mdf by ak 这里是设置字幕开关回调
+            if self?.subTitleBtnClickHandle != nil {
+                self?.subTitleBtnClickHandle!(subtitileModel.setting.subtitleIsShow)
+                
+            }
         }
         // 编辑字幕完成
         subtitleEditView.editSubtitleDone = { [weak self] newtext, index in
-            // 1,刷新 UI
-            self?.subtitleLabel.text = newtext
-
-            self?.setSubtitleStyle(settingModel: (self?.subtitleSettingView.subtitle.setting)!)
 
             // 更新缓存数据
             if index < (self?.itemModels[self?.currItemModelIndex ?? 0].titleStickers.count ?? 0) {
@@ -713,6 +710,10 @@ public class BFRecordScreenController: BFBaseViewController {
                     self?.itemModels[self?.currItemModelIndex ?? 0].titleStickers[index].text = newtext
                 }
             }
+
+            self?.setSubtitleStyle(settingModel: (self?.subtitleSettingView.subtitle.setting)!)
+
+         
         }
 
         layoutsubview()
@@ -723,8 +724,8 @@ public class BFRecordScreenController: BFBaseViewController {
             cShowHUB(superView: view, msg: "网络不佳,字幕可能无法生成")
         }
 
-//        view.addSubview(neoNuiDebugLabel)
-//        view.addSubview(audioQueueRecoderLabel)
+        view.addSubview(neoNuiDebugLabel)
+        view.addSubview(audioQueueRecoderLabel)
     }
 
     @objc func editSubtitle() {
@@ -777,8 +778,10 @@ public class BFRecordScreenController: BFBaseViewController {
             setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
 
         } else {
-            subtitleLabel.text = ""
-            subtitleLabel.backgroundColor = UIColor.clear
+            if subtitleLabel.text?.count ?? 0 > 0 {
+                subtitleLabel.text = ""
+                subtitleLabel.backgroundColor = UIColor.clear                
+            }
         }
     }
 
@@ -806,6 +809,8 @@ public class BFRecordScreenController: BFBaseViewController {
             } else { // 上
                 subtitleLabel.frame = CGRect(x: leftPoint, y: cScreenHeigth * 0.12, width: cScreenWidth - 37 * 2, height: height)
             }
+            //打开的时候主动调用一次显示字幕
+            updateSubtitle(time: currentAssetProgress)
         } else {
             subtitleLabel.text = ""
         }
@@ -945,9 +950,8 @@ public class BFRecordScreenController: BFBaseViewController {
     @objc func subTitleClick() {
         BFLog(message: "subTitle Click ")
         subtitleSettingView.isHidden = !subtitleSettingView.isHidden
-        if subTitleBtnClickHandle != nil {
-            subTitleBtnClickHandle!(subtitleSettingView.subtitle.setting.subtitleIsShow)
-        }
+  
+        updateSubtitle(time: currentAssetProgress)
     }
 
     // 声音设置
@@ -1120,6 +1124,13 @@ public class BFRecordScreenController: BFBaseViewController {
         if !avatarView.isHidden {
             avatarView.endRecord()
         }
+        //add by ak 添加统计
+        if let model = itemModels[currItemModelIndex].voiceStickers.last
+        {
+            recordRndHandle?(model)
+        }
+        
+//
     }
 
     @objc func cancleRecord() {
@@ -1137,6 +1148,7 @@ public class BFRecordScreenController: BFBaseViewController {
         BFLog(3, message: "开始录制-取消:currentAssetProgress=\(currentAssetProgress.seconds),cuInde=\(currItemModelIndex),currIndex=\(voiceModel?.currIndex ?? 0),\(String(describing: voiceModel)),\(String(describing: recorderManager?.voiceModel))")
         if voiceModel != nil, currentAssetProgress.seconds - (recorderManager?.voiceModel?.startCMTime.seconds ?? 0) < 1.0 {
             cShowHUB(superView: nil, msg: "最短录制1秒")
+            recorderManager?.cancelTitleService()
         }
         // 删除文件
         recorderManager?.deleteFile(outfile: voiceModel?.wavFilePath ?? "")
@@ -1344,9 +1356,9 @@ public class BFRecordScreenController: BFBaseViewController {
             //  TODO: 停在了录音区间,显示删除按钮
             if needAdsorb {
                 if fabs(elems[0].1.endCMTime.seconds - currentAssetProgress.seconds) < 0.5 {
-                    BFLog(1, message: "吸附在录音结尾")
+                    BFLog(1, message: "吸附在录音结尾, \(elems[0].1.endCMTime.seconds)")
                     //                changeWithDrawBtnLayout(false)
-                    changeProgress(progress: Float(elems[0].1.endCMTime.seconds / itemModels[currItemModelIndex].materialDuraion))
+                    changeProgress(changCMTime:elems[0].1.endCMTime)
                     progressThumV.progress = elems[0].1.endCMTime.seconds
 
 //                    deleteRecordBtn.isHidden = true
@@ -1462,7 +1474,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 assetPlayer?.volume = noSpeakVolume
             }
         }
-        BFLog(1, message: "volume:\(assetPlayer?.volume ?? -1)")
+//        BFLog(1, message: "volume:\(assetPlayer?.volume ?? -1)")
 
         if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
             return
@@ -1881,7 +1893,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
     // 通过缩略图进度条控制播放进度
     // progress : 图片且isback为true时,表示是时长;  其他情况: 0 - 1,百分比
-    func changeProgress(isBack: Bool = false, progress: Float) {
+    func changeProgress(isBack: Bool = false, progress: Float = -1, changCMTime:CMTime = .zero) {
         var newProgress = progress
         if progress.isNaN || progress.isInfinite {
             newProgress = 0
@@ -1889,7 +1901,11 @@ public class BFRecordScreenController: BFBaseViewController {
         if itemModels[currItemModelIndex].mediaType == .VIDEO {
             let duration = itemModels[currItemModelIndex].materialDuraion
             if duration > 0 {
-                currentAssetProgress = CMTime(seconds: Double(newProgress) * duration, preferredTimescale: 1000)
+                if progress == -1 {
+                    currentAssetProgress = changCMTime
+                }else{
+                    currentAssetProgress = CMTime(seconds: Double(newProgress) * duration, preferredTimescale: 1000)
+                }
                 DispatchQueue.main.async { [weak self] in
                     BFLog(message: "更新录音进度\(#function)- \(self?.currentAssetProgress.seconds ?? 0)")
                     self!.progreddL.text = String(format: "%@", CMTimeGetSeconds(self!.currentAssetProgress).formatDurationToHMS())
@@ -2084,6 +2100,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             searchStopAtRecordRange()
             // 切换要更新当前录制index,避免在录制完以后切换素材这种时候为-3会拦截
             currentPlayRecordIndex = -1
+            showSubtitleIndex = -1
             // 重置播放器
             assetPlayer?.seek(to: CMTime.zero)
             recordPlayer?.seek(to: CMTime.zero)

+ 2 - 3
BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleEditView.swift

@@ -14,7 +14,7 @@ typealias EditSubtitleDone = (_ text: String,_ index:Int) -> Void
 
 
 //字幕最大数限制
-public let subtitleMaxlength:Int = 30
+//public let subtitleMaxlength:Int = 0
 
 class BFSubtitleEditView: UIView {
     
@@ -25,7 +25,6 @@ class BFSubtitleEditView: UIView {
     /// 输入框
     lazy var textView: BFTextView = {
         let textView = BFTextView()
-        textView.maxTextLength = subtitleMaxlength
         textView.maxTextLengthRemind = ""
         textView.backgroundColor = UIColor.clear
         textView.textColor = UIColor.hexColor(hexadecimal: "#FFFFFF")
@@ -104,7 +103,7 @@ class BFSubtitleEditView: UIView {
 
     func setNewText(text: String,index:Int) {
         showSubtitleIndex = index
-        textView.text = text.substring(to: subtitleMaxlength)
+        textView.text = text
 //        BFLog(message: "传值\(textView.text)")
 //
 //        let attributedText = NSMutableAttributedString(string: textView.text,attributes: [.font: UIFont.systemFont(ofSize: CGFloat(settingModel.subtitleSize)  * 375 / 1080),.strokeWidth:-6,.strokeColor: settingModel.strokeColor,.foregroundColor:settingModel.fontColor])