Bladeren bron

modify: 完善,卡点模板,当选中视频不够时长时,采用最后一帧进行补

Melody 5 jaren geleden
bovenliggende
commit
fa3854eb06
2 gewijzigde bestanden met toevoegingen van 58 en 2 verwijderingen
  1. 56 0
      SuperShow/Tool/WSSMediaOperationTool.swift
  2. 2 2
      SuperShow/UI/Template/Models/WSSVideoInfoModel.swift

+ 56 - 0
SuperShow/Tool/WSSMediaOperationTool.swift

@@ -646,6 +646,62 @@ extension WSSMediaOperationTool {
         }
     }
 
+    class func repeatVideoWithLastFrame(_ video: AVAsset, to duration: TimeInterval) throws -> AVAsset? {
+        guard let videoTrack = video.tracks(withMediaType: .video).first else {
+            return nil
+        }
+
+        // 如果传入的视频时长比指定时长还大,则直接返回原视频
+        if video.duration.seconds >= duration {
+            return video
+        }
+
+        let composition = AVMutableComposition()
+        guard let videoCT = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid) else {
+            WSSSimpleLog("======>创建AVMutableCompositionTrack失败")
+            return video
+        }
+        // 保证拼接后重新生成的视频的旋转角度不变
+        videoCT.preferredTransform = videoTrack.preferredTransform
+
+        let audioTrack = video.tracks(withMediaType: AVMediaType.audio).first
+        var audioCT: AVMutableCompositionTrack?
+        if audioTrack != nil {
+            // 说明原视频中包含有音频
+            audioCT = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
+        }
+
+        do {
+            let originalDuration = videoTrack.timeRange.duration
+            let timeScale = originalDuration.timescale
+
+            /// 插入源视频
+            try videoCT.insertTimeRange(videoTrack.timeRange, of: videoTrack, at: videoCT.timeRange.duration)
+            if let ct = audioCT, let at = audioTrack {
+                try ct.insertTimeRange(at.timeRange, of: at, at: videoCT.timeRange.duration)
+            }
+
+            /// 计算缺少的时间
+            let lackTime = CMTimeMakeWithSeconds(duration, preferredTimescale: timeScale) - originalDuration
+
+            /// 定义最后一帧时间段
+            let lastSecondTime = CMTimeMake(value: originalDuration.value - Int64(20), timescale: timeScale)
+            let perDuration = originalDuration - lastSecondTime
+            let perTimeRange = CMTimeRangeMake(start: lastSecondTime, duration: perDuration)
+
+            let needAddTime = lackTime - perDuration
+
+            /// 把最后一帧,拉长到总时长来补充最后一帧
+            videoCT.scaleTimeRange(perTimeRange, toDuration: needAddTime)
+            /// (TODO)是否要把音频也补充? 感觉音频最后一帧声音时无意义的,但是后面如果要加,要注意timeScale与音频不一样的
+            return composition
+
+        } catch {
+            WSSLog("#repeat-err#: \(error)")
+            throw error
+        }
+    }
+
     /// 将一个视频拉伸到指定时长,以此来改变视频速率
     /// - Parameter video: 源视频
     /// - Parameter duration: 拉伸的指定时长 speed = speedDuration / videoDuration

+ 2 - 2
SuperShow/UI/Template/Models/WSSVideoInfoModel.swift

@@ -121,9 +121,9 @@ extension WSSVideoInfoModel {
                 }
             }
 
-            /// 补充裁剪
+            /// 补充裁剪(规定当选中视频时长不够时,采用补充最后一帧处理)
             if selectedDruation > originDuarion,
-                let newAsset = try WSSMediaOperationTool.repeatVideo(destAsset, to: selectedDruation.seconds) {
+                let newAsset = try WSSMediaOperationTool.repeatVideoWithLastFrame(destAsset, to: selectedDruation.seconds) {
                 WSSSimpleLog("获取裁剪视频+++++++++")
                 destAsset = newAsset
                 print("=====>VideoDuration:\(destAsset.duration.seconds)")