在swift中从本地视频创建缩略图

Ral*_*lph 38 iphone video-capture ios swift

如何从本地视频文件中快速创建缩略图?

例如,如果视频文件路径位于此处:

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

谢谢.

Dav*_*eek 62

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

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

别忘了 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Bas*_*Zen 57

翻译过来的一些编辑:

使用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
Run Code Online (Sandbox Code Playgroud)

  • @AnandGautam我会猜测并说你提供不同的CMTime? (3认同)

Cod*_*der 20

这是David的答案的清理版本,并针对iOS 11/Swift 4.0进行了测试:

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
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. AVURLAsset从提供的创建URL
  2. 创建一个AVAssetImageGenerator使用新创建的AVURLAsset,负责制作缩略图
  3. applyPreferredTrackTransform通知生成器将矩阵应用于缩略图生成.默认值为false.
  4. 尝试CGImage在视频轨道的第一帧创建一个
  5. 创建一个UIImage使用新创建CGImage和返回它
  6. 如果图像生成步骤失败,则会捕获错误并将其与nil UIImage一起呈现给控制台


Car*_*ith 12

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)")
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现我的一些缩略图与原始视频的方向不同。将 imgGenerator.appliesPreferredTrackTransform 设置为 true 可以解决这个问题。 (2认同)

cor*_*ora 6

斯威夫特 5.3

作为其他答案的替代方案,经过轻微修改,我决定制作一个 URL 扩展。

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let image = someURL.generateThumbnail()
Run Code Online (Sandbox Code Playgroud)


Bil*_*lan 5

最好编写较少和简单的代码以供理解。这就是我在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
    }
}
Run Code Online (Sandbox Code Playgroud)

希望它会帮助某人。