wxxsw / GSPlayer

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层
MIT License
433 stars 101 forks source link

Video playing issue when scrolling #94

Closed laxman-iroid closed 8 months ago

laxman-iroid commented 8 months ago

https://github.com/wxxsw/GSPlayer/assets/74966448/79fd9bbf-70e5-4618-b2df-9decc3d5dba4

I am encountering an issue with the UICollectionView where the screen sometimes turns black, or the video occasionally gets stuck. Could you please assist me in resolving this?

Here is my code `class FeedViewController: UIViewController {

@IBOutlet weak var collectionView: UICollectionView!

var items: [URL] = [
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/r43trITADsWpFztxESeYW9ZPSP7LWMzSjKForScq.mov")!,
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/ZZO6FO9QjXOUJtITGASJxxUbg3lTPilfVze9Xc15.mov")!,
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/xENCwn0Xk0SoM2exE0QG8q16HSVGqXRHZO3CzmFy.mov")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/16/mp4/190616155507259516.mp4")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/15/mp4/190615103827358781.mp4")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/05/mp4/190605101703931259.mp4")!,
]

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.dataSource = self
    collectionView.delegate = self

    collectionView.register(UINib(nibName: "FeedCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "FeedCollectionViewCell")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    check()
}

deinit {
    print("Call deinit")
}

}

extension FeedViewController: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    items.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeedCollectionViewCell", for: indexPath) as! FeedCollectionViewCell
    cell.set(url: items[indexPath.row])
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if let cell = cell as? FeedCollectionViewCell {
        cell.pause()
    }
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate { check() }
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    check()
}

func check() {
    checkPreload()
    checkPlay()
}

func checkPreload() {

    guard let lastRow = collectionView.indexPathsForVisibleItems.last?.item else { return }

    let urls = items
        .suffix(from: min(lastRow + 1, items.count))
        .prefix(2)

    VideoPreloadManager.shared.set(waiting: Array(urls))
}

func checkPlay() {
    let visibleCells = collectionView.visibleCells.compactMap { $0 as? FeedCollectionViewCell }

    guard visibleCells.count > 0 else { return }

    let visibleFrame = CGRect(x: collectionView.contentOffset.x, y: 0, width: collectionView.bounds.width, height: collectionView.bounds.height)
    print(visibleFrame.origin.x)
    let visibleCell = visibleCells
        .filter { visibleFrame.intersection($0.frame).height >= $0.frame.height / 2 }
        .first
  //  print(visibleCell)
    visibleCell?.play()
}

} `

laxman-iroid commented 8 months ago

simulator-screen-recording-iphone-15-2024-03-17-at-170825_ejjeu6Ny.mp4 I am encountering an issue with the UICollectionView where the screen sometimes turns black, or the video occasionally gets stuck. Could you please assist me in resolving this?

Here is my code `class FeedViewController: UIViewController {

@IBOutlet weak var collectionView: UICollectionView!

var items: [URL] = [
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/r43trITADsWpFztxESeYW9ZPSP7LWMzSjKForScq.mov")!,
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/ZZO6FO9QjXOUJtITGASJxxUbg3lTPilfVze9Xc15.mov")!,
    URL(string: "https://bk1.goomooz.net/dev/public/storage/post/itamimage/xENCwn0Xk0SoM2exE0QG8q16HSVGqXRHZO3CzmFy.mov")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/16/mp4/190616155507259516.mp4")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/15/mp4/190615103827358781.mp4")!,
    URL(string: "http://vfx.mtime.cn/Video/2019/06/05/mp4/190605101703931259.mp4")!,
]

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.dataSource = self
    collectionView.delegate = self

    collectionView.register(UINib(nibName: "FeedCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "FeedCollectionViewCell")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    check()
}

deinit {
    print("Call deinit")
}

}

extension FeedViewController: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    items.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeedCollectionViewCell", for: indexPath) as! FeedCollectionViewCell
    cell.set(url: items[indexPath.row])
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if let cell = cell as? FeedCollectionViewCell {
        cell.pause()
    }
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate { check() }
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    check()
}

func check() {
    checkPreload()
    checkPlay()
}

func checkPreload() {

    guard let lastRow = collectionView.indexPathsForVisibleItems.last?.item else { return }

    let urls = items
        .suffix(from: min(lastRow + 1, items.count))
        .prefix(2)

    VideoPreloadManager.shared.set(waiting: Array(urls))
}

func checkPlay() {
    let visibleCells = collectionView.visibleCells.compactMap { $0 as? FeedCollectionViewCell }

    guard visibleCells.count > 0 else { return }

    let visibleFrame = CGRect(x: collectionView.contentOffset.x, y: 0, width: collectionView.bounds.width, height: collectionView.bounds.height)
    print(visibleFrame.origin.x)
    let visibleCell = visibleCells
        .filter { visibleFrame.intersection($0.frame).height >= $0.frame.height / 2 }
        .first
  //  print(visibleCell)
    visibleCell?.play()
}

} `