|
@@ -17,7 +17,7 @@ import UIKit
|
|
|
struct WithDrawModel {
|
|
|
var type: Int // 0:拖动; 1:预览播放暂停 2: 录音结束 3: 删除录音
|
|
|
var timestamp: Double
|
|
|
- var deletedVoices : [(PQVoiceModel, Int)]?
|
|
|
+ var deletedVoices: [(PQVoiceModel, Int)]?
|
|
|
}
|
|
|
|
|
|
public class BFRecordScreenController: BFBaseViewController {
|
|
@@ -96,11 +96,11 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
let newRange = CMTimeRange(start: CMTime(seconds: model.startTime, preferredTimescale: 1000), end: CMTime(seconds: model.endTime, preferredTimescale: 1000))
|
|
|
|
|
|
var deletedVoices = [(PQVoiceModel, Int)]()
|
|
|
-
|
|
|
+
|
|
|
for (i, m) in sself.itemModels[sself.currItemModelIndex].voiceStickers.enumerated() {
|
|
|
let originRange = CMTimeRange(start: CMTime(seconds: m.startTime, preferredTimescale: 1000), end: CMTime(seconds: m.endTime, preferredTimescale: 1000))
|
|
|
-
|
|
|
- if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0{
|
|
|
+
|
|
|
+ if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0 {
|
|
|
deletedVoices.append((m, i))
|
|
|
continue
|
|
|
}
|
|
@@ -117,7 +117,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
sself.events.removeLast()
|
|
|
sself.events.append(event!)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
|
|
|
|
|
|
sself.drawOrUpdateRecordProgessLable()
|
|
@@ -178,6 +178,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
return btn
|
|
|
}()
|
|
|
+
|
|
|
lazy var deleteRecordBtn: UIButton = {
|
|
|
let btn = UIButton(type: .custom)
|
|
|
btn.backgroundColor = .red
|
|
@@ -441,16 +442,17 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
self?.setSubtitleStyle(settingModel: subtitileModel.setting)
|
|
|
}
|
|
|
- subtitleEditView.editSubtitleDone = { [weak self] newtext ,index in
|
|
|
- //1,刷新 UI
|
|
|
+ subtitleEditView.editSubtitleDone = { [weak self] newtext, index in
|
|
|
+ // 1,刷新 UI
|
|
|
self?.subtitleLabel.text = newtext
|
|
|
-
|
|
|
+
|
|
|
self?.setSubtitleStyle(settingModel: (self?.subtitleSettingView.subtitle.setting)!)
|
|
|
-
|
|
|
- //更新缓存数据
|
|
|
- if(index < (self?.itemModels[(self?.currItemModelIndex ?? 0)].titleStickers.count ?? 0)){
|
|
|
- self?.itemModels[self?.currItemModelIndex ?? 0].titleStickers[index].text = newtext}
|
|
|
+
|
|
|
+ // 更新缓存数据
|
|
|
+ if index < (self?.itemModels[self?.currItemModelIndex ?? 0].titleStickers.count ?? 0) {
|
|
|
+ self?.itemModels[self?.currItemModelIndex ?? 0].titleStickers[index].text = newtext
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
layoutsubview()
|
|
|
|
|
@@ -461,15 +463,15 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(message: "编辑字幕 index:\(showSubtitleIndex)")
|
|
|
subtitleEditView.isHidden = false
|
|
|
subtitleEditView.textView.becomeFirstResponder()
|
|
|
- subtitleEditView.setNewText(text: subtitleLabel.text ?? "",index: showSubtitleIndex)
|
|
|
+ subtitleEditView.setNewText(text: subtitleLabel.text ?? "", index: showSubtitleIndex)
|
|
|
}
|
|
|
|
|
|
/// 更新字幕,在回放时使用
|
|
|
/// - Parameter time: 当前播放的进度
|
|
|
func updateSubtitle(time: CMTime) {
|
|
|
var findShowSubtitle: PQEditSubTitleModel?
|
|
|
- for (index,subtitle) in itemModels[currItemModelIndex].titleStickers.enumerated() {
|
|
|
- if subtitle.timelineIn <= CMTimeGetSeconds(time) , subtitle.timelineOut >= CMTimeGetSeconds(time) {
|
|
|
+ for (index, subtitle) in itemModels[currItemModelIndex].titleStickers.enumerated() {
|
|
|
+ if subtitle.timelineIn <= CMTimeGetSeconds(time), subtitle.timelineOut >= CMTimeGetSeconds(time) {
|
|
|
findShowSubtitle = subtitle
|
|
|
BFLog(message: "找到要显示的字幕 in \(findShowSubtitle?.timelineIn ?? 0.0) out \(findShowSubtitle?.timelineOut ?? 0.0) text:\(findShowSubtitle?.text ?? "") currTime is \(CMTimeGetSeconds(time))")
|
|
|
showSubtitleIndex = index
|
|
@@ -479,8 +481,8 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
if findShowSubtitle != nil {
|
|
|
subtitleLabel.text = findShowSubtitle?.text
|
|
|
setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
|
|
|
-
|
|
|
- }else{
|
|
|
+
|
|
|
+ } else {
|
|
|
subtitleLabel.text = ""
|
|
|
}
|
|
|
}
|
|
@@ -496,10 +498,9 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
subtitleLabel.textColor = settingModel.fontColor
|
|
|
|
|
|
let leftPoint: CGFloat = 37
|
|
|
-
|
|
|
-
|
|
|
- let height = sizeTextFits(attributedText: nil, text: subtitleLabel.text ?? "", numberOfLines: 0, font: subtitleLabel.font, maxSize: CGSize(width: cScreenWidth - leftPoint * 2, height: CGFloat.greatestFiniteMagnitude)).height
|
|
|
-
|
|
|
+
|
|
|
+ let height = sizeTextFits(attributedText: nil, text: subtitleLabel.text ?? "", numberOfLines: 0, font: subtitleLabel.font, maxSize: CGSize(width: cScreenWidth - leftPoint * 2, height: CGFloat.greatestFiniteMagnitude)).height
|
|
|
+
|
|
|
// 下 //设置位置
|
|
|
if subtitleSettingView.subtitle.setting.subtitlePoint == 0 {
|
|
|
subtitleLabel.frame = CGRect(x: leftPoint, y: cScreenHeigth * 0.70 - height, width: cScreenWidth - 37 * 2, height: height)
|
|
@@ -655,15 +656,14 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
|
|
|
audioSettingView.isHidden = false
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- @objc func deleteRecorded(){
|
|
|
+
|
|
|
+ @objc func deleteRecorded() {
|
|
|
if isStopAtRecordRange != -1, isStopAtRecordRange < itemModels[currItemModelIndex].voiceStickers.count {
|
|
|
let model = itemModels[currItemModelIndex].voiceStickers[isStopAtRecordRange]
|
|
|
itemModels[currItemModelIndex].voiceStickers.remove(at: isStopAtRecordRange)
|
|
|
drawOrUpdateRecordProgessLable()
|
|
|
searchStopAtRecordRange()
|
|
|
- events.append(WithDrawModel(type: 3, timestamp: self.currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)]))
|
|
|
+ events.append(WithDrawModel(type: 3, timestamp: currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)]))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -682,7 +682,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
model.volume = 100
|
|
|
recorderManager.voiceModel = model
|
|
|
recorderManager.startRecord(index: 1)
|
|
|
-
|
|
|
+
|
|
|
movie?.startProcessing()
|
|
|
assetPlayer?.volume = 0
|
|
|
assetPlayer?.play()
|
|
@@ -692,8 +692,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
avatarView.beginRecord()
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// 添加撤销记录点
|
|
|
events.append(WithDrawModel(type: 2, timestamp: model.startTime))
|
|
|
|
|
@@ -746,17 +744,17 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
}) {
|
|
|
let model = itemModels[currItemModelIndex].voiceStickers[modelIndex]
|
|
|
itemModels[currItemModelIndex].voiceStickers.remove(at: modelIndex)
|
|
|
-
|
|
|
+
|
|
|
var tuples = action.deletedVoices
|
|
|
if tuples != nil, tuples!.count > 0 {
|
|
|
tuples!.sort { tuple1, tuple2 in
|
|
|
tuple1.1 < tuple2.1
|
|
|
}
|
|
|
- tuples?.forEach({ tuple in
|
|
|
+ tuples?.forEach { tuple in
|
|
|
itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
|
|
|
- })
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
drawOrUpdateRecordProgessLable()
|
|
|
jumpTime = model.startTime
|
|
|
}
|
|
@@ -767,14 +765,12 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
tuples!.sort { tuple1, tuple2 in
|
|
|
tuple1.1 < tuple2.1
|
|
|
}
|
|
|
- tuples?.forEach({ tuple in
|
|
|
+ tuples?.forEach { tuple in
|
|
|
itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
|
|
|
- })
|
|
|
+ }
|
|
|
}
|
|
|
drawOrUpdateRecordProgessLable()
|
|
|
- } else {
|
|
|
-
|
|
|
- }
|
|
|
+ } else {}
|
|
|
events.removeLast()
|
|
|
let dur = itemModels[currItemModelIndex].materialDuraion
|
|
|
if dur > 0 {
|
|
@@ -784,10 +780,10 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
hadPrepareToPlayRecord = false
|
|
|
progressThumV.progress = jumpTime
|
|
|
}
|
|
|
-
|
|
|
- if let event = events.last, event.type == 2{
|
|
|
+
|
|
|
+ if let event = events.last, event.type == 2 {
|
|
|
withDrawBtn.setTitle("撤销录制", for: .normal)
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
withDrawBtn.setTitle("撤销", for: .normal)
|
|
|
}
|
|
|
searchStopAtRecordRange()
|
|
@@ -834,7 +830,6 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
BFLog(1, message: isDragingProgressSlder ? "drag false" : "drag tr")
|
|
|
searchStopAtRecordRange()
|
|
|
withDrawBtn.setTitle("撤销", for: .normal)
|
|
|
-
|
|
|
}
|
|
|
|
|
|
func searchStopAtRecordRange() {
|
|
@@ -848,13 +843,13 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
// TODO: 停在了录音区间,显示删除按钮
|
|
|
deleteRecordBtn.isHidden = false
|
|
|
recordBtn.isHidden = true
|
|
|
-
|
|
|
+
|
|
|
isStopAtRecordRange = elems.first!.0
|
|
|
BFLog(1, message: "停在了录音区间里 \(isStopAtRecordRange)")
|
|
|
} else {
|
|
|
deleteRecordBtn.isHidden = true
|
|
|
recordBtn.isHidden = false
|
|
|
-
|
|
|
+
|
|
|
isStopAtRecordRange = -1
|
|
|
BFLog(1, message: "停在了录音区间外 \(isStopAtRecordRange)")
|
|
|
}
|
|
@@ -1079,7 +1074,7 @@ public class BFRecordScreenController: BFBaseViewController {
|
|
|
assetPlayer?.volume = 0
|
|
|
avplayerTimeObserver = assetPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 100), queue: DispatchQueue.global()) { [weak self] time in
|
|
|
// 进度监控
|
|
|
- self?.currentAssetProgress = CMTime(seconds: time.seconds, preferredTimescale: 1000)
|
|
|
+ self?.currentAssetProgress = CMTime(seconds: time.seconds, preferredTimescale: 1000)
|
|
|
BFLog(1, message: "curr:\(CMTimeGetSeconds(self?.currentAssetProgress ?? .zero))")
|
|
|
if CMTimeGetSeconds(item?.duration ?? CMTime.zero) > 0 {
|
|
|
DispatchQueue.main.async { [weak self] in
|
|
@@ -1192,20 +1187,19 @@ extension BFRecordScreenController: PQSpeechTranscriberUtilDelegate {
|
|
|
|
|
|
BFLog(message: "识别结果:dicResult is \(String(describing: dicResult)) \((payload?["result"])!)")
|
|
|
DispatchQueue.main.async {
|
|
|
-
|
|
|
// 2,保存字幕数据
|
|
|
let newSubtitle = PQEditSubTitleModel()
|
|
|
newSubtitle.timelineIn = self.itemModels[self.currItemModelIndex].titleStickers.last?.timelineOut ?? 0
|
|
|
// 当前已处理的音频时长,单位:毫秒。
|
|
|
-
|
|
|
- newSubtitle.timelineOut = Float64(((payload?["time"]) as? Int) ?? 0) / 1_000.0 + (self.recorderManager.voiceModel?.startTime ?? 0.0)
|
|
|
+
|
|
|
+ newSubtitle.timelineOut = Float64(((payload?["time"]) as? Int) ?? 0) / 1000.0 + (self.recorderManager.voiceModel?.startTime ?? 0.0)
|
|
|
var showText = ((payload?["result"]) as? String) ?? ""
|
|
|
- if(showText.count > 30){
|
|
|
+ if showText.count > 30 {
|
|
|
showText = showText.substring(to: 30)
|
|
|
showText += "..."
|
|
|
}
|
|
|
newSubtitle.text = showText
|
|
|
-
|
|
|
+
|
|
|
BFLog(message: "添加字幕数据 timelineIn \(newSubtitle.timelineIn) timelineOut \(newSubtitle.timelineOut) text \(newSubtitle.text)")
|
|
|
newSubtitle.setting = self.subtitleSettingView.subtitle.setting
|
|
|
|
|
@@ -1233,6 +1227,14 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
recordItem.fetchCoverImg = { [weak cell] _ in
|
|
|
cell?.addData()
|
|
|
}
|
|
|
+ recordItem.fetchAVUrlAsset = { [weak self] urlAsset in
|
|
|
+ if indexPath.item == self?.currItemModelIndex {
|
|
|
+ DispatchQueue.main.async { [weak self] in
|
|
|
+ self?.progressThumV.videoAsset = urlAsset
|
|
|
+ self?.progressThumV.isHidden = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
recordItem.fetchPlayItem = { [weak self, weak cell] _ in
|
|
|
if indexPath.item == self?.currItemModelIndex {
|
|
|
self?.setAudioPlay(item: recordItem.playItem)
|
|
@@ -1259,6 +1261,9 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
|
|
|
// 更新当前page
|
|
|
currItemModelIndex = page
|
|
|
let recordItem = itemModels[currItemModelIndex]
|
|
|
+ // 更新缩略图
|
|
|
+ progressThumV.videoAsset = recordItem.urlAsset
|
|
|
+ progressThumV.isHidden = false
|
|
|
if recordItem.mediaType == .VIDEO {
|
|
|
let currCell: BFVideoCoverViewCell? = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFVideoCoverViewCell
|
|
|
setAudioPlay(item: recordItem.playItem)
|