|
@@ -24,6 +24,9 @@ struct WithDrawModel {
|
|
|
var deletedVoices: [(PQVoiceModel, Int)]?
|
|
|
// add by ak 保存删除的字幕数据用于恢复
|
|
|
var deletedTittles: [PQEditSubTitleModel]?
|
|
|
+ //
|
|
|
+ var deletedCameras: [PQEditVisionTrackMaterialsModel]?
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public class BFRecordScreenController: BFBaseViewController {
|
|
@@ -62,6 +65,20 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
guard let wself = self else { return }
|
|
|
wself.recordBtn.isEnabled = true
|
|
|
}
|
|
|
+
|
|
|
+ // MARK: 摄像头结束回调
|
|
|
+ m.recordEndCallBack = { [weak self] isSuccess, sticker in
|
|
|
+ guard let wself = self, let sticker = sticker else { return }
|
|
|
+
|
|
|
+ if isSuccess{
|
|
|
+ wself.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)")
|
|
|
+ }
|
|
|
+ }
|
|
|
return m
|
|
|
}()
|
|
|
var rscurrentManager = BFRecordScreenBaseManager()
|
|
@@ -83,7 +100,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
progressThumV.isHidden = false
|
|
|
cameraProgressThumV.isHidden = true
|
|
|
progreddL.isHidden = false
|
|
|
- rscurrentManager.progressThumV = progressThumV
|
|
|
|
|
|
case .Video:
|
|
|
rscurrentManager = rsvmanager
|
|
@@ -91,7 +107,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
progressThumV.isHidden = false
|
|
|
cameraProgressThumV.isHidden = true
|
|
|
progreddL.isHidden = false
|
|
|
- rscurrentManager.progressThumV = progressThumV
|
|
|
|
|
|
case .Camera:
|
|
|
rscurrentManager = rscmanager
|
|
@@ -105,41 +120,34 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
default:
|
|
|
break
|
|
|
}
|
|
|
- rscurrentManager.dele = self
|
|
|
+
|
|
|
if let cell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
|
|
|
if (cell as? BFCameraCoverViewCell) != nil {
|
|
|
cell.playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
|
|
|
progressThumV.isHidden = true
|
|
|
- if let rendV = (rscurrentManager as? BFRecordScreenCameraManager)?.rendView {
|
|
|
- rendV.removeFromSuperview()
|
|
|
- cell.playView.addSubview(rendV)
|
|
|
- rendV.snp.makeConstraints { make in
|
|
|
- make.edges.equalToSuperview()
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: 摄像头结束回调
|
|
|
- (rscurrentManager as? BFRecordScreenCameraManager)?.recordEndCallBack = { [weak self] _, sticker in
|
|
|
- guard let wself = self, let sticker = sticker else { return }
|
|
|
-
|
|
|
- wself.currentAssetProgress = CMTime(seconds: sticker.timelineOut , preferredTimescale: 1000)
|
|
|
-// if isSuccess, let sticker = sticker {
|
|
|
-// itemModel.videoStickers.append(sticker)
|
|
|
-// }
|
|
|
- }
|
|
|
+
|
|
|
+ rscmanager.rendView.removeFromSuperview()
|
|
|
+ cell.playView.addSubview(rscmanager.rendView)
|
|
|
+ rscmanager.rendView.snp.makeConstraints { make in
|
|
|
+ make.edges.equalToSuperview()
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
} else {
|
|
|
cell.playView.setInputRotation(GPUImageRotationMode(rawValue: 0), at: 0)
|
|
|
-// if itemModel.mediaType == .Video {
|
|
|
-// rsvmanager.assetPlayer
|
|
|
-// }
|
|
|
+ progressThumV.isHidden = false
|
|
|
}
|
|
|
rscurrentManager.playView = cell.playView
|
|
|
- rscurrentManager.progreddL = progreddL
|
|
|
-
|
|
|
- rscurrentManager.recordItem = itemModel
|
|
|
- rscurrentManager.resetEnv()
|
|
|
}
|
|
|
+
|
|
|
+ rscurrentManager.progreddL = progreddL
|
|
|
+ rscurrentManager.recordPlayer = recordPlayer
|
|
|
+ rscurrentManager.progressThumV = progressThumV
|
|
|
+ rscurrentManager.dele = self
|
|
|
+
|
|
|
+ rscurrentManager.recordItem = itemModel
|
|
|
+ rscurrentManager.resetEnv()
|
|
|
|
|
|
}
|
|
|
}
|
|
@@ -499,8 +507,15 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
deinit {
|
|
|
NotificationCenter.default.removeObserver(self)
|
|
|
- avplayerTimeObserver?.invalidate()
|
|
|
- recordPlayerTimeObserver?.invalidate()
|
|
|
+ if avplayerTimeObserver != nil {
|
|
|
+ assetPlayer.removeTimeObserver(avplayerTimeObserver)
|
|
|
+ avplayerTimeObserver?.invalidate()
|
|
|
+ }
|
|
|
+ if recordPlayerTimeObserver != nil {
|
|
|
+ recordPlayer.removeTimeObserver(recordPlayerTimeObserver)
|
|
|
+ recordPlayerTimeObserver?.invalidate()
|
|
|
+ }
|
|
|
+
|
|
|
if isRecording {
|
|
|
recorderManager?.stopRecord(isCancel: true)
|
|
|
}
|
|
@@ -788,7 +803,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
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") 传入的地址:\(currentVoice.wavFilePath ?? "aa")")
|
|
|
+ BFLog(1, message: "添加字幕数据 timelineIn \(newSubtitle.timelineIn.seconds) timelineOut \(newSubtitle.timelineOut.seconds) text: \(newSubtitle.text)")
|
|
|
newSubtitle.setting = self?.subtitleSettingView.subtitle.setting ?? BFSubTitileSettingModel()
|
|
|
currentItem.titleStickers.append(newSubtitle)
|
|
|
}
|
|
@@ -863,12 +878,16 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
if wself.itemModels[wself.currItemModelIndex].mediaType != .Video {
|
|
|
var duration: CMTime = .zero
|
|
|
- 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
|
|
|
+ if wself.itemModels[wself.currItemModelIndex].mediaType == .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.itemModels[wself.currItemModelIndex].materialDuraion = duration
|
|
|
+
|
|
|
self?.isEndPlay = true
|
|
|
// 录制结束显示播放按钮
|
|
|
wself.playBtn.isSelected = wself.itemModels[wself.currItemModelIndex].voiceStickers.count <= 0
|
|
@@ -931,7 +950,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
/// 更新字幕,在回放时使用
|
|
|
/// - Parameter time: 当前播放的进度
|
|
|
func updateSubtitle(time: CMTime) {
|
|
|
- BFLog(message: "currTime is \(CMTimeGetSeconds(time))")
|
|
|
+ BFLog(1, message: "currTime is \(CMTimeGetSeconds(time))")
|
|
|
if isRecording || !subtitleSettingView.subtitle.setting.subtitleIsShow || currentPlayRecordIndex == -3 {
|
|
|
// currentPlayRecordIndex == -3 代表刚录完音,不要找字幕,会因为小幅度回退seek导致上一个字幕出现
|
|
|
if subtitleLabel.text?.count ?? 0 > 0 {
|
|
@@ -1119,11 +1138,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
event.deletedTittles = deleteTitles(voiceModel: model)
|
|
|
events.append(event)
|
|
|
|
|
|
+ rscurrentManager.deleteRecord(at: currentAssetProgress)
|
|
|
+
|
|
|
// 注:删除录音后图片素材需要回撤指针进度,同时后面录音往前挪
|
|
|
if itemModels[currItemModelIndex].mediaType == .Image {
|
|
|
let currDuration = model.endCMTime - model.startCMTime
|
|
|
itemModels[currItemModelIndex].materialDuraion = itemModels[currItemModelIndex].materialDuraion - currDuration
|
|
|
currentAssetProgress = model.startCMTime
|
|
|
+
|
|
|
// 更新进度
|
|
|
resetCurrentProgress()
|
|
|
for (index, item) in itemModels[currItemModelIndex].voiceStickers.enumerated() {
|
|
@@ -1145,12 +1167,20 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
/// 重绘录音进度视图
|
|
|
resetAllIndirectionView()
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ rscurrentManager.changeRecordMaterail()
|
|
|
+
|
|
|
+ if itemModels[currItemModelIndex].mediaType != .Video{
|
|
|
// 判断是否无录音了
|
|
|
if itemModels[currItemModelIndex].materialDuraion == .zero {
|
|
|
playBtn.isSelected = true
|
|
|
playBtn.isHidden = playBtn.isSelected
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
searchStopAtRecordRange()
|
|
|
changeWithDrawBtnLayout(3)
|
|
|
}
|
|
@@ -1225,22 +1255,24 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
beginOnStartBtn = false
|
|
|
|
|
|
- BFLog(1, message: "停止录音-")
|
|
|
+ BFLog(1, message: "停止录音- \(currentAssetProgress.seconds)")
|
|
|
recordBtn.isEnabled = false
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
|
|
|
self?.recordBtn.isEnabled = true
|
|
|
}
|
|
|
|
|
|
rscurrentManager.endRecord()
|
|
|
+
|
|
|
isRecording = false
|
|
|
// progressThumV.progressView.isUserInteractionEnabled = true
|
|
|
// collectionView.isScrollEnabled = true
|
|
|
|
|
|
UIApplication.shared.keyWindow?.isUserInteractionEnabled = true
|
|
|
- recorderManager?.stopRecord(isCancel: false)
|
|
|
|
|
|
- if currentAssetProgress.seconds - (recorderManager?.voiceModel?.startCMTime.seconds ?? 0) >= 1.0 {
|
|
|
+ if currentAssetProgress.seconds - (recorderManager?.voiceModel?.startCMTime.seconds ?? 0) > 1.0 {
|
|
|
+ recorderManager?.stopRecord(isCancel: false)
|
|
|
} else {
|
|
|
+ recorderManager?.stopRecord(isCancel: true)
|
|
|
changeProgress(changCMTime: recorderManager?.voiceModel?.startCMTime ?? .zero)
|
|
|
}
|
|
|
|
|
@@ -1707,7 +1739,8 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(3, message: "播放结束")
|
|
|
didPlayToEndTime((shouldPlayRecordIndex, recordedAudio), newItem)
|
|
|
}
|
|
|
- recordPlayerTimeObserver?.invalidate()
|
|
|
+// recordPlayer.removeTimeObserver(recordPlayerTimeObserver as Any)
|
|
|
+// recordPlayerTimeObserver?.invalidate()
|
|
|
recordPlayerTimeObserver = recordPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 1000), queue: DispatchQueue.global()) { [weak self, weak recordPlayer] time in
|
|
|
guard let wself = self, let rPlay = recordPlayer else {
|
|
|
BFLog(3, message: "wself为空")
|
|
@@ -1814,25 +1847,22 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
recorderManager?.voiceModel = nil
|
|
|
|
|
|
itemModels[currItemModelIndex].titleStickers.sort { m1, m2 in
|
|
|
- m1.timelineIn < m2.timelineIn
|
|
|
+ CMTimeCompare(m1.timelineIn, m2.timelineIn) < 0
|
|
|
}
|
|
|
|
|
|
isNormalPlaying = true
|
|
|
- if isEndPlay || (itemModels[currItemModelIndex].mediaType == .Image && CMTimeCompare(currentAssetProgress, itemModels[currItemModelIndex].materialDuraion) >= 0) {
|
|
|
+ if isEndPlay || (itemModels[currItemModelIndex].mediaType != .Video && CMTimeCompare(currentAssetProgress, itemModels[currItemModelIndex].materialDuraion) >= 0) {
|
|
|
isEndPlay = false
|
|
|
assetPlayer.seek(to: CMTime.zero)
|
|
|
progressThumV.progress = 0
|
|
|
currentPlayRecordIndex = -1
|
|
|
BFLog(3, message: "重置播放index-\(#function) = \(currentPlayRecordIndex)")
|
|
|
- if itemModels[currItemModelIndex].mediaType == .Video {
|
|
|
- recordBtn.isHidden = false
|
|
|
- }
|
|
|
+
|
|
|
currentAssetProgress = CMTime.zero
|
|
|
}
|
|
|
|
|
|
rscurrentManager.play()
|
|
|
|
|
|
-
|
|
|
deleteRecordBtn.isHidden = true
|
|
|
|
|
|
subtitleBtn.isHidden = true
|
|
@@ -1845,11 +1875,11 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(1, message: "暂停播放")
|
|
|
isNormalPlaying = false
|
|
|
|
|
|
- // ---- 修复暂停播放回退问题
|
|
|
- avplayerTimeObserver?.invalidate()
|
|
|
- avplayerTimeObserver = nil
|
|
|
- recordPlayerTimeObserver?.invalidate()
|
|
|
- recordPlayerTimeObserver = nil
|
|
|
+// // ---- 修复暂停播放回退问题
|
|
|
+// avplayerTimeObserver?.invalidate()
|
|
|
+// avplayerTimeObserver = nil
|
|
|
+// recordPlayerTimeObserver?.invalidate()
|
|
|
+// recordPlayerTimeObserver = nil
|
|
|
// ----
|
|
|
|
|
|
subtitleBtn.isHidden = false
|
|
@@ -1934,14 +1964,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
} else {
|
|
|
assetPlayer.replaceCurrentItem(with: item)
|
|
|
BFLog(message: "设置播放器item-替换:\(String(describing: item))")
|
|
|
-// assetPlayer.volume = noSpeakVolume
|
|
|
- avplayerTimeObserver?.invalidate()
|
|
|
avplayerTimeObserver = assetPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 1000), queue: DispatchQueue.global()) { [weak self] time in
|
|
|
// 进度监控
|
|
|
- self?.periodicTimeObserver(item: item, time: time)
|
|
|
- if self?.isNormalPlaying ?? false {
|
|
|
+ guard let wself = self else { return }
|
|
|
+
|
|
|
+ wself.periodicTimeObserver(item: item, time: time)
|
|
|
+ if wself.isNormalPlaying {
|
|
|
// 播放录音
|
|
|
- self?.startPlayRecord(time: time)
|
|
|
+ wself.startPlayRecord(time: time)
|
|
|
}
|
|
|
} as? NSKeyValueObservation
|
|
|
}
|
|
@@ -2051,7 +2081,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- currentAssetProgress = isBack ? CMTime(value: CMTimeValue(newProgress * 1000), timescale: 1000) : (progress != -1 ? CMTime(value: CMTimeValue(newProgress * Float(itemModels[currItemModelIndex].materialDuraion.seconds) * 1000), timescale: 1000) : changCMTime)
|
|
|
+ currentAssetProgress = isBack ? CMTime(seconds: Double(newProgress), preferredTimescale: 1000) : ((progress != -1) ? CMTime(seconds: (Double(newProgress) * itemModels[currItemModelIndex].materialDuraion.seconds), preferredTimescale: 1000) : changCMTime)
|
|
|
if currentAssetProgress.seconds > itemModels[currItemModelIndex].materialDuraion.seconds {
|
|
|
currentAssetProgress = itemModels[currItemModelIndex].materialDuraion
|
|
|
}
|
|
@@ -2068,7 +2098,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
// 画进度线
|
|
|
func drawProgressIndication(progress: Double) {
|
|
|
- if indirectionView == nil {
|
|
|
+ if itemModels[currItemModelIndex].mediaType != .Camera, indirectionView == nil {
|
|
|
var percenWidth: CGFloat = 0
|
|
|
if itemModels[currItemModelIndex].mediaType == .Image {
|
|
|
percenWidth = progressThumV.thumbImageWidth / 2.0
|
|
@@ -2258,9 +2288,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
}
|
|
|
// 更新缩略图
|
|
|
// progressThumV.isHidden = false
|
|
|
- progreddL.text = "00:00"
|
|
|
- // 重置指针
|
|
|
- currentAssetProgress = .zero
|
|
|
+
|
|
|
searchStopAtRecordRange()
|
|
|
// 切换要更新当前录制index,避免在录制完以后切换素材这种时候为-3会拦截
|
|
|
currentPlayRecordIndex = -1
|
|
@@ -2388,6 +2416,8 @@ public extension BFRecordScreenController {
|
|
|
/// 重绘录音进度视图
|
|
|
func resetAllIndirectionView() {
|
|
|
if itemModels[currItemModelIndex].mediaType == .Camera {
|
|
|
+ rscmanager.cameraProgressV?.collectionV.reloadData()
|
|
|
+ rscmanager.locationTo(time: currentAssetProgress)
|
|
|
return
|
|
|
}
|
|
|
// 重绘录音进度视图
|