2017-04-07 5 views
1

현재 카메라 롤에서 데이터를 검색하여 모든 비디오를 컬렉션에로드하는 UI Collection이 있습니다. 이제 내가하려고하는 것은 컬렉션에서 비디오를 선택하여 AVPlayer 인 사용자 정의 UIView에서 재생할 때입니다. 모든 것이 훌륭합니다. 비디오를 재생할 때 항상 올바른 비디오를 배열로 재생하지는 않습니다. 비디오 URL을 추가했습니다. 일반적으로 라이브러리에서 임의의 동영상을 재생하며 때로는 동영상 URL을 추가하고 "치명적인 범위를 벗어났습니다"라고 말하는 지점을 가리키는 앱을 충돌시킵니다. 왜 이런 일이 일어나는지 알 수는없는 것 같습니다. 그것은 정확히 배열의 값과 카운트를 출력합니다. 그래서 나는 그것이 내가 비디오를 어떻게 가져 오는 지와 관련이 있다고 생각한다. >> 내가 생각 - :AVPlayer가 올바르게 작동하지 않습니다.

 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은 비록> 나는이 문제를 생각하지 않는다 -

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

각 셀의 로딩 : 여기

내가 비디오를 가져 오는하고있는 곳입니다 문제가

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

이 단지의 경우 전체 콜렉션 뷰 클래스입니다.

https://paste.ee/p/JgZSu

는 다시, 나는 내가 추가하고 비디오를 검색하고 어떻게 함께 할 수있다 생각합니다.

답변

0

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을 채우는 미디어 배열을 사용 : 여기

가 아닌 테스트 예이다. 항상 데이터를 언랩하는 것을 잊지 마십시오. 언 래핑을 사용하지 마십시오. 충돌이 거의 발생하지 않습니다.

+0

정말 고마워요! 그것은 작동합니다! – AndrewS

관련 문제