使用iCloud PHAsset请求AVAsset会返回没有VideoTracks的AVAsset

问题描述

最近,开始注意到从照片库导入某些资产时未显示它们。有问题的资产存储在iCloud中,并且不会缓存在设备上。 我认为这是一个iOS 14问题,因为我从未在iOS 13上遇到过此问题。(由于无法将个人设备推广到iOS 13,因此我不确定100%。

这是我在 iOS 14 中所做的事情:

  1. 使用新的选择器视图控制器导入视频资产
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.filter = PHPickerFilter.videos
let videoPickerController = PHPickerViewController(configuration: configuration)
videoPickerController.delegate = self
present(videoPickerController,animated: true,completion: nil)
  1. 我从[PHPickerResult](委托方法)中提取了PHAsset
func picker(_ picker: PHPickerViewController,didFinishPicking results: [PHPickerResult]) {
  picker.dismiss(animated: true,completion: nil)
  guard results.count > 0 else {
    return
  }
  guard let firstPHAssetIdentifier = results.first?.assetIdentifier else {
    fatalError("No asset identifier")
  }
  let fetchOptions = PHFetchOptions()
  guard let phAsset = PHAsset.fetchAssets(withLocalIdentifiers: [firstPHAssetIdentifier],options: fetchOptions).firstObject else {
    fatalError("No matching PHAsset")
  }
  guard phAsset.mediaType == .video else {
    fatalError("Asset not of the video type")
  }
}
  1. 然后,我为匹配的PHAsset请求一个AVAsset
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
options.progressHandler = { progress,_,_ in
  print("Progress: \(progress)")
}

PHCachingImageManager.default().requestAVAsset(forVideo: phAsset,options: options) { [weak self] avAsset,info in
  guard info?[PHImageCancelledKey] == nil && info?[PHImageErrorKey] == nil else {
    print("Error or cancelled. Info: \(String(describing: info))")
    return
  }
  guard let avAsset = avAsset else {
    print("Asset is nil. Info: \(String(describing: info))")
    return
  }
  guard let videoTrack = avAsset.tracks(withMediaType: .video).first else {
    print("Cound not extract video track from AvAsset") // <- My issue
    return
  }
}

问题:通常,当资产来自iCloud时,我没有videoTrack。 avAsset.duration也将为 0.0

我将看到下载进度,但是我将保留在最后一个保护声明中。 有时,一旦资产下载完毕并无法加载videoTrack,重试就会立即失败(它不会尝试再次加载资产,似乎已损坏)。它会落在最后一个保护声明中。

我注意到在PHVideoRequestOptions上使用deliveryMode = .highQualityFormat可以正常工作,但我宁愿只下载720p视频,而不下载高质量视频。

我想我在这里做错了。我应该这样从PHPickerResult获取phAsset吗?任何指针/帮助将不胜感激。 我创建了此仓库以复制https://github.com/SwiftRabbit/RequestAVAssetIssues/tree/main/RequestAVAssetIssues。不能100%复制,而必须是不再在设备上的iCloud视频。

其他注释/尝试:

  • 我在使用PHCachingImageManager和PHImageManager时遇到了同样的问题
  • 某些流行的应用似乎对某些资产(例如Instagram,TikTok ...)存在相同的问题
  • PHCachingImageManager.default()。requestPlayerItem也不起作用。它返回一个不包含任何轨道的AVPlayerItem。
  • iPhone XS,企业托管设备

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)