I'm using Swift to develop a mobile app. I'm playing videos in 2 Gemini collection views. Please see video of the flow:
However, I noticed that after a few 'users' are added, videos from both collection view cells start to disappear. See bellow:
See relevant code for BIG collection view:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UserCollectionCell", for: indexPath) as! UserCollectionCell
cell.setupUserNameAndVideo(userName: users[indexPath.row].name, userVideo: users[indexPath.row].picture)
self.collectionView.animateCell(cell)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? UserCollectionCell {
self.collectionView.animateCell(cell)
cell.playVideo()
}
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? UserCollectionCell {
cell.pauseVideo()
}
}
See relevant code for SMALL collection view:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AvatarsCollectionCell", for: indexPath) as! AvatarsCollectionCell
cell.setupUserNameAndVideo(video: avatars[indexPath.row].picture)
self.avatarsCollectionView.animateCell(cell)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? AvatarsCollectionCell {
cell.playVideo()
self.avatarsCollectionView.animateCell(cell)
}
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? AvatarsCollectionCell {
cell.pauseVideo()
}
}
Video player function in cell:
func setupUserNameAndVideo(userName: String, userVideo: String) {
let path = Bundle.main.path(forResource: String(userVideo), ofType: "MOV")
let pathURL = URL(fileURLWithPath: path!)
let duration = Int64( ( (Float64(CMTimeGetSeconds(AVAsset(url: pathURL).duration)) * 10.0) - 1) / 10.0 )
playerItem = AVPlayerItem(url: pathURL)
player = AVQueuePlayer()
player.volume = 0
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
videoView.layoutIfNeeded()
playerLayer?.frame = videoView.layer.bounds
videoView.layer.insertSublayer(playerLayer, at: 1)
playerLooper = AVPlayerLooper(player: player, templateItem: playerItem,
timeRange: CMTimeRange(start: CMTime.zero, end: CMTimeMake(value: duration, timescale: Int32(0.00))) )
}
Also, play / pause functions in cell:
func playVideo() {
player.play()
}
func pauseVideo() {
player.pause()
}
Add user delegate function:
extension SelectUsersViewController: AddUserDelegate {
func userAdded(name: String, picture: String) {
users.append(User(name: name, picture: picture))
DispatchQueue.main.async {
self.collectionView.insertItems(at: [IndexPath(row: self.users.count-1, section: 0)])
self.collectionView.scrollToItem(at:IndexPath(item: self.users.count-1, section: 0), at: .centeredHorizontally, animated: true)
}
}
}
I understand that looping multiple videos at once can be resource extensive. At first I though this might be memory issue, but it never reaches more than 100MB (which is ok in my opinion). Any other ideas?

