|
@@ -12,25 +12,34 @@ import GPUImage
|
|
|
import Photos
|
|
|
import BFCommonKit
|
|
|
import BFFramework
|
|
|
+import UIKit
|
|
|
|
|
|
public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
public var nextActionHandle:(()->Void)?
|
|
|
public var closeActionHandle:(()->Void)?
|
|
|
+
|
|
|
+ // MARK: - 录制参数
|
|
|
public var asset:PHAsset?
|
|
|
+// var shouldPlayRecordIndex:Int = -1 // 当前应该播放的录音资源序号
|
|
|
+ var currentPlayRecordIndex:Int = -1 // 当前正在播放的录音资源序号
|
|
|
+ var isRecording = false // 是否正在录音
|
|
|
+ var isNormalPlaying = false { // 是否正在录音
|
|
|
+ didSet{
|
|
|
+ playBtn.isSelected = isNormalPlaying
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var currentAssetProgress : CMTime = .zero // 当前素材播放的进度
|
|
|
+ // 视频素材
|
|
|
public var avasset:AVURLAsset?
|
|
|
public var recordList:[PQVoiceModel] = [PQVoiceModel]()
|
|
|
-
|
|
|
var assetPlayer:AVPlayer? // 原视频音频播放器
|
|
|
- lazy var recordPlayer:AVAudioPlayer = {// 录音音频播放器
|
|
|
- let player = AVAudioPlayer()
|
|
|
- player.volume = 1
|
|
|
- return player
|
|
|
-
|
|
|
- }()
|
|
|
+ var isCompletePlay = true
|
|
|
+ var hadPrepareToPlayRecord = false // 录音播放器准备
|
|
|
+ var recordPlayer:AVPlayer? // 录音音频播放器
|
|
|
var movie :GPUImageMovie? // 视频预览
|
|
|
var playView :GPUImageView? // 视频展示视图
|
|
|
- var isDragingProgressSlder : Bool = false
|
|
|
+ var isDragingProgressSlder : Bool = false // 是否在拖动进度条
|
|
|
|
|
|
//定义音频的编码参数
|
|
|
let recordSettings:[String : Any] = [AVSampleRateKey : 44100.0, //声音采样率
|
|
@@ -48,29 +57,44 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
}
|
|
|
manager.endRecordHandle = {[weak self] (isTimeout, model) in
|
|
|
- if FileManager.default.fileExists(atPath: model?.wavFilePath ?? ""){
|
|
|
+ if let model = model, FileManager.default.fileExists(atPath: model.wavFilePath ?? ""){
|
|
|
// 加入到语音数组里
|
|
|
+ let ass = AVURLAsset(url: URL(fileURLWithPath: model.wavFilePath))
|
|
|
+
|
|
|
+ model.endTime = model.startTime + CMTimeGetSeconds(ass.duration)
|
|
|
while let m = self?.recordList.last{
|
|
|
- if m.startTime < model!.startTime {
|
|
|
+ if model.startTime < m.startTime {
|
|
|
self?.recordList.removeLast()
|
|
|
- }else if m.endTime < model!.startTime {
|
|
|
- m.endTime = model!.startTime
|
|
|
+ }else if m.endTime > model.startTime {
|
|
|
+ m.endTime = model.startTime
|
|
|
}else{
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
- self?.recordList.append(model!)
|
|
|
- self?.drewRecordProgessLable()
|
|
|
+ BFLog(1, message: "添加录音文件:\(model.startTime) -- \(model.endTime)")
|
|
|
+ self?.recordList.append(model)
|
|
|
+ self?.drawOrUpdateRecordProgessLable()
|
|
|
}
|
|
|
|
|
|
}
|
|
|
return manager
|
|
|
}()
|
|
|
|
|
|
+ // MARK: - 视图参数
|
|
|
var beginOnStartBtn:Bool = false
|
|
|
var touchStart:CGPoint = CGPoint(x: 0, y: 0)
|
|
|
var avplayerTimeObserver: NSKeyValueObservation?
|
|
|
|
|
|
+ lazy var progreddL : UILabel = {
|
|
|
+ let l = UILabel(frame: CGRect(x: 0, y: cDevice_iPhoneStatusBarHei, width: cScreenWidth, height: 14))
|
|
|
+ l.textAlignment = .center
|
|
|
+ l.font = UIFont.systemFont(ofSize: 10)
|
|
|
+ l.textColor = .white
|
|
|
+ l.shadowColor = .black
|
|
|
+ l.shadowOffset = CGSize(width: 1, height: 1)
|
|
|
+ return l
|
|
|
+ }()
|
|
|
+
|
|
|
lazy var playBtn:UIButton = {
|
|
|
let btn = UIButton(frame: view.bounds)
|
|
|
btn.addTarget(self, action: #selector(playVideo(btn:)), for: .touchUpInside)
|
|
@@ -100,6 +124,13 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
return btn
|
|
|
}()
|
|
|
|
|
|
+ lazy var progessSildeBackV : UIView = {
|
|
|
+ let vv = UIView()
|
|
|
+ vv.backgroundColor = UIColor.hexColor(hexadecimal: "#303030")
|
|
|
+
|
|
|
+ return vv
|
|
|
+ }()
|
|
|
+
|
|
|
lazy var progessSilde:BFPlayerSlider = {
|
|
|
let sliderView = BFPlayerSlider()
|
|
|
let tjbV = UIView(frame: CGRect(x: 0, y: 0, width: 4, height: 16))
|
|
@@ -109,8 +140,8 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
sliderView.setMaximumTrackImage(thbImage, for: .normal)
|
|
|
sliderView.setThumbImage(thbImage, for: .highlighted)
|
|
|
sliderView.setThumbImage(thbImage, for: .normal)
|
|
|
- sliderView.maximumTrackTintColor = UIColor.hexColor(hexadecimal: "#303030")
|
|
|
- sliderView.minimumTrackTintColor = UIColor.hexColor(hexadecimal: "#303030")
|
|
|
+ sliderView.maximumTrackTintColor = .clear // UIColor.hexColor(hexadecimal: "#303030")
|
|
|
+ sliderView.minimumTrackTintColor = .clear //UIColor.hexColor(hexadecimal: "#303030")
|
|
|
// sliderView.minimumTrackTintColor = UIColor.hexColor(hexadecimal: "#FA6400")
|
|
|
sliderView.addTarget(self, action: #selector(sliderTouchBegan(sender:)), for: .touchDown)
|
|
|
sliderView.addTarget(self, action: #selector(sliderTouchEnded(sender:)), for: .touchUpInside)
|
|
@@ -122,7 +153,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
lazy var closeBtn:UIButton = {
|
|
|
let btn = UIButton(type: .custom)
|
|
|
btn.setImage(imageInRecordScreenKit(by: "xx"), for: .normal)
|
|
|
- btn.addTarget(self, action: #selector(close), for: .touchUpInside)
|
|
|
+ btn.addTarget(self, action: #selector(closePage), for: .touchUpInside)
|
|
|
return btn
|
|
|
}()
|
|
|
|
|
@@ -133,14 +164,29 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
return btn
|
|
|
}()
|
|
|
|
|
|
- //MARK: -- 生命周期
|
|
|
+ lazy var toolV : BFIntroduceToolView = {
|
|
|
+ let toolV = BFIntroduceToolView()
|
|
|
+ toolV.centerY = view.centerY
|
|
|
+
|
|
|
+ toolV.choosedToolHandle = {[weak self] tool in
|
|
|
+ guard let sself = self else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ tool.center = sself.view.center
|
|
|
+ sself.view.addSubview(tool)
|
|
|
+ }
|
|
|
+
|
|
|
+ return toolV
|
|
|
+
|
|
|
+ }()
|
|
|
+ //MARK: ------------------ 生命周期
|
|
|
deinit {
|
|
|
cleanMovieTarget()
|
|
|
NotificationCenter.default.removeObserver(self)
|
|
|
avplayerTimeObserver?.invalidate()
|
|
|
recorderManager.stopRecord(isCancel: true)
|
|
|
assetPlayer?.pause()
|
|
|
- recordPlayer.pause()
|
|
|
+ recordPlayer?.pause()
|
|
|
|
|
|
}
|
|
|
|
|
@@ -160,10 +206,12 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
view.addSubview(playView!)
|
|
|
fetchVideo()
|
|
|
|
|
|
-
|
|
|
view.addSubview(playBtn)
|
|
|
view.addSubview(bottomeView)
|
|
|
+ view.addSubview(progreddL)
|
|
|
+// view.addSubview(toolV)
|
|
|
bottomeView.addSubview(recordBtn)
|
|
|
+ bottomeView.addSubview(progessSildeBackV)
|
|
|
bottomeView.addSubview(progessSilde)
|
|
|
bottomeView.addSubview(closeBtn)
|
|
|
bottomeView.addSubview(nextBtn)
|
|
@@ -197,10 +245,15 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
make.top.width.height.equalTo(closeBtn)
|
|
|
}
|
|
|
|
|
|
- progessSilde.snp.makeConstraints { make in
|
|
|
+ progessSildeBackV.snp.makeConstraints { make in
|
|
|
make.left.equalTo(closeBtn.snp.right).offset(16)
|
|
|
make.right.equalTo(nextBtn.snp.left).offset(-16)
|
|
|
make.centerY.equalTo(closeBtn)
|
|
|
+ make.height.equalTo(8)
|
|
|
+ }
|
|
|
+
|
|
|
+ progessSilde.snp.makeConstraints { make in
|
|
|
+ make.left.right.centerY.equalTo(progessSildeBackV)
|
|
|
make.height.equalTo(20)
|
|
|
}
|
|
|
|
|
@@ -208,9 +261,9 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
// MARK: - 按钮事件响应
|
|
|
|
|
|
- // 觸發拖曳手勢後 執行的動作
|
|
|
+ // 触发拖曳手势后,执行的动作
|
|
|
@objc func pan(recognizer: UIPanGestureRecognizer) {
|
|
|
- // 設置 UIView 新的位置
|
|
|
+ // 设置 UIView 新的位置
|
|
|
if !checkStatus(show: false) {
|
|
|
return
|
|
|
}
|
|
@@ -252,28 +305,35 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
@objc func startRecord(btn:UIButton){
|
|
|
btn.setImage(imageInRecordScreenKit(by: "mic2"), for: .normal)
|
|
|
BFLog(1, message: "start \(UIControl.Event.touchDown)")
|
|
|
+ pause()
|
|
|
+
|
|
|
let model = PQVoiceModel()
|
|
|
- model.startTime = CMTimeGetSeconds(assetPlayer?.currentItem?.currentTime() ?? CMTime.zero)
|
|
|
+ model.startTime = CMTimeGetSeconds(self.currentAssetProgress)
|
|
|
recorderManager.voiceModel? = model
|
|
|
recorderManager.startRecord(index: recordList.count)
|
|
|
movie?.startProcessing()
|
|
|
assetPlayer?.volume = 0
|
|
|
assetPlayer?.play()
|
|
|
+ isRecording = true
|
|
|
}
|
|
|
|
|
|
@objc func endRecord(btn:UIButton){
|
|
|
recordBtn.setImage(imageInRecordScreenKit(by: "mic1"), for: .normal)
|
|
|
// 存储录音
|
|
|
recorderManager.endRecord()
|
|
|
+ isRecording = false
|
|
|
+
|
|
|
pause()
|
|
|
}
|
|
|
|
|
|
func cancleRecord(){
|
|
|
recordBtn.setImage(imageInRecordScreenKit(by: "mic1"), for: .normal)
|
|
|
recorderManager.cancleRecord()
|
|
|
+ isRecording = false
|
|
|
+
|
|
|
pause()
|
|
|
}
|
|
|
- @objc func close(){
|
|
|
+ @objc func closePage(){
|
|
|
pause()
|
|
|
closeActionHandle?()
|
|
|
}
|
|
@@ -283,25 +343,19 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
|
|
|
@objc func playVideo(btn:UIButton){
|
|
|
- btn.isSelected = !btn.isSelected
|
|
|
- BFLog(1, message: "点击")
|
|
|
- if btn.isSelected{
|
|
|
- play()
|
|
|
-
|
|
|
- }else{
|
|
|
- pause()
|
|
|
- }
|
|
|
+ btn.isSelected ? pause() : play()
|
|
|
}
|
|
|
|
|
|
@objc public func sliderTouchBegan(sender _: UISlider) {
|
|
|
-// isDragingProgressSlder = true
|
|
|
-// pause()
|
|
|
+ isDragingProgressSlder = true
|
|
|
+ pause()
|
|
|
}
|
|
|
|
|
|
@objc public func sliderTouchEnded(sender: UISlider) {
|
|
|
-// changeProgress(progress: sender.value)
|
|
|
-// isDragingProgressSlder = false
|
|
|
-// play()
|
|
|
+ changeProgress(progress: sender.value)
|
|
|
+ isDragingProgressSlder = false
|
|
|
+ currentPlayRecordIndex = -1
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// MARK: - 权限申请
|
|
@@ -350,29 +404,88 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
|
|
|
// MARK: - 音视频处理
|
|
|
- func playRecord(at duration:CMTime){
|
|
|
- if recordList.count > 0, let player = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: (recordList.first?.wavFilePath)!)) {
|
|
|
- self.recordPlayer = player
|
|
|
- self.recordPlayer.volume = 1
|
|
|
- self.recordPlayer.play()
|
|
|
- }else{
|
|
|
- self.recordPlayer.pause()
|
|
|
+ func playRecord(at currentT:CMTime){
|
|
|
+ let (shouldPlayRecordIndex, recordedAudio) = recordList.enumerated().first { model in
|
|
|
+ model.1.endTime > CMTimeGetSeconds(currentT)
|
|
|
+ } ?? (-1, nil)
|
|
|
+
|
|
|
+ guard let recordedAudio = recordedAudio else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ BFLog(1, message: "当前时间:\(CMTimeGetSeconds(currentT)), 找到的音频:\(recordedAudio.startTime), \(recordedAudio.endTime)")
|
|
|
+
|
|
|
+ // 创建播放器
|
|
|
+ if self.recordPlayer == nil || (self.recordPlayer?.currentItem?.asset as? AVURLAsset)?.url.lastPathComponent != (recordedAudio.wavFilePath as NSString).lastPathComponent {
|
|
|
+ self.recordPlayer?.pause()
|
|
|
+ self.recordPlayer = AVPlayer(url: URL(fileURLWithPath: recordedAudio.wavFilePath))
|
|
|
+ self.recordPlayer!.volume = 1
|
|
|
+ // self.recordPlayer?.prepareToPlay()
|
|
|
+ currentPlayRecordIndex = -1
|
|
|
+ hadPrepareToPlayRecord = false
|
|
|
+ BFLog(1, message: "录音播放器初始化(有时候不准)")
|
|
|
}
|
|
|
+
|
|
|
+ synced(currentPlayRecordIndex) {
|
|
|
+ if !hadPrepareToPlayRecord
|
|
|
+ && CMTimeGetSeconds(currentT) >= recordedAudio.startTime
|
|
|
+ && CMTimeGetSeconds(currentT) <= recordedAudio.endTime - 0.2 // 这个条件是避免录音结束后有小幅度回退导致播放最新录音
|
|
|
+ {
|
|
|
+ // 应当开始播放了
|
|
|
+ // 两个逻辑:如果在播,则跳过;如果暂停拖动到中间,则seek
|
|
|
+ if currentPlayRecordIndex == -1 {
|
|
|
+ let second = CMTimeGetSeconds(currentT) - recordedAudio.startTime
|
|
|
+ recordPlayer?.seek(to: CMTime(value: CMTimeValue(second), timescale: 100), toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000), completionHandler: {[weak self] finished in
|
|
|
+ if finished && (self?.isNormalPlaying ?? false) {
|
|
|
+ DispatchQueue.main.async {[weak self] in
|
|
|
+ self?.recordPlayer?.play()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ currentPlayRecordIndex = shouldPlayRecordIndex
|
|
|
+ hadPrepareToPlayRecord = true
|
|
|
+ BFLog(1, message: "录音开始播放2, \(second), \(CMTimeGetSeconds(recordPlayer?.currentItem?.duration ?? .zero))")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ BFLog(1, message: "应当播放:\(shouldPlayRecordIndex), 当前播放:\(currentPlayRecordIndex)")
|
|
|
+// if let recordedAudio = recordedAudio {
|
|
|
+//
|
|
|
+//
|
|
|
+// if shouldPlayRecordIndex != currentPlayRecordIndex {
|
|
|
+// // 设置新的播放资源
|
|
|
+//
|
|
|
+//// self.recordPlayer.delegate = self
|
|
|
+// self.recordPlayer.play()
|
|
|
+//
|
|
|
+// } else {
|
|
|
+// // 更新播放进度
|
|
|
+// let second = CMTimeGetSeconds(duration) - recordedAudio.startTime
|
|
|
+// self.recordPlayer.seek(to: CMTime(seconds: second, preferredTimescale: 25), toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000))
|
|
|
+// }
|
|
|
+// }
|
|
|
}
|
|
|
|
|
|
func play(){
|
|
|
- cShowHUB(superView: nil, msg: "开始播放")
|
|
|
- assetPlayer?.volume = 0.5
|
|
|
+ BFLog(1, message: "开始播放")
|
|
|
+ assetPlayer?.volume = 0.2
|
|
|
movie?.startProcessing()
|
|
|
- assetPlayer?.play()
|
|
|
- playRecord(at: CMTime.zero)
|
|
|
+ isNormalPlaying = true
|
|
|
+ let second = assetPlayer?.currentItem?.currentTime()
|
|
|
+ assetPlayer?.seek(to: second ?? CMTime.zero, toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000), completionHandler: {[weak self] finished in
|
|
|
+ if finished {
|
|
|
+ self?.assetPlayer?.play()
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
func pause(){
|
|
|
- cShowHUB(superView: nil, msg: "暂停播放")
|
|
|
+ BFLog(1, message: "暂停播放")
|
|
|
movie?.cancelProcessing()
|
|
|
assetPlayer?.pause()
|
|
|
- recordPlayer.pause()
|
|
|
+ recordPlayer?.pause()
|
|
|
+ isNormalPlaying = false
|
|
|
}
|
|
|
|
|
|
func fetchVideo(){
|
|
@@ -466,14 +579,18 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
assetPlayer?.replaceCurrentItem(with: item)
|
|
|
}else {
|
|
|
assetPlayer = AVPlayer(playerItem: item)
|
|
|
- avplayerTimeObserver = assetPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 10), queue: DispatchQueue.global()) {[weak self] time in
|
|
|
+ avplayerTimeObserver = assetPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 100), queue: DispatchQueue.global()) {[weak self] time in
|
|
|
// 进度监控
|
|
|
+ self?.currentAssetProgress = time
|
|
|
BFLog(1, message: "curr:\(CMTimeGetSeconds(time))")
|
|
|
if CMTimeGetSeconds(item.duration) > 0, !(self?.isDragingProgressSlder ?? false) {
|
|
|
DispatchQueue.main.async { [weak self] in
|
|
|
self?.progessSilde.value = Float(CMTimeGetSeconds(time) / CMTimeGetSeconds(item.duration))
|
|
|
+ self?.progreddL.text = String(format: "%.2f / %.2f", CMTimeGetSeconds(time), CMTimeGetSeconds(item.duration))
|
|
|
}
|
|
|
}
|
|
|
+ // 播放对应的录音音频
|
|
|
+ self?.playRecord(at: time)
|
|
|
} as? NSKeyValueObservation
|
|
|
}
|
|
|
|
|
@@ -482,6 +599,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
|
|
|
self?.assetPlayer?.seek(to: CMTime.zero)
|
|
|
self?.playBtn.isSelected = false
|
|
|
+ self?.currentPlayRecordIndex = -1
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -499,28 +617,49 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
//MARK: - 录音对应图像绘制
|
|
|
|
|
|
func changeProgress(progress:Float) {
|
|
|
- if let item = assetPlayer?.currentItem {
|
|
|
- let duration = CMTimeGetSeconds(item.duration)
|
|
|
- item.seek(to: CMTime(value: CMTimeValue(progress * Float(duration) * 100), timescale: 100)) { finished in
|
|
|
+ if let duration = assetPlayer?.currentItem?.duration {
|
|
|
+ assetPlayer!.seek(to: CMTime(value: CMTimeValue(progress * Float(CMTimeGetSeconds(duration)) * 100), timescale: 100), toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000)) {[weak self] finished in
|
|
|
if finished{
|
|
|
BFLog(1, message: "拖动成功")
|
|
|
+ self?.movie?.startProcessing()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- func drewRecordProgessLable(){
|
|
|
-
|
|
|
+ func drawOrUpdateRecordProgessLable(){
|
|
|
+ progessSildeBackV.subviews.forEach { vv in
|
|
|
+ vv.removeFromSuperview()
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async {[weak self] in
|
|
|
+ if let totalDur = self?.asset?.duration, totalDur > 0, let list = self?.recordList {
|
|
|
+ let width = self?.progessSildeBackV.width ?? 0
|
|
|
+ let height = self?.progessSildeBackV.height ?? 0
|
|
|
+ list.forEach { model in
|
|
|
+ let lineV = UIView(frame: CGRect(x: model.startTime * width / totalDur , y: 0, width: (model.endTime - model.startTime) * width / totalDur, height: height))
|
|
|
+ lineV.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67")
|
|
|
+ self?.progessSildeBackV.addSubview(lineV)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
extension BFRecordScreenController:GPUImageMovieDelegate {
|
|
|
public func didCompletePlayingMovie(){
|
|
|
BFLog(1, message: "播放结束")
|
|
|
-
|
|
|
+ currentPlayRecordIndex = -1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
extension BFRecordScreenController:AVAudioRecorderDelegate {
|
|
|
-
|
|
|
+ public func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
|
|
|
+ BFLog(1, message: "录音结束")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+extension BFRecordScreenController : AVAudioPlayerDelegate {
|
|
|
+ public func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
|
|
|
+ BFLog(1, message: "录音播放结束")
|
|
|
+ }
|
|
|
}
|