|
@@ -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
|