【问题标题】:Creating thumbnail from local video in swift快速从本地视频创建缩略图
【发布时间】:2015-10-25 01:54:33
【问题描述】:

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

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

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

谢谢。

【问题讨论】:

    标签: ios swift iphone video-capture


    【解决方案1】:

    这是在 swift 5 中生成视频缩略图(第一帧)的方法:

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var imageView: UIImageView!
        override func viewDidLoad() {
            super.viewDidLoad()
        
            let video = AVURLAsset(url: URL(fileURLWithPath: Bundle.main.path(forResource: "sampleVideo", ofType: "mov")!))
            let thumbnailGenerator = AVAssetImageGenerator(asset: video)
        
            do
            {
                let cgImage = try thumbnailGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
                let UiImage = UIImage(cgImage: cgImage)
                imageView.image = UiImage
            }
            catch
            { print(error) }
        
        }
    
    }
    

    在此示例中,视频名称为 sampleVideo.mov(将文件 url 更改为视频文件的名称),确保将视频导入本地 Xcode 项目并将其添加到应用程序的目标中。

    我制作了一个 youtube 来解释这个 here

    【讨论】:

      【解决方案2】:

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

      用法:

      let image = someURL.generateThumbnail()
      

      【讨论】:

        【解决方案3】:

        最好少写一些简单的代码便于理解。 这就是我在 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)
        }
        

        希望对某人有所帮助。

        【讨论】:

          【解决方案4】:
          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)}
          

          【讨论】:

            【解决方案5】:

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

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

            【讨论】:

              【解决方案6】:

              翻译自:

              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
              

              【讨论】:

              • 如何使用任何视频 URL 从持续时间(10 秒到 15 秒)中获取缩略图?
              • @AnandGautam 我大胆猜测一下,你提供了不同的 CMTime?
              • 如何获取系统cameraRoll视频缩略图?
              【解决方案7】:

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

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

              别忘了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
                  }
              }
              

              对于所有对此有疑问的人,我创建了以下托管在 Github 上的示例

              【讨论】:

              • 嘿,感谢代码,不知道为什么,但它需要 10-15 秒才能显示预览。有人可以帮忙吗?
              • @vivektakrani 打开一个新线程并提供您的代码和逻辑
              • @DavidSeek 创建了一个新线程,介意看看吗? stackoverflow.com/questions/41407123/…
              • 既然你已经得到了答案,我刚刚为你投了赞成票,所以你又要收支平衡了
              • 非常好。很抱歉这个菜鸟问题,但支持哪种视频格式?
              【解决方案8】:

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

              【讨论】:

              • 当然,var err 现在已经无关紧要了。
              • 谢谢。我删除了它。
              • 我发现我的一些缩略图与原始视频的方向不同。将 imgGenerator.appliesPreferredTrackTransform 设置为 true 可以解决此问题。
              • 如何使用任何视频 URL 从持续时间(10 秒到 15 秒)中获取缩略图?
              猜你喜欢
              • 2018-05-15
              • 1970-01-01
              • 2017-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多