|
@@ -58,11 +58,11 @@ public class BFRecordExport {
|
|
|
if let itemModels = data {
|
|
|
var totalDur = 0.0
|
|
|
var titleStickers = [PQEditSubTitleModel]()
|
|
|
- var voiceList = [PQVoiceModel]()
|
|
|
+ var voiceList = [PQEditVisionTrackMaterialsModel]()
|
|
|
var videoStickers = [PQEditVisionTrackMaterialsModel]()
|
|
|
|
|
|
// 切割视频素材
|
|
|
- for (_, itemModel) in itemModels.enumerated() {
|
|
|
+ for (_, itemModel) in itemModels.enumerated() {
|
|
|
// 保留录音部分时,是否按录音顺序合成最终视频;
|
|
|
// 如果需要排序,则排视频的顺序;否则排音频的顺序
|
|
|
let needSort = false
|
|
@@ -90,11 +90,12 @@ public class BFRecordExport {
|
|
|
if itemModel.voiceStickers.count == 0 {
|
|
|
// 图片无录音保持2s
|
|
|
duration = 2
|
|
|
- let voice = PQVoiceModel()
|
|
|
- voice.startTime = 0
|
|
|
- voice.endTime = 2
|
|
|
- voice.duration = "2"
|
|
|
- voice.voiceType = VOICETYPT.None.rawValue
|
|
|
+ let voice = PQEditVisionTrackMaterialsModel()
|
|
|
+ voice.model_in = 0.0
|
|
|
+ voice.out = 2.0
|
|
|
+ voice.aptDuration = 2.0
|
|
|
+// voice.voiceType = VOICETYPT.None.rawValue
|
|
|
+ voice.volumeGain = 100
|
|
|
voiceList.append(voice)
|
|
|
}
|
|
|
|
|
@@ -129,7 +130,7 @@ public class BFRecordExport {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- voiceList.append(contentsOf: itemModel.voiceStickers)
|
|
|
+// voiceList.append(contentsOf: itemModel.voiceStickers)
|
|
|
|
|
|
if synthesisAll {
|
|
|
var subDur = 0.0
|
|
@@ -141,6 +142,24 @@ public class BFRecordExport {
|
|
|
sticker.volumeGain = Float64(srange.isRecord ? originSoundInRecordVolumn*100 : originSoundVolumn*100)
|
|
|
videoStickers.append(sticker)
|
|
|
subDur += range.duration.seconds
|
|
|
+
|
|
|
+ if srange.isRecord {
|
|
|
+ // 处理voice
|
|
|
+ if let mod = itemModel.voiceStickers.first(where: { m in
|
|
|
+ m.startTime == range.start.seconds
|
|
|
+ }){
|
|
|
+ let sticker = PQEditVisionTrackMaterialsModel()
|
|
|
+ sticker.model_in = 0
|
|
|
+ sticker.out = mod.endTime - mod.startTime
|
|
|
+ sticker.timelineIn = totalDur + mod.startTime
|
|
|
+ sticker.timelineOut = totalDur + mod.endTime
|
|
|
+ sticker.aptDuration = sticker.out
|
|
|
+ sticker.duration = sticker.out
|
|
|
+ sticker.locationPath = mod.wavFilePath
|
|
|
+ sticker.volumeGain = 100 // Float64(model.volume)
|
|
|
+ voiceList.append(sticker)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
for titleS in itemModel.titleStickers {
|
|
@@ -174,6 +193,17 @@ public class BFRecordExport {
|
|
|
videoStickers.append(sticker)
|
|
|
|
|
|
let voiceSticker = itemModel.voiceStickers[index]
|
|
|
+ let voice = PQEditVisionTrackMaterialsModel()
|
|
|
+ voice.model_in = 0
|
|
|
+ voice.out = voiceSticker.endTime - voiceSticker.startTime
|
|
|
+ voice.timelineIn = totalDur + subDur
|
|
|
+ voice.timelineOut = totalDur + subDur + voice.out
|
|
|
+ voice.aptDuration = voice.out
|
|
|
+ voice.duration = voice.out
|
|
|
+ voice.locationPath = voiceSticker.wavFilePath
|
|
|
+ voice.volumeGain = 100 // Float64(model.volume)
|
|
|
+ voiceList.append(voice)
|
|
|
+
|
|
|
let titleModels = itemModel.titleStickers.filter({ mod in
|
|
|
mod.audioFilePath == voiceSticker.wavFilePath
|
|
|
})
|
|
@@ -243,7 +273,7 @@ public class BFRecordExport {
|
|
|
|
|
|
// 因为titleStickers 是传递过来的,会修改timelinein,需要重新生成,以免影响原来的数据
|
|
|
// voiceList是考虑到图片有时候没有录音,在保留全部时,需要添加一个2秒的空sticker
|
|
|
- func beginExport(synthesisAll: Bool, videoStickers: [PQEditVisionTrackMaterialsModel], voiceList: [PQVoiceModel], titleStickers: [PQEditSubTitleModel]) {
|
|
|
+ func beginExport(synthesisAll: Bool, videoStickers: [PQEditVisionTrackMaterialsModel], voiceList: [PQEditVisionTrackMaterialsModel], titleStickers: [PQEditSubTitleModel]) {
|
|
|
// 输出视频地址
|
|
|
// exprotVideo()
|
|
|
// return;
|
|
@@ -292,7 +322,7 @@ public class BFRecordExport {
|
|
|
exportCompletion?(error as Error, nil)
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+ // MARK: - 声音合成
|
|
|
// 有录音操作或者多个视频,就会进入合成步骤,否则就是一个没有处理的素材,直接导出就行了
|
|
|
if voiceCount > 0 || videoStickers.count > 1 {
|
|
|
let (audioMix, composition) = mergeAudio(videoStickers: videoStickers, audios: voiceList, synthesisAll: synthesisAll)
|
|
@@ -400,7 +430,7 @@ public class BFRecordExport {
|
|
|
}
|
|
|
|
|
|
extension BFRecordExport {
|
|
|
- func mergeAudio(videoStickers: [PQEditVisionTrackMaterialsModel], audios: [PQVoiceModel]?, synthesisAll: Bool) -> (AVMutableAudioMix, AVMutableComposition) {
|
|
|
+ func mergeAudio(videoStickers: [PQEditVisionTrackMaterialsModel], audios: [PQEditVisionTrackMaterialsModel]?, synthesisAll: Bool) -> (AVMutableAudioMix, AVMutableComposition) {
|
|
|
let composition = AVMutableComposition()
|
|
|
let audioMix = AVMutableAudioMix()
|
|
|
var tempParameters = [AVMutableAudioMixInputParameters]()
|
|
@@ -427,49 +457,32 @@ extension BFRecordExport {
|
|
|
return (audioMix, composition)
|
|
|
}
|
|
|
|
|
|
- func mergeRecordVoiceOnly(voices: [PQVoiceModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
|
|
|
+ func mergeRecordVoiceOnly(voices: [PQEditVisionTrackMaterialsModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
|
|
|
var tempParameters = [AVMutableAudioMixInputParameters]()
|
|
|
var totalDur: Double = 0.0
|
|
|
for model in voices {
|
|
|
- if model.volume == 0 {
|
|
|
+ if model.volumeGain == 0 {
|
|
|
// 如果添加了会有刺啦音
|
|
|
BFLog(message: "音频音量 为0 不添加")
|
|
|
continue
|
|
|
}
|
|
|
- let duration = model.endTime - model.startTime
|
|
|
-
|
|
|
- let sticker = PQEditVisionTrackMaterialsModel()
|
|
|
- sticker.model_in = 0
|
|
|
- sticker.out = duration
|
|
|
- sticker.timelineIn = totalDur
|
|
|
- sticker.aptDuration = duration
|
|
|
- sticker.duration = duration
|
|
|
- sticker.locationPath = model.wavFilePath
|
|
|
- sticker.volumeGain = 100 // Float64(model.volume)
|
|
|
- tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
|
|
|
- totalDur += duration
|
|
|
+ tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: model, composition: composition)
|
|
|
+ totalDur += model.aptDuration
|
|
|
}
|
|
|
|
|
|
return tempParameters
|
|
|
}
|
|
|
|
|
|
- func mergeRecordVoiceAll(voices: [PQVoiceModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
|
|
|
+ func mergeRecordVoiceAll(voices: [PQEditVisionTrackMaterialsModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
|
|
|
var tempParameters = [AVMutableAudioMixInputParameters]()
|
|
|
+ var totalDur = 0.0
|
|
|
for model in voices {
|
|
|
- if model.volume == 0 {
|
|
|
+ if model.volumeGain == 0 {
|
|
|
// 如果添加了会有刺啦音
|
|
|
BFLog(message: "音频音量 为0 不添加")
|
|
|
continue
|
|
|
}
|
|
|
- let sticker = PQEditVisionTrackMaterialsModel()
|
|
|
- sticker.model_in = 0
|
|
|
- sticker.timelineIn = model.startTime
|
|
|
- sticker.out = model.endTime
|
|
|
- sticker.aptDuration = model.endTime - model.startTime
|
|
|
- sticker.duration = sticker.aptDuration
|
|
|
- sticker.locationPath = model.wavFilePath
|
|
|
- sticker.volumeGain = 100 // Float64(model.volume)
|
|
|
- tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
|
|
|
+ tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: model, composition: composition)
|
|
|
}
|
|
|
|
|
|
return tempParameters
|