BFVoiceRecordManager.swift 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // BFVoiceRecordManager.swift
  3. // BFRecordScreenKit
  4. //
  5. // Created by 胡志强 on 2021/11/24.
  6. //
  7. import BFCommonKit
  8. import BFMediaKit
  9. import Foundation
  10. class BFVoiceRecordManager: NSObject {
  11. // 录音相关
  12. var audioRecorder: BFRecorderManager?
  13. //录音结束回调
  14. var endRecordHandle: ((PQVoiceModel?, Error?) -> Void)?
  15. //录音取消回调
  16. var cancelRecordHandle: ((PQVoiceModel?) -> Void)?
  17. //录音进度回调
  18. var recorderProgrossHandle: ((Float64?) -> Void)?
  19. //字幕的回调 参数1: 字幕数据 ,参数2 :对应的录音文件
  20. var subtitleRecordHandle: ((String?,String?) -> Void)?
  21. //开始录制时间
  22. var beginRecordTime: Date = Date()
  23. //音频文件模型
  24. var voiceModel: PQVoiceModel?
  25. //停止是否为取消操作
  26. var mIsCancel:Bool = false
  27. /// 初始化方法
  28. /// - Parameters:
  29. /// - token: NLS token
  30. /// - appid: NLS appid
  31. public init(token: String, appid: String) {
  32. super.init()
  33. audioRecorder = BFRecorderManager(token, appid: appid)
  34. audioRecorder?.delegate = self
  35. }
  36. /// 开始录音
  37. func startRecord() {
  38. var recorderFilePath = exportAudiosDirectory
  39. if !directoryIsExists(dicPath: recorderFilePath) {
  40. BFLog(message: "文件夹不存在 \(recorderFilePath)")
  41. createDirectory(path: recorderFilePath)
  42. }
  43. recorderFilePath.append("recorder_\(Date().timeIntervalSince1970).pcm")
  44. BFLog(1, message: "开始录音 \(recorderFilePath)")
  45. BFLog(1, message: "开始录制")
  46. audioRecorder?.startRecord(recorderFilePath)
  47. beginRecordTime = Date()
  48. }
  49. /// 停止录制
  50. /// - Parameter isCancel: 是否为取消 ,取消操作会把录制的文件删除和字幕删除
  51. func stopRecord(isCancel: Bool) {
  52. mIsCancel = isCancel
  53. audioRecorder?.stopRecord()
  54. }
  55. }
  56. // MARK: - 录音机回调
  57. extension BFVoiceRecordManager: BFRecorderManagerDelegate {
  58. public func recorderProgress(_: BFRecorderManager, recoderTime: Double) {
  59. BFLog(message: "录音机进度:\(recoderTime)")
  60. recorderProgrossHandle?(recoderTime)
  61. }
  62. public func recorderDidStop(_ outfile: String) {
  63. let duration = Date().timeIntervalSince(beginRecordTime)
  64. if duration > 1 {
  65. if(mIsCancel){
  66. // 删除录制的原文件
  67. do {
  68. try FileManager.default.removeItem(atPath: outfile)
  69. print("取消后删除文件Success to remove recorder file. \(outfile)")
  70. } catch {
  71. print("取消后删除文件Failed to remove recorder file. \(outfile)")
  72. }
  73. cancelRecordHandle?(nil)
  74. }else{
  75. var beginRecordTime1 = Date()
  76. //1转wav
  77. let wavFilePath = outfile.replacingOccurrences(of: ".pcm", with: ".wav")
  78. BFPcmToWaveTool().pcmToWav(inFileName: outfile, outFileName: wavFilePath)
  79. BFLog(message: "转 WAV用时\( Date().timeIntervalSince(beginRecordTime1))")
  80. // 删除录制的pcm文件
  81. do {
  82. try FileManager.default.removeItem(atPath: outfile)
  83. print("Success to remove recorder file. \(outfile)")
  84. } catch {
  85. print("Failed to remove recorder file. \(outfile)")
  86. }
  87. //2处理降噪
  88. beginRecordTime1 = Date()
  89. let noiseFilePath = wavFilePath.replacingOccurrences(of: ".wav", with: "_noise.wav")
  90. BFLog(1, message: "降噪后地址:\(noiseFilePath) 原地址:\(wavFilePath)")
  91. NXNoiseReduction().denoise(wavFilePath, outFile: noiseFilePath)
  92. if let model = voiceModel {
  93. model.wavFilePath = noiseFilePath
  94. model.duration = "\(duration)"
  95. endRecordHandle?(model, nil)
  96. BFLog(message: "降噪用时\( Date().timeIntervalSince(beginRecordTime1))")
  97. }
  98. // 删除临时 wav 文件
  99. do {
  100. try FileManager.default.removeItem(atPath: wavFilePath)
  101. print("Success to remove recorder file. \(wavFilePath)")
  102. } catch {
  103. print("Failed to remove recorder file. \(wavFilePath)")
  104. }
  105. }
  106. } else {
  107. cShowHUB(superView: nil, msg: "最短录制1秒")
  108. cancelRecordHandle?(voiceModel)
  109. }
  110. }
  111. public func eventCallback(_: BFRecorderManager, asrResult: String,audioFilePath:String) {
  112. //最后输出的文件是降噪后的
  113. let noiseFilePath = audioFilePath.replacingOccurrences(of: ".pcm", with: "_noise.wav")
  114. subtitleRecordHandle?(asrResult, noiseFilePath)
  115. }
  116. }