从照片中提取后,视频及其缩略图未按顺序保存

Posted

技术标签:

【中文标题】从照片中提取后,视频及其缩略图未按顺序保存【英文标题】:Videos and its thumbnails not saved in sequence after fetching From Photos 【发布时间】:2017-08-22 08:24:44 【问题描述】:

我正在使用以下代码获取视频(URL、持续时间、缩略图)。获取数据后,我将其显示在CollectionView 上。 主要问题是,一些视频和它的缩略图不匹配。谁能告诉我如何解决它,或任何其他更好的解决方案? 谢谢

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell

        cell.imgV.image = photoLibrary[indexPath.row]

        let duration: TimeInterval = videosDuration[indexPath.row] // 2 minutes, 30 seconds
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .positional
        formatter.allowedUnits = [ .minute, .second ]
        formatter.zeroFormattingBehavior = [ .pad ]
        let formattedDuration = formatter.string(from: duration)
        cell.duration.text = "\(String(describing: formattedDuration!))"

        return cell
    

    func grabPhotos()
        let imgManager = PHImageManager.default()

        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        requestOptions.deliveryMode = .highQualityFormat

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) 
            if fetchResult.count > 0 
                for i in 0..<fetchResult.count
                    //Used for fetch Image//
                    imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFill, options: requestOptions, resultHandler: 
                        image, error in
                        let imageOfVideo = image! as UIImage
                        self.photoLibrary.append(imageOfVideo)
                    )
                    //Used for fetch Video//
                    imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: (avAsset, audioMix, info) -> Void in
                        if let asset = avAsset as? AVURLAsset 
                            self.videoURL.append(asset.url)
                            let duration : CMTime = asset.duration
                            let durationInSecond = CMTimeGetSeconds(duration)
                            self.videosDuration.append(durationInSecond)
                        
                    )
                
            
            else
                //showAllertToImportImage()//A function to show alert
            
        

    

【问题讨论】:

请出示collectionView的代码 我认为是因为 imgManager.requestImage 和 imgManager.requestAVAsset 是异步执行的 所以你可以使用 [[PHImageManager defaultManager] requestAVAssetForVideo 我们需要更多信息。您何时在 viewdidload 中获取视频和图像?此外,永远不要获取您可能不需要的任何东西。如果您有 20 个视频但显示 5 个,那是不对的。获取每行的视频和图像。 请检查答案,看看是否有帮助,如果您遇到问题,请在 cmets 中提问 【参考方案1】:

由于照片是异步获取的,因此图像和视频数组中的顺序不会保持不变,因此要获取视频的对应图像,您可以使用字典来存储结果

我对你的代码做了一些修改,请检查

var imageDictionary = [String: AnyObject]()
var videoDictionary = [String: AnyObject]()

func fetchData()
        let imgManager = PHImageManager.default()

        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        requestOptions.deliveryMode = .highQualityFormat

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) 
            if fetchResult.count > 0 
                for i in 0..<fetchResult.count
                    //Used for fetch Image//

                    imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFill, options: requestOptions, resultHandler: 
                        image, error in
                        let imageOfVideo = image! as UIImage
                        //self.photoLibrary.append(imageOfVideo)
                        let key = "\(i)"
                        self.imageDictionary[key] = imageOfVideo
                    )
                    //Used for fetch Video//
                    imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: (avAsset, audioMix, info) -> Void in
                        if let asset = avAsset as? AVURLAsset 
                            //let videoData = NSData(contentsOf: asset.url)
                            self.videoURL.append(asset.url)
                            //print(asset.url)
                            let duration : CMTime = asset.duration
                            let durationInSecond = CMTimeGetSeconds(duration)
                            //self.videosDuration.append(durationInSecond)
                            //print(durationInSecond)
                            let key = "\(i)"
                            self.videoDictionary[key] = ["VideoURL" : asset.url, "VideoDuration" : durationInSecond]
                        
                    )
                
            
            else
                //showAllertToImportImage()//A function to show alert
            
        

    


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return self.imageDictionary.count
    

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

               //You can access the values like this....

               let key = "\(indexPath.row)"

               cell.image = self.imageDictionary[key] as? UIImage
               let singleVideo = self.videoDictionary[key] as? [String: AnyObject]

               cell.videoURL = singleVideo["VideoURL"] as? URL
               cell.videoDuration = singleVideo["VideoDuration"] as? CMTime


    

【讨论】:

仍然遇到同样的问题? 抱歉,didSelectItemAt 是我的错误,您的代码运行良好。谢谢 @ZAFAR007 不用担心,很高兴我能帮上忙

以上是关于从照片中提取后,视频及其缩略图未按顺序保存的主要内容,如果未能解决你的问题,请参考以下文章

如何从 PHAsset 获取视频的缩略图?

PDFKit PDFThumbnailView 缩略图未居中

iOS:如何从磁盘上的照片文件中提取缩略图和元数据

引导缩略图未正确对齐

改进了从视频中提取缩略图

响应式文件管理器缩略图未显示