我目前拥有的UI Collection可以从您的相机胶卷中检索数据,以便将所有视频加载到该集合中。现在我要做的是当你在集合中选择一个视频时,在我的自定义UIView中播放它是一个AVPlayer;一切都很好,除了当我播放视频时,它并不总是在数组中播放正确的视频我已经添加了视频网址。它通常只是从图书馆播放一个随机视频,有时会崩溃应用程序指向我附加视频网址的地方,并说#34;致命超出范围"。我似乎无法弄清楚为什么会这样。它正确地打印出数组的值以及计数;所以我认为这与我如何检索视频有关。
以下是我提取视频的地方:
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
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: 200, height: 200), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
self.imageArray.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 {
let videoData = NSURL(string: "\(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
self.videoArray.append(videoData!)
print(self.videoArray)
}
})
}
}
else{
//showAllertToImportImage()//A function to show alert
}
}
}
每个细胞的加载 - &gt;我不认为这件事
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! VideoSelectionCVCell
cell.uploadedFile.image = imageArray[indexPath.row]
return cell
}
didSelect: - &gt;&gt;我认为这就是问题所在
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
displayView.frame = CGRect(x: self.view.frame.size.width / 2, y: self.view.frame.size.height / 2, width:self.view.frame.size.width / 1.15, height: self.view.frame.size.height / 1.3)
displayView.center = view.center
displayView.backgroundColor = UIColor.clear
displayView.layer.cornerRadius = displayView.layer.frame.size.width / 10
displayView.layer.borderColor = UIColor.black.cgColor
displayView.layer.borderWidth = 4
//displayView.avPlayerLayer.cornerRadius = displayView.avPlayerLayer.frame.size.width/10
displayView.url = videoArray[indexPath.row]
}
计数
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
自定义播放器:
class VideoPlayBack: UIView {
var url: NSURL!
var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!
var cancelButton: UIButton!
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
self.backgroundColor = UIColor.black
avPlayer = AVPlayer(url: url! as URL)
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEnd.none
avPlayerLayer = AVPlayerLayer(player: avPlayer)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(_:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem)
avPlayerLayer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
//avPlayerLayer.frame = self.layer.bounds
self.layer.addSublayer(avPlayerLayer)
avPlayer.play()
}
func playerItemDidReachEnd(_ notification: Notification) {
let playerItem = notification.object as! AVPlayerItem
playerItem.seek(to: kCMTimeZero)
}
}
以下是完整的集合视图类。
同样,我认为这与我追加和检索视频的方式有关。
答案 0 :(得分:0)
我认为创建一个小类或结构(即Media)来保存图像和视频,并创建一个用于集合视图的Media数组,而不是拥有2个数组。这是因为2个获取方法是异步的,所以你永远不知道将分配哪个视频/图像组合的索引。此外,尝试嵌套异步调用,以便两个调用使用相同的媒体实例来保持数据一致性。
这是一个未经测试的例子:
struct Media {
var image:UIImage?
var videoURL:URL?
}
var mediaArray = [Media]()
for i in 0..<fetchResult.count{
let mediaItem = Media()
//Used for fetch Image//
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
mediaItem.image = 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 = URL(string: "\(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
mediaItem.videoURL = videoData!
self.mediaArray.append(mediaItem)
}
})
})
}
然后使用媒体数组填充collectionView。不要忘记始终打开数据。不要使用力展开,你(几乎)永远不会崩溃