【问题标题】:Getting same Video Thumbnail Image every time from the Url in Swift iOS每次从 Swift iOS 中的 Url 获取相同的视频缩略图图像
【发布时间】:2023-03-22 09:35:01
【问题描述】:

我正在 Swift3 中开发基于视频的应用程序。根据视频时长,我有一个视频网址和一个范围滑块,用户可以从滑块中选择任何最小值和最大值。如果假设用户选择了最小值 3 秒和最大值 7 秒,那么在此期间我需要生成一个视频缩略图图像。为此,我使用AVAssetImageGenerator 来生成它,我尝试了以下两个代码来实现这一点:

func createThumbnailOfVideoFromFileURL(_ strVideoURL: URL) -> UIImage?{

        let asset = AVAsset(url: strVideoURL)
        let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
        assetImgGenerate.appliesPreferredTrackTransform = true
        let time = CMTimeMake(1, 30)
        let img = try? assetImgGenerate.copyCGImage(at: time, actualTime: nil)

        guard let cgImage = img else { return nil }

        let frameImg    = UIImage(cgImage: cgImage)
        return frameImg
    }

func generateThumbnailForUrl(vidUrl:URL) -> UIImage {

        let asset = AVURLAsset(url: vidUrl, options: nil)
        let imgGenerator = AVAssetImageGenerator(asset: asset)
        var thmbnlImg = UIImage()
        do{
            let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil)
            thmbnlImg = UIImage(cgImage: cgImage)
            thmbnlImg = thmbnlImg.imageRotatedByDegrees(degrees: 90.0, flip: false)
        }
        catch{
            print(error)
        }
        // !! check the error before proceeding
        return thmbnlImg
    }

但问题是我使用上述两种方法都得到了相同的缩略图,因为我没有在这两种方法中设置持续时间。如何添加最小和最大持续时间来为每个不同的持续时间生成不同的缩略图。请帮我解决我的问题。谢谢!

编辑:我尝试将持续时间设置为:

let time: CMTime = CMTimeMakeWithSeconds(rangeSlider!.lowerValue, 1)

然后我得到不同的缩略图图像,但对于某些滑块范围,我也得到零缩略图图像。谁能知道如何在CMTimeMakeWithSeconds 中设置preferredTimeScale 值?

【问题讨论】:

    标签: ios swift video avasset video-thumbnails


    【解决方案1】:

    试试这个代码

    static func generateThumbnail(videoUrl: String) -> UIImage? {
    
        do {
            let url                                         = URL(string: videoUrl)
            let asset                                       = AVURLAsset(url: url!)
            let imageGenerator                              = AVAssetImageGenerator(asset: asset)
            imageGenerator.appliesPreferredTrackTransform   = true
            let cgImage                                     = try imageGenerator.copyCGImage(at: CMTime(seconds: 2.0, preferredTimescale: 60),
                                                                                             actualTime: nil)
    
            return UIImage(cgImage: cgImage)
    
        } catch {
    
            print(error.localizedDescription)
            return nil
        }
    }
    

    【讨论】:

      【解决方案2】:

      假设,您修剪后的视频 URL 是 videoURL。成功修剪视频后,添加此代码 sn -p。实际上,这段代码 sn-p 将帮助您每秒从修剪过的视频中提取图像(意思是,如果修剪过的视频的持续时间为 10 秒,则此代码将每秒提取 10 张图像,所有这些图像都保存在一个数组,命名为videoFrames)。最后,您可以对这些图像做任何您想做的事情。您还可以在此过程进行时添加活动指示器。希望这会有所帮助。

      var videoFrames = [UIImage]()
      let asset : AVAsset = AVAsset(url: videoURL as URL)
      let videoDuration = CMTimeGetSeconds(asset.duration)
      let integerValueOFVideoDuration = Int(videoDuration)
      
      //start activity indicator here
      
      for index in 0..<integerValueOFVideoDuration + 1 {
         self.generateFrames(url: videoURL, fromTime: Float64(index))
      }
      
      func generateFrames(url: NSURL, fromTime: Float64) {
              if videoFrames.count == integerValueOFVideoDuration {
                  //end activity indicator here
                  return
              }
              let asset: AVAsset = AVAsset(url: url as URL)
              let assetImgGenerate: AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
              assetImgGenerate.maximumSize = CGSize(width: 300, height: 300)
              assetImgGenerate.appliesPreferredTrackTransform = true
              let time: CMTime = CMTimeMakeWithSeconds(fromTime, 600)
              var img: CGImage?
              do {
                  img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
              } catch {
              }
              if img != nil {
                  let frameImg: UIImage = UIImage(cgImage: img!)
                  videoFrames.append(frameImg)
              } else {
                  //return nil
              }
          }
      

      【讨论】:

      • 感谢您的回复,这里我没有修剪视频网址。我只有一个主视频网址和一个范围滑块,用户可以从滑块中选择最小值和最大值。使用该范围值,我需要生成一个缩略图图像。有什么建议……你明白吗?
      • 好的...您需要将您的最小值和最大值从滑块转换为 CMTimeMakeWithSeconds 并将这些值传递给上述函数。 fromTime: Float64 是这里的参数。
      • 你能用代码告诉我吗,我改变了 CMTimeMake 的值,但每次都相同的缩略图。
      • 让 lowerVal = Float64(rangeSlider.lowerValue) & 将此值传递给上述函数。您将获得较低值的缩略图。同样的方法也适用于 rangeSlider.upperValue。我猜您在这里使用的是自定义滑块,所以如果没有看到完整的自定义滑块属性,很难在这里回答您的问题。
      • 我有 rangeSlider.lowerValue 和 rangeSlider.upperValue,如何在 CMTimeMakeWithSeconds 中添加这两个值?我对此一无所知。
      猜你喜欢
      • 2011-05-25
      • 2017-06-27
      • 2010-11-23
      • 2019-05-06
      • 1970-01-01
      • 2013-11-01
      • 2020-05-16
      • 2011-06-18
      • 2011-06-14
      相关资源
      最近更新 更多