|
@@ -6,6 +6,8 @@
|
|
|
// Copyright © 2021 CocoaPods. All rights reserved.
|
|
|
//
|
|
|
|
|
|
+import AVFAudio
|
|
|
+import AVFoundation
|
|
|
import BFCommonKit
|
|
|
import BFMediaKit
|
|
|
import BFNetRequestKit
|
|
@@ -20,7 +22,7 @@ struct WithDrawModel {
|
|
|
var timestamp: Double
|
|
|
var deletedVoices: [(PQVoiceModel, Int)]?
|
|
|
// add by ak 保存删除的字幕数据用于恢复
|
|
|
- var deletedTittles: [(PQEditSubTitleModel, Int)]?
|
|
|
+ var deletedTittles: [PQEditSubTitleModel]?
|
|
|
}
|
|
|
|
|
|
public class BFRecordScreenController: BFBaseViewController {
|
|
@@ -67,7 +69,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
var currentAssetProgress: CMTime = .zero {
|
|
|
didSet {
|
|
|
- BFLog(3,message: "currentAssetProgress=\(currentAssetProgress.seconds)")
|
|
|
+ BFLog(3, message: "currentAssetProgress=\(currentAssetProgress.seconds)")
|
|
|
}
|
|
|
} // 当前素材播放的进度
|
|
|
// 播放器开始播放时间
|
|
@@ -132,11 +134,12 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
lazy var progreddL: UILabel = {
|
|
|
let l = UILabel()
|
|
|
l.textAlignment = .center
|
|
|
- l.font = UIFont.systemFont(ofSize: 13)
|
|
|
+ l.font = UIFont.systemFont(ofSize: 13, weight: .medium)
|
|
|
l.textColor = .white
|
|
|
- l.shadowColor = .black
|
|
|
- l.shadowOffset = CGSize(width: 0, height: 1)
|
|
|
- l.layer.opacity = 0.4
|
|
|
+ l.layer.shadowOpacity = 0.4
|
|
|
+ l.layer.shadowColor = UIColor.black.cgColor
|
|
|
+ l.layer.shadowOffset = CGSize(width: 0, height: 2)
|
|
|
+ l.layer.shadowRadius = 2
|
|
|
l.text = "00:00"
|
|
|
return l
|
|
|
}()
|
|
@@ -423,6 +426,19 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
endRecord()
|
|
|
}
|
|
|
|
|
|
+ /// 线路切换
|
|
|
+ /// - Parameter nofify: <#nofify description#>
|
|
|
+ @objc func routeChangeNofify(nofify: Notification) {
|
|
|
+ let routeChangeDic = nofify.userInfo
|
|
|
+ let routeChangeReason: AVAudioSession.RouteChangeReason? = AVAudioSession.RouteChangeReason(rawValue: UInt((routeChangeDic?[AVAudioSessionRouteChangeReasonKey] as? Int) ?? 0))
|
|
|
+ if routeChangeReason == .oldDeviceUnavailable {
|
|
|
+ let previousRoute = routeChangeDic?[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription
|
|
|
+ if previousRoute?.outputs.first?.portType == .headphones {
|
|
|
+ playVideo(btn: playBtn)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
override public func viewWillAppear(_ animated: Bool) {
|
|
|
super.viewWillAppear(animated)
|
|
|
navigationController?.isNavigationBarHidden = true
|
|
@@ -440,7 +456,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
// 进入活跃状态
|
|
|
PQNotification.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
|
|
|
-
|
|
|
+ PQNotification.addObserver(self, selector: #selector(routeChangeNofify(nofify:)), name: AVAudioSession.routeChangeNotification, object: nil)
|
|
|
// 进入非活跃状态
|
|
|
PQNotification.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
|
|
|
|
|
@@ -476,14 +492,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let header = dicResult?["header"] as? [String: Any]
|
|
|
let payload = dicResult?["payload"] as? [String: Any]
|
|
|
|
|
|
- BFLog(1, message: "识别结果:) \((payload)!),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 为开始的录制的时间,开始和结束都要加上这个时差
|
|
|
|
|
|
let newSubtitle = PQEditSubTitleModel()
|
|
|
// 任务全局唯一ID,请记录该值,便于排查问题。 每次 startRecorder 和 stopRecoder 之间 task_Id都不会变化
|
|
|
newSubtitle.taskID = (header?["task_id"] as? String) ?? ""
|
|
|
-
|
|
|
BFLog(1, message: "对应关系:字幕所属地址:\((audioFilePath ?? "b").replacingOccurrences(of: documensDirectory, with: "")), 开始录音输入:\((self?.recorderManager?.voiceModel?.wavFilePath ?? "aa").replacingOccurrences(of: documensDirectory, with: ""))")
|
|
|
// 这里加300ms 是因为返回结果为了切到字,时长提前一些时间,具体时间官方没说和原音频有关系。这里我们先延后300ms 单位:毫秒。
|
|
|
if let audioUrl = audioFilePath, URL(fileURLWithPath: audioUrl).deletingPathExtension().lastPathComponent.contains(URL(fileURLWithPath: self?.recorderManager?.voiceModel?.wavFilePath ?? "aa").deletingPathExtension().lastPathComponent) {
|
|
@@ -508,7 +524,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(1, message: "卡在录音尾巴上了1")
|
|
|
newSubtitle.timelineIn = newSubtitle.timelineIn - CMTime(seconds: 0.1, preferredTimescale: 1000)
|
|
|
}
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
BFLog(1, message: "没有对应音频播放记录,出现错误!!!!!!")
|
|
|
return
|
|
|
}
|
|
@@ -530,12 +546,13 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
|
|
|
// MARK: - 录音结束
|
|
|
+
|
|
|
recorderManager?.endRecordHandle = { [weak self, weak recorderManager] voideModel, _ in
|
|
|
if let sself = self, let model = voideModel, FileManager.default.fileExists(atPath: model.wavFilePath ?? "") {
|
|
|
// 加入到语音数组里
|
|
|
-
|
|
|
+
|
|
|
model.endCMTime = sself.currentAssetProgress
|
|
|
- BFLog(1, message: "对应关系:录制结束文件地址:\((model.wavFilePath ?? "") .replacingOccurrences(of: documensDirectory, with: "")) 开始录音前地址:\((self?.recorderManager?.voiceModel?.wavFilePath ?? "aa").replacingOccurrences(of: documensDirectory, with: ""))- \(model.startCMTime.seconds)-\(model.endCMTime.seconds)-\(model.endCMTime.seconds - model.startCMTime.seconds)")
|
|
|
+ BFLog(1, message: "对应关系:录制结束文件地址:\((model.wavFilePath ?? "").replacingOccurrences(of: documensDirectory, with: "")) 开始录音前地址:\((self?.recorderManager?.voiceModel?.wavFilePath ?? "aa").replacingOccurrences(of: documensDirectory, with: ""))- \(model.startCMTime.seconds)-\(model.endCMTime.seconds)-\(model.endCMTime.seconds - model.startCMTime.seconds)")
|
|
|
/// 注:录音机回调的录音时长大于一秒,而业务逻辑计算的会小于一秒
|
|
|
if (model.endCMTime.seconds - model.startCMTime.seconds) < 1 {
|
|
|
// 取消录制
|
|
@@ -547,7 +564,9 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
var deletedVoices = [(PQVoiceModel, Int)]()
|
|
|
// 要删除的字幕
|
|
|
- var deletedTitlesTemp = [(PQEditSubTitleModel, Int)]()
|
|
|
+ var deletedTitlesTemp = [PQEditSubTitleModel]()
|
|
|
+
|
|
|
+ // 查找要删除的音频和字幕数据
|
|
|
for (i, m) in sself.itemModels[sself.currItemModelIndex].voiceStickers.enumerated() {
|
|
|
let originRange = CMTimeRange(start: m.startCMTime, end: CMTime(seconds: m.endCMTime.seconds - 0.02, preferredTimescale: 1000))
|
|
|
if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0 {
|
|
@@ -562,6 +581,8 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
m.wavFilePath == tempM.wavFilePath
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
BFLog(1, message: "添加录音文件:\(model.startCMTime.seconds) -- \(model.endCMTime.seconds)")
|
|
|
sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
|
|
|
// 如果是图片素材同时有需要删除的录音时需要调整录音文件开始结束时间
|
|
@@ -620,8 +641,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
sself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
|
|
|
BFLog(3, message: "重置播放index-\(#function) = \(sself.currentPlayRecordIndex)")
|
|
|
recorderManager?.voiceModel = nil
|
|
|
- }
|
|
|
- else{
|
|
|
+ } else {
|
|
|
BFLog(2, message: "数据出错!!!!\(voideModel?.wavFilePath ?? "")")
|
|
|
}
|
|
|
}
|
|
@@ -781,7 +801,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
progreddL.snp.makeConstraints { make in
|
|
|
make.width.equalTo(100)
|
|
|
make.centerX.equalToSuperview()
|
|
|
- make.top.equalToSuperview().offset(-8)
|
|
|
+ make.top.equalToSuperview().offset(-5)
|
|
|
make.height.equalTo(18)
|
|
|
}
|
|
|
|
|
@@ -920,22 +940,19 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
/// 删除指定段落的所有字幕 数据
|
|
|
/// - Parameter voiceModel: 删除的音频数据
|
|
|
- func deleteTitles(voiceModel: PQVoiceModel) -> [(PQEditSubTitleModel, Int)] {
|
|
|
+ func deleteTitles(voiceModel: PQVoiceModel) -> [PQEditSubTitleModel] {
|
|
|
BFLog(message: "itemModels[currItemModelIndex].titleStickers 删除前:\(itemModels[currItemModelIndex].titleStickers.count) model.startCMTime.seconds: \(voiceModel.startCMTime.seconds) model.end: \(voiceModel.endCMTime.seconds)")
|
|
|
- var deleteTemp = [(PQEditSubTitleModel, Int)]()
|
|
|
+ var deleteTemp = [PQEditSubTitleModel]()
|
|
|
|
|
|
- for (ind, sticker) in itemModels[currItemModelIndex].titleStickers.enumerated() {
|
|
|
- if sticker.audioFilePath == voiceModel.wavFilePath {
|
|
|
- deleteTemp.append((sticker, ind))
|
|
|
- }
|
|
|
- }
|
|
|
// 从原数组中删除
|
|
|
- let arr = itemModels[currItemModelIndex].titleStickers.filter { model in
|
|
|
- !deleteTemp.contains { tuple in
|
|
|
- tuple.0.audioFilePath == model.audioFilePath
|
|
|
+ itemModels[currItemModelIndex].titleStickers.removeAll { m in
|
|
|
+ let su = (m.audioFilePath == voiceModel.wavFilePath)
|
|
|
+ if su {
|
|
|
+ deleteTemp.append(m)
|
|
|
}
|
|
|
+ return su
|
|
|
}
|
|
|
- itemModels[currItemModelIndex].titleStickers = arr
|
|
|
+
|
|
|
BFLog(message: "itemModels[currItemModelIndex].titleStickers 删除后:\(itemModels[currItemModelIndex].titleStickers.count)")
|
|
|
|
|
|
// 清空字幕UI
|
|
@@ -953,7 +970,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
var event = WithDrawModel(type: 3, timestamp: currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)])
|
|
|
event.deletedTittles = deleteTitles(voiceModel: model)
|
|
|
events.append(event)
|
|
|
-
|
|
|
+
|
|
|
// 注:删除录音后图片素材需要回撤指针进度,同时后面录音往前挪
|
|
|
if itemModels[currItemModelIndex].mediaType == .IMAGE {
|
|
|
let currDuration = model.endCMTime.seconds - model.startCMTime.seconds
|
|
@@ -974,6 +991,11 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
/// 重绘录音进度视图
|
|
|
resetAllIndirectionView()
|
|
|
+
|
|
|
+ // 判断是否无录音了
|
|
|
+ if itemModels[currItemModelIndex].materialDuraion == 0 {
|
|
|
+ playBtn.isSelected = true
|
|
|
+ }
|
|
|
}
|
|
|
searchStopAtRecordRange()
|
|
|
changeWithDrawBtnLayout(3)
|
|
@@ -1004,6 +1026,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ recorderManager?.cancelTitleService()
|
|
|
// 开始时间
|
|
|
beginOnStartBtn = true
|
|
|
isRecording = true
|
|
@@ -1015,7 +1038,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
model.currIndex = currItemModelIndex
|
|
|
model.volume = 100
|
|
|
recorderManager?.voiceModel = model
|
|
|
- BFLog(3,message: "开始录制-开始:currentAssetProgress=\(currentAssetProgress.seconds),cuInde=\(currItemModelIndex),\(model)")
|
|
|
+ BFLog(3, message: "开始录制-开始:currentAssetProgress=\(currentAssetProgress.seconds),cuInde=\(currItemModelIndex),\(model)")
|
|
|
recorderManager?.startRecord()
|
|
|
recorderManager?.audioRecorder?.startNeoNui(NeoNuiToken ?? "", appid: NeoNuiAPPID ?? "")
|
|
|
isRecording = true
|
|
@@ -1049,10 +1072,10 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
beginOnStartBtn = false
|
|
|
|
|
|
recordBtn.isEnabled = false
|
|
|
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {[weak self] in
|
|
|
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
|
|
|
self?.recordBtn.isEnabled = true
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
isRecording = false
|
|
|
// progressThumV.progressView.isUserInteractionEnabled = true
|
|
|
// collectionView.isScrollEnabled = true
|
|
@@ -1078,7 +1101,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
if !avatarView.isHidden {
|
|
|
avatarView.endRecord()
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
@objc func cancleRecord() {
|
|
@@ -1093,7 +1115,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
/// 不足一秒,主动取消录制
|
|
|
/// - Parameter voiceModel: <#voiceModel description#>
|
|
|
@objc func recordManagerCancelRecord(voiceModel: PQVoiceModel?) {
|
|
|
- BFLog(3,message: "开始录制-取消:currentAssetProgress=\(currentAssetProgress.seconds),cuInde=\(currItemModelIndex),currIndex=\(voiceModel?.currIndex ?? 0),\(String(describing: voiceModel)),\(String(describing:recorderManager?.voiceModel))")
|
|
|
+ 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秒")
|
|
|
}
|
|
@@ -1138,13 +1160,12 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let model = itemModels[currItemModelIndex].voiceStickers[modelIndex]
|
|
|
itemModels[currItemModelIndex].voiceStickers.remove(at: modelIndex)
|
|
|
indirectionView?.deleteItem(index: modelIndex)
|
|
|
+
|
|
|
// 删除对应字幕
|
|
|
- let deleteTitiles = deleteTitles(voiceModel: model)
|
|
|
- for title in deleteTitiles {
|
|
|
- itemModels[currItemModelIndex].titleStickers.removeAll { model in
|
|
|
- title.0.timelineIn == model.timelineIn
|
|
|
- }
|
|
|
+ itemModels[currItemModelIndex].titleStickers.removeAll { m in
|
|
|
+ m.audioFilePath == model.wavFilePath
|
|
|
}
|
|
|
+
|
|
|
// 恢复被覆盖的音频
|
|
|
var tuples = action.deletedVoices
|
|
|
if tuples != nil, tuples!.count > 0 {
|
|
@@ -1159,7 +1180,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let titleTuples = action.deletedTittles
|
|
|
if titleTuples != nil, titleTuples!.count > 0 {
|
|
|
titleTuples?.forEach { titleTuple in
|
|
|
- itemModels[currItemModelIndex].titleStickers.insert(titleTuple.0, at: titleTuple.1)
|
|
|
+ itemModels[currItemModelIndex].titleStickers.append(titleTuple)
|
|
|
}
|
|
|
}
|
|
|
jumpTime = model.startCMTime.seconds
|
|
@@ -1200,7 +1221,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let titleTuples = action.deletedTittles
|
|
|
if titleTuples != nil, titleTuples!.count > 0 {
|
|
|
titleTuples?.forEach { titleTuple in
|
|
|
- itemModels[currItemModelIndex].titleStickers.insert(titleTuple.0, at: titleTuple.1)
|
|
|
+ itemModels[currItemModelIndex].titleStickers.append(titleTuple)
|
|
|
}
|
|
|
}
|
|
|
if itemModels[currItemModelIndex].mediaType == .IMAGE {
|
|
@@ -1247,6 +1268,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
@objc func playVideo(btn: UIButton) {
|
|
|
if itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0 {
|
|
|
BFLog(message: "图片没有录音无法播放")
|
|
|
+ btn.isSelected = true
|
|
|
return
|
|
|
}
|
|
|
btn.isSelected = !btn.isSelected
|
|
@@ -1400,7 +1422,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
// MARK: - 音视频处理
|
|
|
|
|
|
func playRecord(at currentT: CMTime, periodicTimeObserver: @escaping (_ time: CMTime, _ currentItem: AVPlayerItem) -> Void, didPlayToEndTime: @escaping (_ recordedInfo: (Int, PQVoiceModel)?, _ currentItem: AVPlayerItem?) -> Void, playFailed _: @escaping (_ recordedInfo: (Int, PQVoiceModel)?, _ currentItem: AVPlayerItem?) -> Void) {
|
|
|
-
|
|
|
// if currentPlayRecordIndex >= 0 {
|
|
|
// if assetPlayer?.volume != haveSpeakVolume{
|
|
|
// assetPlayer?.volume = haveSpeakVolume
|
|
@@ -1410,23 +1431,23 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
// assetPlayer?.volume = noSpeakVolume
|
|
|
// }
|
|
|
// }
|
|
|
-
|
|
|
+
|
|
|
if itemModels[currItemModelIndex].voiceStickers.first(where: { m in
|
|
|
- return CMTimeCompare(m.startCMTime, currentT) <= 0 && CMTimeCompare(currentT, m.endCMTime) <= 0
|
|
|
- }) != nil{
|
|
|
- if assetPlayer?.volume != haveSpeakVolume{
|
|
|
+ CMTimeCompare(m.startCMTime, currentT) <= 0 && CMTimeCompare(currentT, m.endCMTime) <= 0
|
|
|
+ }) != nil {
|
|
|
+ if assetPlayer?.volume != haveSpeakVolume {
|
|
|
assetPlayer?.volume = haveSpeakVolume
|
|
|
}
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
if assetPlayer?.volume != noSpeakVolume {
|
|
|
assetPlayer?.volume = noSpeakVolume
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 先排序,再查找下一个需要播放的录音
|
|
|
let list = itemModels[currItemModelIndex].voiceStickers.sorted { m1, m2 in
|
|
|
m1.startCMTime.seconds < m2.startCMTime.seconds
|
|
@@ -1434,14 +1455,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let (shouldPlayRecordIndex, recordedAudio) = list.enumerated().first { model in
|
|
|
model.1.endCMTime.seconds > CMTimeGetSeconds(currentT)
|
|
|
} ?? (-1, nil)
|
|
|
-
|
|
|
+
|
|
|
// 没找到,代表后边没有录音需求了
|
|
|
guard let recordedAudio = recordedAudio, recordedAudio.wavFilePath.count > 0 else {
|
|
|
BFLog(3, message: "未找到可播放录音")
|
|
|
return
|
|
|
}
|
|
|
BFLog(1, message: "当前时间:\(CMTimeGetSeconds(currentT)), 找到的音频:\(recordedAudio.startCMTime.seconds) ~ \(recordedAudio.endCMTime.seconds), \(recordedAudio.wavFilePath ?? "")")
|
|
|
-
|
|
|
+
|
|
|
// 创建播放器
|
|
|
if recordPlayer == nil || (recordPlayer?.currentItem?.asset as? AVURLAsset)?.url.lastPathComponent != (recordedAudio.wavFilePath as NSString?)?.lastPathComponent {
|
|
|
let newItem = AVPlayerItem(url: URL(fileURLWithPath: recordedAudio.wavFilePath))
|
|
@@ -1475,7 +1496,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
recordPlayerTimeObserver?.invalidate()
|
|
|
recordPlayerTimeObserver = recordPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 1000), queue: DispatchQueue.global()) { [weak self, weak recordPlayer] time in
|
|
|
- guard let sself = self,let rPlay = recordPlayer else {
|
|
|
+ guard let sself = self, let rPlay = recordPlayer else {
|
|
|
BFLog(3, message: "sself为空")
|
|
|
return
|
|
|
}
|
|
@@ -1593,6 +1614,10 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
func play() {
|
|
|
BFLog(1, message: "开始播放 \(currentAssetProgress.seconds)")
|
|
|
recorderManager?.voiceModel = nil
|
|
|
+
|
|
|
+ itemModels[currItemModelIndex].titleStickers.sort { m1, m2 in
|
|
|
+ m1.timelineIn < m2.timelineIn
|
|
|
+ }
|
|
|
|
|
|
isNormalPlaying = true
|
|
|
if isEndPlay {
|
|
@@ -1611,7 +1636,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
movie?.startProcessing()
|
|
|
movieIsProcessing = true
|
|
|
}
|
|
|
- //add by ak 切换段落时会有一小段原素材的声音播放时先把视频原音量设置为0
|
|
|
+ // add by ak 切换段落时会有一小段原素材的声音播放时先把视频原音量设置为0
|
|
|
assetPlayer?.volume = 0
|
|
|
assetPlayer?.play()
|
|
|
} else {
|
|
@@ -1630,14 +1655,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
func pause() {
|
|
|
BFLog(1, message: "暂停播放")
|
|
|
isNormalPlaying = false
|
|
|
-
|
|
|
+
|
|
|
// ---- 修复暂停播放回退问题
|
|
|
avplayerTimeObserver?.invalidate()
|
|
|
avplayerTimeObserver = nil
|
|
|
recordPlayerTimeObserver?.invalidate()
|
|
|
recordPlayerTimeObserver = nil
|
|
|
// ----
|
|
|
-
|
|
|
+
|
|
|
subtitleBtn.isHidden = false
|
|
|
soundSettingBtn.isHidden = false
|
|
|
withDrawBtn.isHidden = false
|
|
@@ -1649,7 +1674,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
pauseTime = currentAssetProgress.seconds
|
|
|
currentPlayRecordIndex = -1
|
|
|
hadPrepareToPlayRecord = false
|
|
|
-
|
|
|
+
|
|
|
// 暂停状态
|
|
|
playBtn.isSelected = (itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0)
|
|
|
}
|
|
@@ -1980,10 +2005,11 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
|
|
|
public func collectionView(_: UICollectionView, didSelectItemAt _: IndexPath) {}
|
|
|
|
|
|
- public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
|
|
+ public func scrollViewWillBeginDragging(_: UIScrollView) {
|
|
|
BFLog(1, message: "开始滚动")
|
|
|
recordBtn.isEnabled = false
|
|
|
}
|
|
|
+
|
|
|
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
|
|
endScrollItem(scrollView)
|
|
|
}
|
|
@@ -1997,7 +2023,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
func endScrollItem(_ scrollView: UIScrollView) {
|
|
|
// public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
|
BFLog(1, message: "滚动结束")
|
|
|
-
|
|
|
+
|
|
|
let page = Int((scrollView.contentOffset.x + scrollView.frame.width / 2) / scrollView.frame.width)
|
|
|
if page != currItemModelIndex {
|
|
|
// 切换素材时先把录制状态切为不可用,延迟可点,避免在缩略图未加载出来时即可录制
|
|
@@ -2038,10 +2064,10 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
// 重置播放器
|
|
|
assetPlayer?.seek(to: CMTime.zero)
|
|
|
recordPlayer?.seek(to: CMTime.zero)
|
|
|
-
|
|
|
+
|
|
|
if let voice = itemModels[page].voiceStickers.enumerated().first(where: { m in
|
|
|
m.1.startTime == 0
|
|
|
- }){
|
|
|
+ }) {
|
|
|
currentPlayRecordIndex = voice.0
|
|
|
}
|
|
|
|
|
@@ -2091,7 +2117,7 @@ public extension BFRecordScreenController {
|
|
|
recordStartPlayTime = currentAssetProgress
|
|
|
currenStartPlayTime = CMTime.zero
|
|
|
}
|
|
|
- playRecord(at: time, periodicTimeObserver: { [weak self] currentT, currentItem in
|
|
|
+ playRecord(at: time, periodicTimeObserver: { [weak self] currentT, _ in
|
|
|
// BFLog(1, message: "播放录音进度:\(currentT.seconds),\(currentItem)")
|
|
|
if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE, self?.isNormalPlaying ?? false {
|
|
|
self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
|