'Create a thumbnail or image of an AVPlayer at current time

I have implemented an AVPlayer and i want to take an image or thumbnail when clicking on a toolbar button and open in a new UIViewController with UIImageView. The image should be scaled exactly like the AVPlayer. The segue is already working, i just have to implement that i get the image at the current play time.

Thanks!



Solution 1:[1]

Try this

 - (UIImage*)takeScreeenShot {

 AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL
 options:nil];

 AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

 imageGenerator.appliesPreferredTrackTransform = YES;

 NSError *err = NULL;

 CMTime time = CMTimeMake(1, 60); // time range in which you want
 screenshot

 CGImageRef imgRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL
 error:&err];

 return [[UIImage alloc] initWithCGImage:imgRef];

 }

Hope this helps !!!

Solution 2:[2]

Swift 2.x:

let asset = AVAsset(...)
let imageGenerator = AVAssetImageGenerator(asset: asset)
let screenshotTime = CMTime(seconds: 1, preferredTimescale: 1)
if let imageRef = try? imageGenerator.copyCGImageAtTime(screenshotTime, actualTime: nil) {

    let image = UIImage(CGImage: imageRef)

    // do something with your image
}

Solution 3:[3]

Add below code to generate thumbnail from video.

AVURLAsset *assetURL = [[AVURLAsset alloc] initWithURL:partOneUrl options:nil]; 

AVAssetImageGenerator *assetGenerator = [[AVAssetImageGenerator alloc] initWithAsset:assetURL]; 

assetGenerator.appliesPreferredTrackTransform = YES;  

NSError *err = NULL; 

CMTime time = CMTimeMake(1, 2);     

CGImageRef imgRef = [assetGenerator copyCGImageAtTime:time actualTime:NULL error:&err]; 

UIImage *one = [[UIImage alloc] initWithCGImage:imgRef];    

Solution 4:[4]

This is how I get a shot of the current visible frame on the scene in Swift:

The key is to

  1. get the current time of the player which is of type CMTime
  2. convert that time into seconds of type Float64
  3. switch the secondss back to CMTime using CMTimeMake. The first parameter which would be where the seconds goes should be cast to Int64

Code:

var myImage: UIImage?

guard let player = player else { return }

let currentTime: CMTime = player.currentTime() // step 1.
let currentTimeInSecs: Float64 = CMTimeGetSeconds(currentTime) // step 2.
let actionTime: CMTime = CMTimeMake(Int64(currentTimeInSecs), 1) // step 3.

let asset = AVAsset(url: fileUrl)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true // prevent image rotation

do{
    let imageRef =  try imageGenerator.copyCGImage(at: actionTime, actualTime: nil)

     myImage = UIImage(cgImage: imageRef)
}catch let err as NSError{
    print(err.localizedDescription)
}

Solution 5:[5]

Swift extension for generating thumbnails from video

extension AVPlayer {
    func generateThumbnail(time: CMTime) -> UIImage? {
        guard let asset = currentItem?.asset else { return nil }
        let imageGenerator = AVAssetImageGenerator(asset: asset)

        do {
            let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
            return UIImage(cgImage: cgImage)
        } catch {
            print(error.localizedDescription)
        }

        return nil
    }
}

Solution 6:[6]

When you need to create multiple thumbnails at once the class AVAssetImageGenerator is golden, as it provides an async way.

If you need a Thumbnail-Image of the player's current frame, simply render it's View (platform specific) or its Layer (platform independent):

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGSize frameSize = _playerLayer.frame.size;
CGContextRef thumbnailContext = CGBitmapContextCreate(nil, frameSize.width, frameSize.height, 8, 0, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
[_playerLayer renderInContext:thumbnailContext];
CGImageRef playerThumbnail = CGBitmapContextCreateImage(thumbnailContext);
CGContextRelease(thumbnailContext);

This is super fast and works synchronously.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rahulg
Solution 2 JAL
Solution 3 FelixSFD
Solution 4 Lance Samaria
Solution 5 ????????? ??????
Solution 6 Karsten