|
@@ -99,7 +99,12 @@ class PQStuckPointEditerController: PQBaseViewController {
|
|
|
let sustomSwitchView = PQCustomSwitchView(frame: CGRect(x: 16, y: 0, width: 180, height: 30), titles: ["快节奏", "适中", "慢节奏"], defaultIndex: stuckPointMusicData?.speed ?? 2)
|
|
|
sustomSwitchView.switchChangeHandle = { [weak self] sender in
|
|
|
// 改变速率
|
|
|
- self?.stuckPointMusicData?.speed = sender.tag
|
|
|
+ if(self?.currentCreateStickersModel == .createStickersModelSpeed){
|
|
|
+ self?.stuckPointMusicData?.speed = sender.tag + 1
|
|
|
+ }else{
|
|
|
+ self?.stuckPointMusicData?.speed = sender.tag
|
|
|
+ }
|
|
|
+
|
|
|
self?.projectModel.sData?.getBGMSession()?.sectionTimeline?.audioTrack?.audioTrackMaterials.first?.bgmInfo?.rhythmMusicSpeed = sender.tag
|
|
|
// 播放前先暂停
|
|
|
// self?.playerView.stop()
|
|
@@ -1110,125 +1115,128 @@ extension PQStuckPointEditerController {
|
|
|
|
|
|
BFLog(message: "stuckPoints count is \(finallyStuckPoints.count)")
|
|
|
//一共裁剪的段数
|
|
|
-// var totalClipNum:Int = 0
|
|
|
+ var totalClipNum:Int = 0
|
|
|
+ for sticker in section.sectionTimeline!.visionTrack!.getEnableVisionTrackMaterials() {
|
|
|
+ if sticker.type == StickerType.VIDEO.rawValue {
|
|
|
+ let asset: AVURLAsset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + sticker.locationPath), options: nil)
|
|
|
+
|
|
|
+ var i:Int = 0
|
|
|
+ //一个视频切的的段落
|
|
|
+ var oneVideoClipNum:Int = 0
|
|
|
+
|
|
|
+ var realUsedMusicDuration = 0.0
|
|
|
+ while realUsedMusicDuration <= CMTimeGetSeconds(asset.duration) {
|
|
|
+ //快速段
|
|
|
+ let LA = maxSpeed * (finallyStuckPoints[i+1] - finallyStuckPoints[i])
|
|
|
+ realUsedMusicDuration = realUsedMusicDuration + Float64(LA)
|
|
|
+ if(realUsedMusicDuration > CMTimeGetSeconds(asset.duration)){ break}
|
|
|
+ oneVideoClipNum = oneVideoClipNum + 1
|
|
|
+ //慢速段
|
|
|
+ if(i + 2 >= finallyStuckPoints.count){
|
|
|
+ break
|
|
|
+ }
|
|
|
+ let LB = minSpeed * (finallyStuckPoints[i+2] - finallyStuckPoints[i+1])
|
|
|
+ realUsedMusicDuration = realUsedMusicDuration + Float64(LB)
|
|
|
+ oneVideoClipNum = oneVideoClipNum + 1
|
|
|
+ i = i + 1
|
|
|
+ }
|
|
|
+ BFLog(message: "单个视频\(sticker.locationPath)时长::\(CMTimeGetSeconds(asset.duration)) ,clipNum is:\(oneVideoClipNum)")
|
|
|
+ var lastOutTime:Float64 = 0.0
|
|
|
+ for clipindex in 0 ... oneVideoClipNum - 1 {
|
|
|
+ // deep copy sticker model 防止只有一个对象
|
|
|
+ let stickerjson = sticker.toJSONString(prettyPrint: false)
|
|
|
+ let deepCopySticker = Mapper<PQEditVisionTrackMaterialsModel>().map(JSONString: stickerjson!)
|
|
|
+ // 设置循环模式和适配模式
|
|
|
+ deepCopySticker?.generateDefaultValues()
|
|
|
+ //当前分段的速度
|
|
|
+ var tempSpeed:Float = 1.0
|
|
|
+
|
|
|
+ if(totalClipNum + 1 + clipindex < finallyStuckPoints.count){
|
|
|
+ deepCopySticker?.speedRate = tempSpeed
|
|
|
+
|
|
|
+ //定义临时使用的变量
|
|
|
+ let tempModel_In = lastOutTime
|
|
|
+ let tempOut = lastOutTime + Float64(tempSpeed) * Float64(finallyStuckPoints[totalClipNum + 1 + clipindex] - finallyStuckPoints[totalClipNum + clipindex])
|
|
|
+
|
|
|
+ let tempTimelineIn = Float64(finallyStuckPoints[totalClipNum + clipindex])
|
|
|
+ let timelineOut = Float64(finallyStuckPoints[totalClipNum + 1 + clipindex])
|
|
|
+
|
|
|
+ //处理最后一点视频素材不够卡点时长 e.g. 0.3 卡点时长0.5
|
|
|
+ if(tempOut > realUsedMusicDuration){
|
|
|
+ BFLog(message: "最后一点视频素材不够卡点时长 ")
|
|
|
+ //最后一点素材时长
|
|
|
+ let lastAssetDuration = realUsedMusicDuration - tempOut
|
|
|
+ let pointDuration = timelineOut - tempTimelineIn
|
|
|
+ let needSpeed = lastAssetDuration / pointDuration
|
|
|
+ //当前卡点段为快速
|
|
|
+ if(tempSpeed >= 1){
|
|
|
+ if(needSpeed > 0.4 * Double(tempSpeed)){
|
|
|
+ deepCopySticker?.speedRate = tempSpeed
|
|
|
+ } else{
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }else{//当前卡点段为慢速
|
|
|
+ if(needSpeed > 0.4 * Double(tempSpeed) && needSpeed > 0.2){
|
|
|
+ deepCopySticker?.speedRate = tempSpeed
|
|
|
+ } else{
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ deepCopySticker?.model_in = tempModel_In
|
|
|
+ deepCopySticker?.out = tempOut
|
|
|
+
|
|
|
+ deepCopySticker?.timelineIn = tempTimelineIn
|
|
|
+ deepCopySticker?.timelineOut = timelineOut
|
|
|
+
|
|
|
+ lastOutTime = deepCopySticker?.out ?? 0
|
|
|
+
|
|
|
+ }
|
|
|
+ BFLog(message: " 创建 sticker crilp is in \(String(format: "%.6f", deepCopySticker?.model_in ?? 0)) out \(String(format: "%.6f", deepCopySticker?.out ?? 0)) ,分段素材时长:\(String(format: "%.6f", (deepCopySticker?.out ?? 0) - (deepCopySticker?.model_in ?? 0))) ,分段显示时长:\(String(format: "%.6f", (deepCopySticker?.timelineOut ?? 0) - (deepCopySticker?.timelineIn ?? 0))), 总时长\(CMTimeGetSeconds(asset.duration)) timelineIN: \(String(format: "%.6f", deepCopySticker?.timelineIn ?? 0)) timelineOUT:\(String(format: "%.6f", deepCopySticker?.timelineOut ?? 0)) speedRate:\(deepCopySticker?.speedRate ?? 0.0)")
|
|
|
+
|
|
|
+ if deepCopySticker != nil {
|
|
|
+ stickers.append(deepCopySticker!)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ totalClipNum = totalClipNum + oneVideoClipNum - 1
|
|
|
+ } else if sticker.type == StickerType.IMAGE.rawValue {
|
|
|
+ sticker.generateDefaultValues()
|
|
|
+ sticker.timelineIn = Float64(finallyStuckPoints[totalClipNum])
|
|
|
+ sticker.timelineOut = Float64(finallyStuckPoints[totalClipNum + 1])
|
|
|
+ stickers.append(sticker)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ///---
|
|
|
+// var totalStickerTimer:Float64 = CMTimeGetSeconds(playeTimeRange.start)
|
|
|
// for sticker in section.sectionTimeline!.visionTrack!.getEnableVisionTrackMaterials() {
|
|
|
// if sticker.type == StickerType.VIDEO.rawValue {
|
|
|
// let asset: AVURLAsset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + sticker.locationPath), options: nil)
|
|
|
//
|
|
|
-// var i:Int = 0
|
|
|
-// //一个视频切的的段落
|
|
|
-// var oneVideoClipNum:Int = 0
|
|
|
-//
|
|
|
-// var realUsedMusicDuration = 0.0
|
|
|
-// while realUsedMusicDuration <= CMTimeGetSeconds(asset.duration) {
|
|
|
-// //快速段
|
|
|
-// let LA = maxSpeed * (finallyStuckPoints[i+1] - finallyStuckPoints[i])
|
|
|
-// realUsedMusicDuration = realUsedMusicDuration + Float64(LA)
|
|
|
-// if(realUsedMusicDuration > CMTimeGetSeconds(asset.duration)){ break}
|
|
|
-// oneVideoClipNum = oneVideoClipNum + 1
|
|
|
-// //慢速段
|
|
|
-// let LB = minSpeed * (finallyStuckPoints[i+2] - finallyStuckPoints[i+1])
|
|
|
-// realUsedMusicDuration = realUsedMusicDuration + Float64(LB)
|
|
|
-// oneVideoClipNum = oneVideoClipNum + 1
|
|
|
-// i = i + 1
|
|
|
-// }
|
|
|
-// BFLog(message: "单个视频\(sticker.locationPath)时长::\(CMTimeGetSeconds(asset.duration)) ,clipNum is:\(oneVideoClipNum)")
|
|
|
-// var lastOutTime:Float64 = 0.0
|
|
|
-// for clipindex in 0 ... oneVideoClipNum - 1 {
|
|
|
-// // deep copy sticker model 防止只有一个对象
|
|
|
-// let stickerjson = sticker.toJSONString(prettyPrint: false)
|
|
|
-// let deepCopySticker = Mapper<PQEditVisionTrackMaterialsModel>().map(JSONString: stickerjson!)
|
|
|
-// // 设置循环模式和适配模式
|
|
|
-// deepCopySticker?.generateDefaultValues()
|
|
|
-// //当前分段的速度
|
|
|
-// var tempSpeed:Float = 1.0
|
|
|
-//
|
|
|
-// if(totalClipNum + 1 + clipindex < finallyStuckPoints.count){
|
|
|
-// deepCopySticker?.speedRate = tempSpeed
|
|
|
-//
|
|
|
-// //定义临时使用的变量
|
|
|
-// let tempModel_In = lastOutTime
|
|
|
-// let tempOut = lastOutTime + Float64(tempSpeed) * Float64(finallyStuckPoints[totalClipNum + 1 + clipindex] - finallyStuckPoints[totalClipNum + clipindex])
|
|
|
-//
|
|
|
-// let tempTimelineIn = Float64(finallyStuckPoints[totalClipNum + clipindex])
|
|
|
-// let timelineOut = Float64(finallyStuckPoints[totalClipNum + 1 + clipindex])
|
|
|
-//
|
|
|
-// //处理最后一点视频素材不够卡点时长 e.g. 0.3 卡点时长0.5
|
|
|
-// if(tempOut > realUsedMusicDuration){
|
|
|
-// BFLog(message: "最后一点视频素材不够卡点时长 ")
|
|
|
-// //最后一点素材时长
|
|
|
-// let lastAssetDuration = realUsedMusicDuration - tempOut
|
|
|
-// let pointDuration = timelineOut - tempTimelineIn
|
|
|
-// let needSpeed = lastAssetDuration / pointDuration
|
|
|
-// //当前卡点段为快速
|
|
|
-// if(tempSpeed >= 1){
|
|
|
-// if(needSpeed > 0.4 * Double(tempSpeed)){
|
|
|
-// deepCopySticker?.speedRate = tempSpeed
|
|
|
-// } else{
|
|
|
-// continue
|
|
|
-// }
|
|
|
-// }else{//当前卡点段为慢速
|
|
|
-// if(needSpeed > 0.4 * Double(tempSpeed) && needSpeed > 0.2){
|
|
|
-// deepCopySticker?.speedRate = tempSpeed
|
|
|
-// } else{
|
|
|
-// continue
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-// deepCopySticker?.model_in = tempModel_In
|
|
|
-// deepCopySticker?.out = tempOut
|
|
|
-//
|
|
|
-// deepCopySticker?.timelineIn = tempTimelineIn
|
|
|
-// deepCopySticker?.timelineOut = timelineOut
|
|
|
+// BFLog(message: "单个视频\(sticker.locationPath)时长::\(CMTimeGetSeconds(asset.duration))")
|
|
|
+// sticker.generateDefaultValues()
|
|
|
+// sticker.model_in = 0
|
|
|
+// sticker.out = CMTimeGetSeconds(asset.duration)
|
|
|
//
|
|
|
-// lastOutTime = deepCopySticker?.out ?? 0
|
|
|
+// sticker.timelineIn = totalStickerTimer
|
|
|
+// sticker.timelineOut = sticker.timelineIn + sticker.out
|
|
|
//
|
|
|
-// }
|
|
|
-// BFLog(message: " 创建 sticker crilp is in \(String(format: "%.6f", deepCopySticker?.model_in ?? 0)) out \(String(format: "%.6f", deepCopySticker?.out ?? 0)) ,分段素材时长:\(String(format: "%.6f", (deepCopySticker?.out ?? 0) - (deepCopySticker?.model_in ?? 0))) ,分段显示时长:\(String(format: "%.6f", (deepCopySticker?.timelineOut ?? 0) - (deepCopySticker?.timelineIn ?? 0))), 总时长\(CMTimeGetSeconds(asset.duration)) timelineIN: \(String(format: "%.6f", deepCopySticker?.timelineIn ?? 0)) timelineOUT:\(String(format: "%.6f", deepCopySticker?.timelineOut ?? 0)) speedRate:\(deepCopySticker?.speedRate ?? 0.0)")
|
|
|
+// totalStickerTimer = totalStickerTimer + sticker.out
|
|
|
//
|
|
|
-// if deepCopySticker != nil {
|
|
|
-// stickers.append(deepCopySticker!)
|
|
|
-// }
|
|
|
//
|
|
|
-// }
|
|
|
-// totalClipNum = totalClipNum + oneVideoClipNum - 1
|
|
|
// } else if sticker.type == StickerType.IMAGE.rawValue {
|
|
|
// sticker.generateDefaultValues()
|
|
|
-// sticker.timelineIn = Float64(finallyStuckPoints[totalClipNum])
|
|
|
-// sticker.timelineOut = Float64(finallyStuckPoints[totalClipNum + 1])
|
|
|
-// stickers.append(sticker)
|
|
|
+// sticker.timelineIn = totalStickerTimer
|
|
|
+// sticker.timelineOut = sticker.timelineIn + sticker.out
|
|
|
+//
|
|
|
+// totalStickerTimer = totalStickerTimer + sticker.out
|
|
|
+//
|
|
|
// }
|
|
|
+//
|
|
|
+// stickers.append(sticker)
|
|
|
// }
|
|
|
- ///---
|
|
|
- var totalStickerTimer:Float64 = CMTimeGetSeconds(playeTimeRange.start)
|
|
|
- for sticker in section.sectionTimeline!.visionTrack!.getEnableVisionTrackMaterials() {
|
|
|
- if sticker.type == StickerType.VIDEO.rawValue {
|
|
|
- let asset: AVURLAsset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + sticker.locationPath), options: nil)
|
|
|
-
|
|
|
- BFLog(message: "单个视频\(sticker.locationPath)时长::\(CMTimeGetSeconds(asset.duration))")
|
|
|
- sticker.generateDefaultValues()
|
|
|
- sticker.model_in = 0
|
|
|
- sticker.out = CMTimeGetSeconds(asset.duration)
|
|
|
-
|
|
|
- sticker.timelineIn = totalStickerTimer
|
|
|
- sticker.timelineOut = sticker.timelineIn + sticker.out
|
|
|
-
|
|
|
- totalStickerTimer = totalStickerTimer + sticker.out
|
|
|
-
|
|
|
-
|
|
|
- } else if sticker.type == StickerType.IMAGE.rawValue {
|
|
|
- sticker.generateDefaultValues()
|
|
|
- sticker.timelineIn = totalStickerTimer
|
|
|
- sticker.timelineOut = sticker.timelineIn + sticker.out
|
|
|
-
|
|
|
- totalStickerTimer = totalStickerTimer + sticker.out
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- stickers.append(sticker)
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1311,8 +1319,9 @@ extension PQStuckPointEditerController {
|
|
|
finallyStuckPoints.removeAll()
|
|
|
//注意推荐时间位置和后面最近的卡点时间与0.3的关系
|
|
|
//保存丢卡点处理后的卡点信息推荐开始到最后倒数第二个
|
|
|
- let stuckPointsTemp = getUsedStuckPoint(seed: stuckPointMusicData?.speed ?? 0)
|
|
|
-
|
|
|
+ let stuckPointsTemp:Array<Float>
|
|
|
+
|
|
|
+
|
|
|
|
|
|
if(selectedDataCount == selectedImageDataCount){
|
|
|
|
|
@@ -1321,6 +1330,7 @@ extension PQStuckPointEditerController {
|
|
|
var realUsedMusicDuration:Float = 0.0
|
|
|
switch model {
|
|
|
case .createStickersModelPoint://跳跃卡点
|
|
|
+ stuckPointsTemp = getUsedStuckPoint(seed: stuckPointMusicData?.speed ?? 0)
|
|
|
// L/(n+1) L -原视觉素材总时长 n-抛留倍数
|
|
|
realUsedMusicDuration = Float(selectedTotalDuration) / (Float(maxSpeed) + 1)
|
|
|
|
|
@@ -1353,7 +1363,10 @@ extension PQStuckPointEditerController {
|
|
|
|
|
|
break
|
|
|
case .createStickersModelSpeed://快慢速
|
|
|
-
|
|
|
+// (1:快节奏,2:适中,3:慢节奏)
|
|
|
+// 快慢速 (2:快节奏,3:适中,4:慢节奏)
|
|
|
+ stuckPointsTemp = getUsedStuckPoint(seed: (stuckPointMusicData?.speed ?? 0) + 1)
|
|
|
+
|
|
|
/*
|
|
|
- A-视频中的快速片段
|
|
|
- B-视频中的慢速片段
|
|
@@ -1412,9 +1425,36 @@ extension PQStuckPointEditerController {
|
|
|
|
|
|
break
|
|
|
case .createStickersModelOnlyMusic://仅音乐
|
|
|
- //时长为所有素材总时长
|
|
|
- finallyStuckPoints.append(Float(stuckPointMusicData?.startTime ?? 0) + Float(selectedTotalDuration))
|
|
|
-
|
|
|
+
|
|
|
+ stuckPointsTemp = getUsedStuckPoint(seed: 1)
|
|
|
+ //要拼接的段数
|
|
|
+ var clipNum:Int = 0
|
|
|
+ //所有段的时长总和
|
|
|
+ var tempTime:Float = 0.0
|
|
|
+ var i:Int = 0
|
|
|
+ while tempTime < Float(selectedTotalDuration) {
|
|
|
+
|
|
|
+ //回环从头取
|
|
|
+ if(i+2 >= stuckPointsTemp.count){
|
|
|
+ i = 0
|
|
|
+ }
|
|
|
+ //快速段
|
|
|
+ let LA = (stuckPointsTemp[i+1] - stuckPointsTemp[i])
|
|
|
+ tempTime = tempTime + Float(LA)
|
|
|
+ clipNum = clipNum + 1
|
|
|
+ if(tempTime > Float(selectedTotalDuration)){ break}
|
|
|
+ //慢速段
|
|
|
+ let LB = (stuckPointsTemp[i+2] - stuckPointsTemp[i+1])
|
|
|
+ tempTime = tempTime + Float(LB)
|
|
|
+ i = i + 1
|
|
|
+ clipNum = clipNum + 1
|
|
|
+ }
|
|
|
+
|
|
|
+ //拼接要使用的卡点信息
|
|
|
+ for i in 0...clipNum {
|
|
|
+ finallyStuckPoints.append(stuckPointsTemp[i % stuckPointsTemp.count] + Float(i / stuckPointsTemp.count) * (stuckPointsTemp.first ?? 0))
|
|
|
+ }
|
|
|
+
|
|
|
break
|
|
|
|
|
|
}
|