|
@@ -74,10 +74,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
if isSuccess, let sticker = sticker{
|
|
if isSuccess, let sticker = sticker{
|
|
wself.rscurrentManager.currentAssetProgress = sticker.timelineCMOut
|
|
wself.rscurrentManager.currentAssetProgress = sticker.timelineCMOut
|
|
- let dur = wself.rscmanager.recordItem?.videoStickers.reduce(0, { partialResult, mod in
|
|
|
|
- (mod.timelineCMOut - mod.timelineCMIn).seconds + partialResult
|
|
|
|
- })
|
|
|
|
- wself.rscmanager.recordItem?.materialDuraion = CMTime(seconds: dur ?? 0, preferredTimescale: 1000)
|
|
|
|
// BFLog(1, message: "camera:\(sticker.timelineCMIn.seconds) ~ \(sticker.timelineCMOut.seconds)")
|
|
// BFLog(1, message: "camera:\(sticker.timelineCMIn.seconds) ~ \(sticker.timelineCMOut.seconds)")
|
|
}else{
|
|
}else{
|
|
wself.withdrawAction()
|
|
wself.withdrawAction()
|
|
@@ -1067,109 +1063,97 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
if let model = voideModel, FileManager.default.fileExists(atPath: model.wavFilePath ?? "") {
|
|
if let model = voideModel, FileManager.default.fileExists(atPath: model.wavFilePath ?? "") {
|
|
// 加入到语音数组里
|
|
// 加入到语音数组里
|
|
-
|
|
|
|
model.endCMTime = wself.currentAssetProgress
|
|
model.endCMTime = wself.currentAssetProgress
|
|
-// BFLog(1, message: "录音地址:\((model.wavFilePath ?? "").replacingOccurrences(of: documensDirectory, with: ""))")
|
|
|
|
|
|
+
|
|
BFLog(1, message: " 文件时长record:\(wself.rscmanager.recordItem?.voiceStickers.count ?? 0), \(model.startCMTime.seconds) -- \(model.endCMTime.seconds), dur: \(model.endCMTime.seconds - model.startCMTime.seconds)")
|
|
BFLog(1, message: " 文件时长record:\(wself.rscmanager.recordItem?.voiceStickers.count ?? 0), \(model.startCMTime.seconds) -- \(model.endCMTime.seconds), dur: \(model.endCMTime.seconds - model.startCMTime.seconds)")
|
|
- wself.recordFinished((model.endCMTime.seconds - model.startCMTime.seconds) >= 1)
|
|
|
|
-
|
|
|
|
|
|
+
|
|
/// 注:录音机回调的录音时长大于一秒,而业务逻辑计算的会小于一秒
|
|
/// 注:录音机回调的录音时长大于一秒,而业务逻辑计算的会小于一秒
|
|
if (model.endCMTime.seconds - model.startCMTime.seconds) < 1 {
|
|
if (model.endCMTime.seconds - model.startCMTime.seconds) < 1 {
|
|
// 取消录制
|
|
// 取消录制
|
|
|
|
+ wself.recordFinished(false)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- // ********** 开始处理冲突的录制部分
|
|
|
|
- let newRange = CMTimeRange(start: model.startCMTime, end: model.endCMTime)
|
|
|
|
-
|
|
|
|
- var deletedVoices = [PQVoiceModel]()
|
|
|
|
- // 要删除的字幕
|
|
|
|
- var deletedTitlesTemp = [PQEditSubTitleModel]()
|
|
|
|
-
|
|
|
|
- // 查找要删除的音频和字幕数据
|
|
|
|
- for m in wself.itemModels[wself.currItemModelIndex].voiceStickers {
|
|
|
|
- let originRange = CMTimeRange(start: m.startCMTime, end: CMTime(seconds: m.endCMTime.seconds - 0.02, preferredTimescale: 1000))
|
|
|
|
- if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0 {
|
|
|
|
- deletedVoices.append(m)
|
|
|
|
- deletedTitlesTemp += wself.deleteTitles(voiceModel: m)
|
|
|
|
- continue
|
|
|
|
|
|
+
|
|
|
|
+ if wself.currMediaType == .Video {
|
|
|
|
+ // ********** 开始处理冲突的录制部分
|
|
|
|
+ wself.overrideRecordDeal(model: model)
|
|
|
|
+
|
|
|
|
+ }else if wself.currMediaType == .Image {
|
|
|
|
+
|
|
|
|
+ if let recordItem = wself.rsimanager.recordItem {
|
|
|
|
+
|
|
|
|
+ let duration = model.endCMTime - model.startCMTime
|
|
|
|
+
|
|
|
|
+ recordItem.voiceStickers.forEach({ mod in
|
|
|
|
+ if mod.startCMTime.seconds >= model.startCMTime.seconds {
|
|
|
|
+ mod.startCMTime = mod.startCMTime + duration
|
|
|
|
+ mod.endCMTime = mod.endCMTime + duration
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ recordItem.voiceChangeStickers.forEach({ mod in
|
|
|
|
+ if mod.startCMTime.seconds >= model.startCMTime.seconds {
|
|
|
|
+ mod.startCMTime = mod.startCMTime + duration
|
|
|
|
+ mod.endCMTime = mod.endCMTime + duration
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ recordItem.titleStickers.forEach({ mod in
|
|
|
|
+ if mod.timelineIn.seconds >= model.startCMTime.seconds {
|
|
|
|
+ mod.timelineIn = mod.timelineIn + duration
|
|
|
|
+ mod.timelineOut = mod.timelineOut + duration
|
|
|
|
+ }
|
|
|
|
+ })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- // 删除冲突的音频
|
|
|
|
- deletedVoices.forEach { m in
|
|
|
|
- wself.itemModels[wself.currItemModelIndex].voiceStickers.removeAll { tempM in
|
|
|
|
- m.wavFilePath == tempM.wavFilePath
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ wself.itemModels[wself.currItemModelIndex].voiceStickers.append(model)
|
|
|
|
+ wself.itemModels[wself.currItemModelIndex].voiceStickers.sort { m1, m2 in
|
|
|
|
+ m1.startCMTime.seconds < m2.startCMTime.seconds
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 录制结束manager处理
|
|
|
|
+ wself.recordFinished(true)
|
|
|
|
|
|
- wself.itemModels[wself.currItemModelIndex].voiceStickers.append(model)
|
|
|
|
// 录制结束回调给主工程页面(埋点之类功能)
|
|
// 录制结束回调给主工程页面(埋点之类功能)
|
|
wself.recordEndHandle?(model)
|
|
wself.recordEndHandle?(model)
|
|
- // 如果是图片素材同时有需要删除的录音时需要调整录音文件开始结束时间
|
|
|
|
- // warning: 图片录制的时候应该只能在结尾处录制
|
|
|
|
- if wself.currMediaType == .Image {
|
|
|
|
- if deletedVoices.count > 0 {
|
|
|
|
- // 如果是图片先排序在计算区间
|
|
|
|
- wself.itemModels[wself.currItemModelIndex].voiceStickers = wself.itemModels[wself.currItemModelIndex].voiceStickers.sorted { voice1, voice2 in
|
|
|
|
- voice1.startCMTime.seconds < voice2.startCMTime.seconds
|
|
|
|
- }
|
|
|
|
- for (index, item) in wself.itemModels[wself.currItemModelIndex].voiceStickers.enumerated() {
|
|
|
|
- if index > 0 {
|
|
|
|
- // 注:开始时间减去duration or 等一前一段录音的结束时间
|
|
|
|
- let tempDuration = item.endCMTime.seconds - item.startCMTime.seconds
|
|
|
|
- item.startCMTime = CMTime(seconds: wself.itemModels[wself.currItemModelIndex].voiceStickers[index - 1].endCMTime.seconds, preferredTimescale: 1000)
|
|
|
|
- item.endCMTime = CMTime(seconds: item.startCMTime.seconds + tempDuration, preferredTimescale: 1000)
|
|
|
|
- }
|
|
|
|
- BFLog(1, message: "录制结束重新排序录音文件:\(index)-\(item.wavFilePath ?? "")-\(item.startCMTime.seconds)-\(item.endCMTime.seconds)-\(item.endCMTime.seconds - item.startCMTime.seconds)")
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // ***********处理冲突的录音部分资源 end
|
|
|
|
|
|
|
|
if wself.currMediaType != .Video {
|
|
if wself.currMediaType != .Video {
|
|
- var duration: CMTime = .zero
|
|
|
|
- if wself.currMediaType == .Image{
|
|
|
|
- wself.itemModels[wself.currItemModelIndex].voiceStickers.forEach { temp in
|
|
|
|
- BFLog(1, message: "录制结束-最终:\(temp.wavFilePath ?? "")-\(temp.startCMTime.seconds)-\(temp.endCMTime.seconds)-\(temp.endCMTime.seconds - temp.startCMTime.seconds)")
|
|
|
|
- temp.duration = "\(temp.endCMTime.seconds - temp.startCMTime.seconds)"
|
|
|
|
- duration = duration + temp.endCMTime - temp.startCMTime
|
|
|
|
- }
|
|
|
|
- wself.itemModels[wself.currItemModelIndex].materialDuraion = duration
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
wself.isEndPlay = true
|
|
wself.isEndPlay = true
|
|
- // 录制结束显示播放按钮
|
|
|
|
- if wself.currMediaType == .Camera {
|
|
|
|
- wself.playBtn.isSelected = true
|
|
|
|
- wself.playBtn.isHidden = true
|
|
|
|
- }else {
|
|
|
|
- wself.playBtn.isSelected = wself.itemModels[wself.currItemModelIndex].voiceStickers.count <= 0
|
|
|
|
- wself.playBtn.isHidden = wself.playBtn.isSelected
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
DispatchQueue.main.async { [weak self] in
|
|
DispatchQueue.main.async { [weak self] in
|
|
guard let wself = self else { return }
|
|
guard let wself = self else { return }
|
|
|
|
|
|
- // 录音完,重绘撤销按钮,更新录音按钮,
|
|
|
|
|
|
+ // 更新playbtn按钮状态
|
|
|
|
+ wself.updatePlayBtnStatus()
|
|
|
|
+
|
|
|
|
+ // 更新录音按钮状态
|
|
|
|
+ wself.updateRecordBtnStatus(false)
|
|
|
|
+
|
|
|
|
+ // 录音完,更新撤销按钮
|
|
wself.changeWithDrawBtnLayout(2)
|
|
wself.changeWithDrawBtnLayout(2)
|
|
|
|
+
|
|
// 注:在录制结束时矫正当前位置,避免跟指针无法对其
|
|
// 注:在录制结束时矫正当前位置,避免跟指针无法对其
|
|
wself.indirectionView?.resetCurrentItem(start: model.startCMTime.seconds, end: model.endCMTime.seconds)
|
|
wself.indirectionView?.resetCurrentItem(start: model.startCMTime.seconds, end: model.endCMTime.seconds)
|
|
- if deletedVoices.count > 0 {
|
|
|
|
- /// 重绘录音进度视图
|
|
|
|
- wself.resetAllIndirectionView()
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ // 重置底部蓝色录音条
|
|
|
|
+ wself.resetAllIndirectionView()
|
|
|
|
+
|
|
// 矫正进度
|
|
// 矫正进度
|
|
wself.resetCurrentProgress()
|
|
wself.resetCurrentProgress()
|
|
- wself.deleteRecordBtn.isHidden = true
|
|
|
|
- wself.recordBtn.isHidden = (wself.currMediaType != .Video && (wself.isEndPlay )) ? false : (wself.isEndPlay )
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
wself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
|
|
wself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
|
|
BFLog(3, message: "重置播放index-\(#function) = \(wself.currentPlayRecordIndex)")
|
|
BFLog(3, message: "重置播放index-\(#function) = \(wself.currentPlayRecordIndex)")
|
|
recorderManager?.voiceModel = nil
|
|
recorderManager?.voiceModel = nil
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
wself.rscurrentManager.recordFinished(isSuccess: false)
|
|
wself.rscurrentManager.recordFinished(isSuccess: false)
|
|
BFLog(2, message: "数据出错!!!!\(voideModel?.wavFilePath ?? "")")
|
|
BFLog(2, message: "数据出错!!!!\(voideModel?.wavFilePath ?? "")")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
recorderManager?.cancelRecordHandle = { [weak self] voiceModel in
|
|
recorderManager?.cancelRecordHandle = { [weak self] voiceModel in
|
|
guard let wself = self else { return }
|
|
guard let wself = self else { return }
|
|
// 取消录制
|
|
// 取消录制
|
|
@@ -1194,7 +1178,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
cShowHUB(superView: wself.view, msg: msg)
|
|
cShowHUB(superView: wself.view, msg: msg)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@objc func editSubtitle() {
|
|
@objc func editSubtitle() {
|
|
@@ -1795,15 +1778,18 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
case .Video:
|
|
case .Video:
|
|
playBtn.isSelected = false
|
|
playBtn.isSelected = false
|
|
- playBtn.isHidden = false
|
|
|
|
|
|
+ playBtn.isHidden = playBtn.isSelected
|
|
|
|
+
|
|
case .Camera:
|
|
case .Camera:
|
|
playBtn.isSelected = isEndPlay ? true : ((rscmanager.recordItem?.voiceStickers.count ?? -1) <= 0)
|
|
playBtn.isSelected = isEndPlay ? true : ((rscmanager.recordItem?.voiceStickers.count ?? -1) <= 0)
|
|
playBtn.isHidden = playBtn.isSelected
|
|
playBtn.isHidden = playBtn.isSelected
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- func updateRecordBtnStatus(_ show:Bool? = nil){
|
|
|
|
- let su = show ?? false
|
|
|
|
|
|
+ /// 更新录音按钮状态
|
|
|
|
+ /// - Parameter hidden: 是否隐藏
|
|
|
|
+ func updateRecordBtnStatus(_ hidden:Bool? = nil){
|
|
|
|
+ let su = hidden ?? false
|
|
switch currMediaType {
|
|
switch currMediaType {
|
|
case .Image:
|
|
case .Image:
|
|
recordBtn.isHidden = (isEndPlay || canInsertVideo) ? false : su
|
|
recordBtn.isHidden = (isEndPlay || canInsertVideo) ? false : su
|
|
@@ -1870,6 +1856,30 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ func overrideRecordDeal(model: PQVoiceModel){
|
|
|
|
+ // ********** 开始处理冲突的录制部分
|
|
|
|
+ let newRange = CMTimeRange(start: model.startCMTime, end: model.endCMTime)
|
|
|
|
+
|
|
|
|
+ var deletedVoices = [PQVoiceModel]()
|
|
|
|
+ // 要删除的字幕
|
|
|
|
+ var deletedTitlesTemp = [PQEditSubTitleModel]()
|
|
|
|
+
|
|
|
|
+ // 查找要删除的音频和字幕数据
|
|
|
|
+ for m in itemModels[currItemModelIndex].voiceStickers {
|
|
|
|
+ let originRange = CMTimeRange(start: m.startCMTime, end: CMTime(seconds: m.endCMTime.seconds - 0.02, preferredTimescale: 1000))
|
|
|
|
+ if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0 {
|
|
|
|
+ deletedVoices.append(m)
|
|
|
|
+ deletedTitlesTemp += deleteTitles(voiceModel: m)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 删除冲突的音频
|
|
|
|
+ deletedVoices.forEach { m in
|
|
|
|
+ itemModels[currItemModelIndex].voiceStickers.removeAll { tempM in
|
|
|
|
+ m.wavFilePath == tempM.wavFilePath
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
// MARK: - 权限申请
|
|
// MARK: - 权限申请
|
|
|
|
|