29

I am trying to acquire a thumbnail from a video url. The video is a stream (HLS) with the m3u8 format. I've already tried requestThumbnailImagesAtTimes from the MPMoviePlayerController, but that didn't work. Does anyone have a solution for that problem? If so how'd you do it?

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
MrCoinSiX
  • 571
  • 1
  • 6
  • 13
  • You can visit to the link given below. Very useful. http://developer.apple.com/library/IOs/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html#//apple_ref/occ/cl/AVAssetImageGenerator – Ajeet Pratap Maurya Nov 11 '11 at 06:02
  • Check it for once https://stackoverflow.com/a/45164607/3908884 – Meet Doshi Jul 18 '17 at 11:00

9 Answers9

48

If you don't want to use MPMoviePlayerController, you can do this:

    AVAsset *asset = [AVAsset assetWithURL:sourceURL];
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
    CMTime time = CMTimeMake(1, 1);
    CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);  // CGImageRef won't be released by ARC

Here's an example in Swift:

func thumbnail(sourceURL sourceURL:NSURL) -> UIImage {
    let asset = AVAsset(URL: sourceURL)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    let time = CMTime(seconds: 1, preferredTimescale: 1)

    do {
        let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
        return UIImage(CGImage: imageRef)
    } catch {
        print(error)
        return UIImage(named: "some generic thumbnail")!
    }
}

I prefer using AVAssetImageGenerator over MPMoviePlayerController because it is thread-safe, and you can have more than one instantiated at a time.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
25

Acquire a thumbnail from a video url.

    NSString *strVideoURL = @"http://www.xyzvideourl.com/samplevideourl";
    NSURL *videoURL = [NSURL URLWithString:strVideoURL] ;
    MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:videoURL]autorelease];
    UIImage  *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
    player = nil;

Replace your video URL string with strVideoURL. You will get thumbnail as a output from video. And thumbnail is UIImage type data !

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Faizan Refai
  • 833
  • 10
  • 13
  • 2
    i am using this code for the thumbnail of video from the url of youtube but it is not giving me the image.i am using to put the thumbnail in the table view so can you help me – Jaspreet Singh Oct 04 '12 at 08:26
  • I think you can't get the video from Youtube URL like this www.youtube.com/watch?v=xxxxxxx – Shinigamae Oct 29 '12 at 04:26
  • I'm using this url http://www.sciencentral.com/news/image_db/2024515/NNM2212_AntPower_MSTR.mov I get nil thumbnail image. please help – ruyamonis346 Aug 07 '13 at 12:23
9
-(UIImage *)loadThumbNail:(NSURL *)urlVideo
{    
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:urlVideo options:nil];
    AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generate.appliesPreferredTrackTransform=TRUE;
    NSError *err = NULL;
    CMTime time = CMTimeMake(1, 60);
    CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
    NSLog(@"err==%@, imageRef==%@", err, imgRef);
    return [[UIImage alloc] initWithCGImage:imgRef];
}

Add AVFoundation framework in your project and don't forget to import <AVFoundation/AVFoundation.h> and you have to pass the path of your video saved in document directory as a parameter and receive the image as UIImage.

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Ankit Goyal
  • 3,019
  • 1
  • 21
  • 26
4

you can get the thumbnail from your video url with the use of below code

MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:videoURL]autorelease];
UIImage  *thumbnail = [player thumbnailImageAtTime:0.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
D-eptdeveloper
  • 2,430
  • 1
  • 16
  • 30
  • 1
    Technically deprecated in iOS 7, but it still works, and I could never figure out how to use – requestThumbnailImagesAtTimes:timeOption: properly – Rob R. Oct 02 '13 at 16:28
  • 4
    What is recommended to use in ios7? – Dejell Oct 06 '13 at 06:56
2

Maybe this is useful for someone else who faces the same problem. I needed an easy solution for creating a thumbnail for Images, PDFs and Videos. To solve that problem I've created the following Library (in Swift).

https://github.com/prine/ROThumbnailGenerator

The usage is very straightforward: var thumbnailImage = ROThumbnail.getThumbnail(url)

It has internally three different implementations and depending on the file extension it does create the thumbnail. You can easily add your own implementation if you need a thumbnail creator for another file extension.

Prine
  • 12,192
  • 8
  • 40
  • 59
2

Swift 3 Version :

func createThumbnailOfVideoFromFileURL(videoURL: String) -> UIImage? {
    let asset = AVAsset(url: URL(string: videoURL)!)
    let assetImgGenerate = AVAssetImageGenerator(asset: asset)
    assetImgGenerate.appliesPreferredTrackTransform = true
    let time = CMTimeMakeWithSeconds(Float64(1), 100)
    do {
        let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
        let thumbnail = UIImage(cgImage: img)
        return thumbnail
    } catch {
        // Set a default image if Image is not acquired
        return UIImage(named: "ico_placeholder")
    }
}
Ankit Kumar Gupta
  • 3,994
  • 4
  • 31
  • 54
2

For Swift 3.0:

  func generateThumbnailForVideoAtURL(filePathLocal: NSString) -> UIImage? {
    let vidURL = NSURL(fileURLWithPath:filePathLocal as String)
    let asset = AVURLAsset(url: vidURL as URL)
    let generator = AVAssetImageGenerator(asset: asset)
    generator.appliesPreferredTrackTransform = true

    let timestamp = CMTime(seconds: 1, preferredTimescale: 60)

    do {
        let imageRef = try generator.copyCGImage(at: timestamp, actualTime: nil)
        let frameImg    : UIImage = UIImage(cgImage: imageRef)
        return frameImg
    } catch let error as NSError {
        print("Image generation failed with error ::\(error)")
        return nil
    }
}
Disha
  • 608
  • 7
  • 10
2

For Swift 5 you can get it this way:

First import AVKit or AVFoundation to ViewController

import AVKit

Code:

// Get Thumbnail Image from URL
private func getThumbnailFromUrl(_ url: String?, _ completion: @escaping ((_ image: UIImage?)->Void)) {

    guard let url = URL(string: url ?? "") else { return }

    DispatchQueue.main.async {
        let asset = AVAsset(url: url)
        let assetImgGenerate = AVAssetImageGenerator(asset: asset)
        assetImgGenerate.appliesPreferredTrackTransform = true

        let time = CMTimeMake(value: 2, timescale: 1)
        do {
            let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
            let thumbnail = UIImage(cgImage: img)
            completion(thumbnail)
        } catch {
            print("Error :: ", error.localizedDescription)
            completion(nil)
        }
    }
}

Usage

@IBOutlet weak imgThumbnail: ImageView! 

and then call getThumbnailFromUrl method and pass URL as a Sting

self.getThumbnailFromUrl(videoURL) { [weak self] (img) in

    guard let `self` = self else { return }

    if let img = img {
        self.imgThumbnail.image = img
    }
}

Thank you

NøBi Mac
  • 505
  • 5
  • 15
0

Swift 2 code with AVAssetImageGenerator:

func thumbnailImageForVideo(url:NSURL) -> UIImage?
{
    let asset = AVAsset(URL: url)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.appliesPreferredTrackTransform = true

    var time = asset.duration
    //If possible - take not the first frame (it could be completely black or white on camara's videos)
    time.value = min(time.value, 2)

    do {
        let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
        return UIImage(CGImage: imageRef)
    }
    catch let error as NSError
    {
        print("Image generation failed with error \(error)")
        return nil
    }
}
Avt
  • 16,927
  • 4
  • 52
  • 72