|
@@ -132,4 +132,82 @@ public class BFRecordItemModel: NSObject {
|
|
dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
|
|
dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// 视频分解成帧
|
|
|
|
+ /// - parameter fps : 自定义帧数 每秒内取的帧数
|
|
|
|
+ /// - parameter firstImagesCount : 获取首先N张连续视频帧后先返回给调用方使用作为缓冲
|
|
|
|
+ /// - parameter splitCompleteClosure : 回调
|
|
|
|
+ func splitVideoFileUrlFps(fps: Double, firstImagesCount:Int = 0, splitCompleteClosure: @escaping ((Bool, [UIImage]) -> Void)) {
|
|
|
|
+ guard let localPath = localPath else {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var splitImages = [UIImage]()
|
|
|
|
+
|
|
|
|
+ var times = [NSValue]()
|
|
|
|
+
|
|
|
|
+ let urlAsset = AVURLAsset(url: URL(fileURLWithPath: localPath))
|
|
|
|
+ let start = 0
|
|
|
|
+ let end = Int(urlAsset.duration.seconds * Float64(fps))
|
|
|
|
+
|
|
|
|
+ for i in start...end {
|
|
|
|
+ let timeValue = NSValue(time: CMTimeMake(value: Int64(i * 1000), timescale: Int32(fps * 1000)))
|
|
|
|
+
|
|
|
|
+ times.append(timeValue)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
|
|
|
|
+ imgGenerator.requestedTimeToleranceBefore = CMTime.zero
|
|
|
|
+ imgGenerator.requestedTimeToleranceAfter = CMTime.zero
|
|
|
|
+ imgGenerator.appliesPreferredTrackTransform = true
|
|
|
|
+ let timesCount = times.count
|
|
|
|
+ var cocu = 0
|
|
|
|
+ // 获取每一帧的图片
|
|
|
|
+ imgGenerator.generateCGImagesAsynchronously(forTimes: times) { _, image, _, result, _ in
|
|
|
|
+ cocu += 1
|
|
|
|
+ switch result {
|
|
|
|
+ case AVAssetImageGenerator.Result.cancelled:
|
|
|
|
+ BFLog(1, message: "splitVideo: cancel")
|
|
|
|
+
|
|
|
|
+ case AVAssetImageGenerator.Result.failed:
|
|
|
|
+ BFLog(1, message: "splitVideo: failed")
|
|
|
|
+
|
|
|
|
+ case AVAssetImageGenerator.Result.succeeded:
|
|
|
|
+ let framImg = UIImage(cgImage: image!)
|
|
|
|
+ splitImages.append(framImg)
|
|
|
|
+ // BFLog(1, message: "aaa: \(requestedTime.seconds) - \(actualTime.seconds)")
|
|
|
|
+ @unknown default:
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if cocu == firstImagesCount {
|
|
|
|
+ splitCompleteClosure(false, splitImages)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if cocu == timesCount { // 最后一帧时 回调赋值
|
|
|
|
+ splitCompleteClosure(true, splitImages)
|
|
|
|
+ BFLog(1, message: "splitVideo: complete")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// 视频分解成帧
|
|
|
|
+ /// - parameter fileUrl : 视频地址
|
|
|
|
+ /// - parameter fps : 自定义帧数 每秒内取的帧数
|
|
|
|
+ /// - parameter splitCompleteClosure : 回调
|
|
|
|
+ func getThumbImageAtTime(urlAsset: AVURLAsset, time: CMTime) -> UIImage? {
|
|
|
|
+ let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
|
|
|
|
+ imgGenerator.requestedTimeToleranceBefore = CMTime.zero
|
|
|
|
+ imgGenerator.requestedTimeToleranceAfter = CMTime.zero
|
|
|
|
+
|
|
|
|
+ var cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)
|
|
|
|
+ if cgImg == nil {
|
|
|
|
+ imgGenerator.requestedTimeToleranceBefore = CMTime.positiveInfinity
|
|
|
|
+ imgGenerator.requestedTimeToleranceAfter = CMTime.positiveInfinity
|
|
|
|
+ cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return cgImg == nil ? nil : UIImage(cgImage: cgImg!)
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|