ios 快速从本地视频创建缩略图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31779150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:07:28  来源:igfitidea点击:

Creating thumbnail from local video in swift

iosswiftiphonevideo-capture

提问by Ralph

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/CoreSimulator/Devices/F33222DF-D8F0-448B-A127-C5B03C64D0DC/data/Containers/Data/Application/4BC62DBF-0108-453C-9324-5BC0E356FE24/tmp/trim.059D11E6-F0EF-43DB-9E97-CA4F1F95D6B6.MOV

file:///Users/Dev/Library/Developer/CoreSimulator/Devices/F33222DF-D8F0-448B-A127-C5B03C64D0DC/data/Containers/Data/Application/4BC62DBF-0108-453C-9324-5BC0E356FE24/tmp/trim.059D11E6-F0EF-43DB-9E97-CA4F1F95D6B6.MOV

Thank you.

谢谢你。

回答by David Seek

BaseZen's answer translated Swift 3/ Swift 4

BaseZen 的回答翻译了Swift 3/ Swift 4

You need to set the location of the video you want to make a thumbnail of as the url asset path, like:

您需要将要制作缩略图的视频的位置设置为 url 资产路径,例如:

Don't forget to import AVFoundation

不要忘记 import AVFoundation

func generateThumbnail(path: URL) -> UIImage? {
    do {
        let asset = AVURLAsset(url: path, options: nil)
        let imgGenerator = AVAssetImageGenerator(asset: asset)
        imgGenerator.appliesPreferredTrackTransform = true
        let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
        let thumbnail = UIImage(cgImage: cgImage)
        return thumbnail
    } catch let error {
        print("*** Error generating thumbnail: \(error.localizedDescription)")
        return nil
    }
}

For everyone having issues with this I have created the following drop in example hosted on Github

对于遇到此问题的每个人,我在Github 上托管的示例中创建了以下示例

回答by BaseZen

Translated with some edits from:

翻译与一些编辑:

First frame of a video using AVFoundation

使用 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

回答by CodeBender

This is a cleaned up version of David's answer and tested against iOS 11 / Swift 4.x.

这是 David 答案的清理版本,并针对 iOS 11 / Swift 4.x 进行了测试。

Please note the different calls for handling the initial time based on which version of Swift you are using.

请注意根据您使用的 Swift 版本处理初始时间的不同调用。

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
    }
}
  1. Creates an AVURLAssetfrom the provided URL
  2. Creates an AVAssetImageGeneratorusing the newly created AVURLAsset, is responsible for making the thumbnail
  3. appliesPreferredTrackTransforminforms the generator to apply the matrix to the thumbnail generation. The default value is false.
  4. Attempts to create a CGImageat the first frame of the video track
  5. Creates a UIImageusing the newly created CGImage & returns it
  6. If the image generation step fails, an error is caught and presented to the console along with a nil UIImage
  1. AVURLAsset从提供的创建一个URL
  2. 创建一个AVAssetImageGenerator使用新创建的AVURLAsset,负责制作缩略图
  3. applyPreferredTrackTransform通知生成器将矩阵应用于缩略图生成。默认值为假。
  4. 尝试CGImage在视频轨道的第一帧创建
  5. UIImage使用新创建的 CGImage创建一个并返回它
  6. 如果图像生成步骤失败,则会捕获错误并将其与 nil UIImage 一起呈现给控制台

回答by Carl Smith

BaseZen's answer translated to Swift 2:

BaseZen 的回答转化为 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)")
}

回答by Bilal Arslan

It's better to write less and simple code for understanding. This is what I convert the solutions in Swift (3.1 ... 4.2)

最好编写较少且简单的代码以供理解。这就是我在 Swift (3.1 ... 4.2) 中转换解决方案的内容

import AVFoundation

func videoPreviewUIImage(moviePath: URL) -> UIImage? {
    let asset = AVURLAsset(url: moviePath)
    let generator = AVAssetImageGenerator(asset: asset)
    generator.appliesPreferredTrackTransform = true
    let timestamp = CMTime(seconds: 2, preferredTimescale: 60)
    if let imageRef = try? generator.copyCGImage(at: timestamp, actualTime: nil) {
        return UIImage(cgImage: imageRef)
    } else {
        return nil
    }
}

Hope it will help someone.

希望它会帮助某人。

回答by user11378394

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)}