|
@@ -120,11 +120,13 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
|
|
sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
|
|
if sself.itemModels[sself.currItemModelIndex].mediaType == .IMAGE {
|
|
if sself.itemModels[sself.currItemModelIndex].mediaType == .IMAGE {
|
|
var duration: Double = 0
|
|
var duration: Double = 0
|
|
- sself.itemModels[sself.currItemModelIndex].voiceStickers.forEach { item in
|
|
|
|
|
|
+ sself.itemModels[sself.currItemModelIndex].voiceStickers.forEach { _ in
|
|
duration = duration + (Double(model.duration ?? "0") ?? 0)
|
|
duration = duration + (Double(model.duration ?? "0") ?? 0)
|
|
}
|
|
}
|
|
sself.itemModels[sself.currItemModelIndex].materialDuraion = duration
|
|
sself.itemModels[sself.currItemModelIndex].materialDuraion = duration
|
|
sself.currentAssetProgress = CMTime(seconds: duration, preferredTimescale: 1000)
|
|
sself.currentAssetProgress = CMTime(seconds: duration, preferredTimescale: 1000)
|
|
|
|
+ model.endTime = sself.currentAssetProgress.seconds
|
|
|
|
+ self?.isEndPlay = true
|
|
}
|
|
}
|
|
sself.drawOrUpdateRecordProgessLable()
|
|
sself.drawOrUpdateRecordProgessLable()
|
|
|
|
|
|
@@ -728,7 +730,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
assetPlayer?.play()
|
|
assetPlayer?.play()
|
|
} else {
|
|
} else {
|
|
recorderManager.audioRecorder?.recorderProgross = { [weak self] progress in
|
|
recorderManager.audioRecorder?.recorderProgross = { [weak self] progress in
|
|
- self?.imageRecordProgress(progress: progress)
|
|
|
|
|
|
+ self?.imageRecordProgress(isRecord: true, progress: progress)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -926,7 +928,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
// MARK: - 音视频处理
|
|
// MARK: - 音视频处理
|
|
|
|
|
|
- func playRecord(at currentT: CMTime, periodicTimeObserver: @escaping (_ time: CMTime, _ currentItem: AVPlayerItem) -> Void, didPlayToEndTime: @escaping (_ currentT: CMTime, _ currentItem: AVPlayerItem) -> Void, playFailut: @escaping () -> Void) {
|
|
|
|
|
|
+ func playRecord(at currentT: CMTime, periodicTimeObserver: @escaping (_ time: CMTime, _ currentItem: AVPlayerItem) -> Void, didPlayToEndTime: @escaping (_ recordedAudio: PQVoiceModel?, _ currentItem: AVPlayerItem?) -> Void, playFailed: @escaping (_ recordedAudio: PQVoiceModel?, _ currentItem: AVPlayerItem?) -> Void) {
|
|
if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
|
|
if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -961,10 +963,10 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
hadPrepareToPlayRecord = false
|
|
hadPrepareToPlayRecord = false
|
|
BFLog(1, message: "录音播放器初始化(有时候不准)")
|
|
BFLog(1, message: "录音播放器初始化(有时候不准)")
|
|
|
|
|
|
- NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: newItem, queue: .main) { [weak self] _ in
|
|
|
|
|
|
+ NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: newItem, queue: .main) { [weak self, weak recordedAudio] _ in
|
|
self?.hadPrepareToPlayRecord = false
|
|
self?.hadPrepareToPlayRecord = false
|
|
self?.currentPlayRecordIndex = -1
|
|
self?.currentPlayRecordIndex = -1
|
|
- didPlayToEndTime(currentT, newItem)
|
|
|
|
|
|
+ didPlayToEndTime(recordedAudio, newItem)
|
|
}
|
|
}
|
|
_ = recordPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 100), queue: DispatchQueue.global()) { [weak self] time in
|
|
_ = recordPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 100), queue: DispatchQueue.global()) { [weak self] time in
|
|
periodicTimeObserver(time, newItem)
|
|
periodicTimeObserver(time, newItem)
|
|
@@ -972,7 +974,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
}
|
|
}
|
|
if recordPlayer?.currentItem?.duration.timescale == 0 {
|
|
if recordPlayer?.currentItem?.duration.timescale == 0 {
|
|
BFLog(1, message: "时间timescale == 0")
|
|
BFLog(1, message: "时间timescale == 0")
|
|
- playFailut()
|
|
|
|
|
|
+ playFailed(recordedAudio, recordPlayer?.currentItem)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
synced(currentPlayRecordIndex) { [weak self] in
|
|
synced(currentPlayRecordIndex) { [weak self] in
|
|
@@ -1026,16 +1028,19 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
func play() {
|
|
func play() {
|
|
BFLog(1, message: "开始播放 \(currentAssetProgress.seconds)")
|
|
BFLog(1, message: "开始播放 \(currentAssetProgress.seconds)")
|
|
isNormalPlaying = true
|
|
isNormalPlaying = true
|
|
|
|
+ if isEndPlay {
|
|
|
|
+ isEndPlay = false
|
|
|
|
+ assetPlayer?.seek(to: CMTime.zero)
|
|
|
|
+ progressThumV.progress = 0
|
|
|
|
+ currentPlayRecordIndex = -1
|
|
|
|
+ if itemModels[currItemModelIndex].mediaType == .VIDEO {
|
|
|
|
+ recordBtn.isHidden = false
|
|
|
|
+ }
|
|
|
|
+ currentAssetProgress = CMTime.zero
|
|
|
|
+ }
|
|
if itemModels[currItemModelIndex].mediaType == .VIDEO {
|
|
if itemModels[currItemModelIndex].mediaType == .VIDEO {
|
|
// assetPlayer?.volume = 0.2
|
|
// assetPlayer?.volume = 0.2
|
|
movie?.startProcessing()
|
|
movie?.startProcessing()
|
|
- if isEndPlay {
|
|
|
|
- isEndPlay = false
|
|
|
|
- assetPlayer?.seek(to: CMTime.zero)
|
|
|
|
- progressThumV.progress = 0
|
|
|
|
- currentPlayRecordIndex = -1
|
|
|
|
- recordBtn.isHidden = false
|
|
|
|
- }
|
|
|
|
assetPlayer?.play()
|
|
assetPlayer?.play()
|
|
} else {
|
|
} else {
|
|
// 处理图片音频播放
|
|
// 处理图片音频播放
|
|
@@ -1052,6 +1057,8 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
assetPlayer?.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000), completionHandler: { _ in
|
|
assetPlayer?.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000), completionHandler: { _ in
|
|
})
|
|
})
|
|
|
|
+ // 暂停状态
|
|
|
|
+ (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = false
|
|
}
|
|
}
|
|
|
|
|
|
func fetchVideo() {
|
|
func fetchVideo() {
|
|
@@ -1126,7 +1133,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
BFLog(message: "播放一段进度:\(currentT),\(currentItem)")
|
|
BFLog(message: "播放一段进度:\(currentT),\(currentItem)")
|
|
}, didPlayToEndTime: { startT, currentItem in
|
|
}, didPlayToEndTime: { startT, currentItem in
|
|
BFLog(message: "播放一段结束:\(startT),\(currentItem)")
|
|
BFLog(message: "播放一段结束:\(startT),\(currentItem)")
|
|
- }, playFailut: {})
|
|
|
|
|
|
+ }, playFailed: { _, _ in })
|
|
}
|
|
}
|
|
} as? NSKeyValueObservation
|
|
} as? NSKeyValueObservation
|
|
}
|
|
}
|
|
@@ -1305,12 +1312,8 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
self?.setVideoPlay(item: recordItem.playItem, imageView: cell?.playView)
|
|
self?.setVideoPlay(item: recordItem.playItem, imageView: cell?.playView)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- cell.btnClickHandle = { [weak self] sender, tempItem in
|
|
|
|
- if tempItem?.mediaType == .VIDEO {
|
|
|
|
- self?.playVideo(btn: sender)
|
|
|
|
- } else {
|
|
|
|
- self?.imageRecordPlay()
|
|
|
|
- }
|
|
|
|
|
|
+ cell.btnClickHandle = { [weak self] sender, _ in
|
|
|
|
+ self?.playVideo(btn: sender)
|
|
}
|
|
}
|
|
cell.recordItem = recordItem
|
|
cell.recordItem = recordItem
|
|
return cell
|
|
return cell
|
|
@@ -1362,10 +1365,15 @@ public extension BFRecordScreenController {
|
|
playRecord(at: currentAssetProgress, periodicTimeObserver: { [weak self] currentT, currentItem in
|
|
playRecord(at: currentAssetProgress, periodicTimeObserver: { [weak self] currentT, currentItem in
|
|
BFLog(message: "播放一段进度:\(currentT),\(currentItem)")
|
|
BFLog(message: "播放一段进度:\(currentT),\(currentItem)")
|
|
self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
|
|
self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
|
|
- }, didPlayToEndTime: { [weak self] startT, currentItem in
|
|
|
|
- BFLog(message: "播放一段结束:\(startT),\(currentItem)")
|
|
|
|
- self?.imageRecordPlay()
|
|
|
|
- }) { [weak self] in
|
|
|
|
|
|
+ }, didPlayToEndTime: { [weak self] recordedAudio, currentItem in
|
|
|
|
+ BFLog(message: "播放一段结束:\(String(describing: recordedAudio)),\(String(describing: currentItem))")
|
|
|
|
+ if (recordedAudio?.endTime ?? 0) >= (self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last?.endTime ?? 0) {
|
|
|
|
+ self?.isEndPlay = true
|
|
|
|
+ self?.pause()
|
|
|
|
+ } else {
|
|
|
|
+ self?.imageRecordPlay()
|
|
|
|
+ }
|
|
|
|
+ }) { [weak self] _, _ in
|
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
|
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
|
|
self?.imageRecordPlay()
|
|
self?.imageRecordPlay()
|
|
}
|
|
}
|
|
@@ -1374,44 +1382,19 @@ public extension BFRecordScreenController {
|
|
}
|
|
}
|
|
|
|
|
|
/// 处理图片素材录音
|
|
/// 处理图片素材录音
|
|
- func imageRecordProgress(progress: Float64) {
|
|
|
|
|
|
+ func imageRecordProgress(isRecord: Bool = false, progress: Float64) {
|
|
BFLog(message: "图片录音进度:\(progress)")
|
|
BFLog(message: "图片录音进度:\(progress)")
|
|
|
|
+ if isRecord {
|
|
|
|
+ currentAssetProgress = CMTime(seconds: itemModels[currItemModelIndex].materialDuraion + progress, preferredTimescale: 1000)
|
|
|
|
+ } else {
|
|
|
|
+ currentAssetProgress = CMTime(seconds: progress, preferredTimescale: 1000)
|
|
|
|
+ }
|
|
if itemModels[currItemModelIndex].mediaType == .IMAGE {
|
|
if itemModels[currItemModelIndex].mediaType == .IMAGE {
|
|
DispatchQueue.main.async { [weak self] in
|
|
DispatchQueue.main.async { [weak self] in
|
|
- self?.progreddL.text = String(format: "%@", (progress + (self?.currentAssetProgress.seconds ?? 0)).formatDurationToHMS())
|
|
|
|
- self?.progressThumV.progress = (progress + (self?.currentAssetProgress.seconds ?? 0))
|
|
|
|
- self?.updateSubtitle(time: CMTime(value: CMTimeValue((progress + (self?.currentAssetProgress.seconds ?? 0))), timescale: 1))
|
|
|
|
|
|
+ self?.progreddL.text = String(format: "%@", ((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress)).formatDurationToHMS())
|
|
|
|
+ self?.progressThumV.progress = ((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress))
|
|
|
|
+ self?.updateSubtitle(time: CMTime(value: CMTimeValue((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress)), timescale: 1))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- // 开始计时
|
|
|
|
- func startTimer() {
|
|
|
|
- if displayLink == nil {
|
|
|
|
- // 创建对象
|
|
|
|
- displayLink = CADisplayLink(target: self, selector: #selector(displayLinkChange(_:)))
|
|
|
|
- // 设置触发频率 这个周期可以通过frameInterval属性设置,CADisplayLink的selector每秒调用次数=60/frameInterval。比如当frameInterval设为2,每秒调用就变成30次
|
|
|
|
- if #available(iOS 10.0, *) {
|
|
|
|
- displayLink?.preferredFramesPerSecond = 1
|
|
|
|
- } else {
|
|
|
|
- displayLink?.frameInterval = 1
|
|
|
|
- }
|
|
|
|
- // 加入循环
|
|
|
|
- displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.default)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 停止计时
|
|
|
|
- func stopTimer() {
|
|
|
|
- if displayLink != nil {
|
|
|
|
- displayLink?.isPaused = true
|
|
|
|
- // 将定时器移除主循环
|
|
|
|
- displayLink?.remove(from: RunLoop.main, forMode: RunLoop.Mode.default)
|
|
|
|
- // 停止定时器
|
|
|
|
- displayLink?.invalidate()
|
|
|
|
- displayLink = nil
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @objc internal func displayLinkChange(_: CADisplayLink) {}
|
|
|
|
}
|
|
}
|