AVAsset+Ex.swift 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //
  2. // AVAsset+Ex.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/23.
  6. //
  7. import UIKit
  8. import AVFoundation
  9. public extension AVAsset {
  10. func getImage(at time: TimeInterval, videoComposition: AVVideoComposition? = nil) -> UIImage? {
  11. let assetImageGenerator = AVAssetImageGenerator(asset: self)
  12. assetImageGenerator.appliesPreferredTrackTransform = true
  13. assetImageGenerator.videoComposition = videoComposition
  14. assetImageGenerator.apertureMode = .encodedPixels
  15. do {
  16. let thumbnailImageRef = try assetImageGenerator.copyCGImage(
  17. at: CMTime(
  18. value: CMTimeValue(time),
  19. timescale: duration.timescale
  20. ),
  21. actualTime: nil
  22. )
  23. let image = UIImage.init(cgImage: thumbnailImageRef)
  24. return image
  25. } catch {
  26. return nil
  27. }
  28. }
  29. func getImage(
  30. at time: TimeInterval,
  31. videoComposition: AVVideoComposition? = nil,
  32. imageGenerator: ((AVAssetImageGenerator) -> Void)? = nil,
  33. completion: @escaping (AVAsset, UIImage?, AVAssetImageGenerator.Result) -> Void
  34. ) {
  35. loadValuesAsynchronously(forKeys: ["duration"]) { [weak self] in
  36. guard let self = self else {
  37. DispatchQueue.main.async {
  38. completion(.init(), nil, .failed)
  39. }
  40. return
  41. }
  42. if self.statusOfValue(forKey: "duration", error: nil) != .loaded {
  43. DispatchQueue.main.async {
  44. completion(self, nil, .failed)
  45. }
  46. return
  47. }
  48. let generator = AVAssetImageGenerator(asset: self)
  49. generator.appliesPreferredTrackTransform = true
  50. generator.videoComposition = videoComposition
  51. let time = CMTime(value: CMTimeValue(time), timescale: self.duration.timescale)
  52. let array = [NSValue(time: time)]
  53. generator.generateCGImagesAsynchronously(
  54. forTimes: array
  55. ) { (_, cgImage, _, result, _) in
  56. if let image = cgImage, result == .succeeded {
  57. var image = UIImage(cgImage: image)
  58. if image.imageOrientation != .up,
  59. let img = image.normalizedImage() {
  60. image = img
  61. }
  62. DispatchQueue.main.async {
  63. completion(self, image, result)
  64. }
  65. }else {
  66. DispatchQueue.main.async {
  67. completion(self, nil, result)
  68. }
  69. }
  70. }
  71. DispatchQueue.main.async {
  72. imageGenerator?(generator)
  73. }
  74. }
  75. }
  76. }