How to create thumbnail in swift from a local video file ?
For example if the video file path is located here :
file:///Users/Dev/Library/Developer/Co
This is a cleaned up version of David's answer and tested against iOS 11 / Swift 4.x.
Please note the different calls for handling the initial time based on which version of Swift you are using.
func generateThumbnail(url: URL) -> UIImage? {
do {
let asset = AVURLAsset(url: url)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true
// Select the right one based on which version you are using
// Swift 4.2
let cgImage = try imageGenerator.copyCGImage(at: .zero,
actualTime: nil)
// Swift 4.0
let cgImage = try imageGenerator.copyCGImage(at: kCMTimeZero,
actualTime: nil)
return UIImage(cgImage: cgImage)
} catch {
print(error.localizedDescription)
return nil
}
}
AVURLAsset
from the provided URL
AVAssetImageGenerator
using the newly created AVURLAsset
, is responsible for making the thumbnailCGImage
at the first frame of the video trackUIImage
using the newly created CGImage & returns itIt's better to write less and simple code for understanding. This is what I convert the solutions in Swift (3.1 ... 5.2)
import AVFoundation
func imagePreview(from moviePath: URL, in seconds: Double) -> UIImage? {
let timestamp = CMTime(seconds: seconds, preferredTimescale: 60)
let asset = AVURLAsset(url: moviePath)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
guard let imageRef = try? generator.copyCGImage(at: timestamp, actualTime: nil) else {
return nil
}
return UIImage(cgImage: imageRef)
}
Hope it will help someone.
Swift 5.3
As an alternative to other answers, with slight modification I decided to make an URL extension.
import AVFoundation
extension URL {
func generateThumbnail() -> UIImage? {
do {
let asset = AVURLAsset(url: self)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true
// Swift 5.3
let cgImage = try imageGenerator.copyCGImage(at: .zero,
actualTime: nil)
return UIImage(cgImage: cgImage)
} catch {
print(error.localizedDescription)
return nil
}
}
}
Usage:
let image = someURL.generateThumbnail()
BaseZen's answer translated to Swift 2:
import UIKit
import AVFoundation
do {
let asset = AVURLAsset(URL: NSURL(fileURLWithPath: "/that/long/path"), options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let cgImage = try imgGenerator.copyCGImageAtTime(CMTimeMake(0, 1), actualTime: nil)
let uiImage = UIImage(CGImage: cgImage)
let imageView = UIImageView(image: uiImage)
// lay out this image view, or if it already exists, set its image property to uiImage
} catch let error as NSError {
print("Error generating thumbnail: \(error)")
}
Translated with some edits from:
First frame of a video using AVFoundation
var err: NSError? = nil
let asset = AVURLAsset(URL: NSURL(fileURLWithPath: "/that/long/path"), options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
let cgImage = imgGenerator.copyCGImageAtTime(CMTimeMake(0, 1), actualTime: nil, error: &err)
// !! check the error before proceeding
let uiImage = UIImage(CGImage: cgImage)
let imageView = UIImageView(image: uiImage)
// lay out this image view, or if it already exists, set its image property to uiImage
func saveImageDocumentDirectoryWithDate(tempImage:UIImage, block : @escaping (_ url: URL?) -> Void ){
let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let random : String = randomString(length: 5)
let fileURL = documentsDirectoryURL.appendingPathComponent(String(format:"CPImage%@.png",random))
do { try tempImage.pngData()?.write(to: fileURL) }
catch { block(nil) }
block(fileURL)}