10

I have a folder in my documents directory containing images and videos, In my app i have a collection view that displays the images in each cell.

I have accomplished this with a load image function that returns a UIImage

    // Get the UI Image from the path passed in
    let image = UIImage(contentsOfFile: path)

    if image == nil
    {
        print("No Image at this path");
    }
    else
    {
        return image
    }

However I can't seem to find something equivalent for videos, Ideally I want it to show as the video player thing like in photo album where you see a still of the video with a little play button on it that when clicked plays the video.

Failing that purely being able to get a still from the video at the specified path I have to be returned as a UIImage I can display would be ok.

I am new to iOS stuff so just wondering if there is some equivalent type like UIImage for videos that means I can just load and display it on the collection view.

Marcello B.
  • 4,177
  • 11
  • 45
  • 65
AngryDuck
  • 4,358
  • 13
  • 57
  • 91

4 Answers4

38

You need a snapshot of the video and display it along with a play button. Here is my func in Swift 2 that can get you the video-snapshot for a video file at path filePathLocal:

func videoSnapshot(filePathLocal: String) -> UIImage? {

    let vidURL = URL(fileURLWithPath:filePathLocal as String)
    let asset = AVURLAsset(url: vidURL)
    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)
        return UIImage(cgImage: imageRef)
    }
    catch let error as NSError
    {
        print("Image generation failed with error \(error)")
        return nil
    }
}
tyoc213
  • 1,223
  • 18
  • 21
Nishant
  • 12,529
  • 9
  • 59
  • 94
  • I followed your method and generated an image snapshot. however the orientation is wrong, is it just me or that is supposed to be the correct outcome? How do I correct the snapshot orientation? – Happiehappie Apr 18 '16 at 04:57
  • This orientation issue is new. Last time I checked, this code was working just fine. – Nishant Apr 18 '16 at 07:27
  • is there a way to get a temporary path to the freshly created UIImage? – user3766930 Sep 20 '16 at 19:26
  • You will have to save the new image locally yourself and then use the path. Check this answer here. http://stackoverflow.com/a/14532028/1463604 – Nishant Sep 21 '16 at 15:50
  • 1
    Still work on swift 5~~~ Cool~ Remember to **import AVKit** – Jerome Dec 10 '19 at 00:44
10

Swift 3 version

func videoPreviewUiimage(fileName:String) -> UIImage? {
    let filePath = NSString(string: "~/").expandingTildeInPath.appending("/Documents/").appending(fileName)

    let vidURL = NSURL(fileURLWithPath:filePath)
    let asset = AVURLAsset(url: vidURL as URL)
    let generator = AVAssetImageGenerator(asset: asset)
    generator.appliesPreferredTrackTransform = true

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

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

Based on Nishant answer above.

mourodrigo
  • 2,232
  • 28
  • 18
8

Using a URL for your path is better than using String:

func videoPreviewImage(url: URL) -> UIImage? {
    let asset = AVURLAsset(url: url)
    let generator = AVAssetImageGenerator(asset: asset)
    generator.appliesPreferredTrackTransform = true
    if let cgImage = try? generator.copyCGImage(at: CMTime(seconds: 2, preferredTimescale: 60), actualTime: nil) {
        return UIImage(cgImage: cgImage)
    }
    else {
        return nil
    }
}
Aaron Halvorsen
  • 2,610
  • 1
  • 23
  • 31
  • will it work for .mp4 video url how will i use it on imageview for single url i have video url "http://13.235.176.85/kick_cast_backend/public/storage/Video/Dilip Tiwari/8BY4vE7EvrUaQLtZ5LNS8hs3oD5M1A7XmSxd8Vsv.mp4" i tried but its not working pls update your answer – Dilip Tiwari Sep 22 '20 at 05:49
7

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)
    return UIImage(cgImage: imageRef)
}
catch let error as NSError
{
    print("Image generation failed with error \(error)")
    return nil
}

}
Bilal Arslan
  • 307
  • 3
  • 10
Disha
  • 608
  • 7
  • 10