iOS視訊列表滾動自動播放的一些坑
阿新 • • 發佈:2020-09-06
最近業務增加視訊列表滾動自動播放的功能,踩了一些坑,在此記錄一下。
應該注意的一些問題
- 視訊
cell
佈局上最好是和其他需要業務操作頻繁更新資料的控制元件分離開(做成不同的cell),比如點贊關注,需要重新整理的時候容易誤傷而導致暫停播放之類的UI錯亂或者為了解決這個問題需要增加一些不必要的判斷邏輯. - 採取的方案是控制器持有播放器,不同的視訊
cell
切換不同的播放器容器,播放器物件唯一,好處是省記憶體,壞處是不能預載入. - 頁面切換或者前後臺切換需要把視訊暫停,重新進入頁面時繼續播放,時機把握應該是
viewDidAppear
和viewWillDisappear
-
自動播放
選擇視訊cell距離tableview的中心線最近的一個cell進行播放
比較cell的中心點y值與中心線的y值的差值的絕對值大小,最小的即為優先播放的視訊cell
... //遍歷尋找距離中心點最近的cell 用於播放 CGPoint coorCentre = [currentCell.superview convertPoint:currentCell.center toView:nil]; CGFloat delta = fabs(coorCentre.y - self.tableView.bounds.size.height*0.5); if (delta < gap) { gap = delta; finnalCell = currentCell; } ...
-
切換播放
控制器持有當前播放的視訊cell,當尋找到最合適播放的cell時,進行比對,如果是同一個則不進行操作,否則切換播放並賦值新的視訊cell,播放器新增到新的視訊cell容器上
if (finnalCell != nil && self.playingCell != finnalCell) { [self stopPlay]; [self playWithUrl:finnalCell.videoURLString showView:finnalCell.playerContainerView]; self.playingCell = finnalCell; return; }
-
停止播放
需求是劃出螢幕50%以上的cell需要停止播放, 業界開源的方案大部分都是純視訊cell的案例,而且cell高度也是固定的,接到這麼一個需求,一開始還是挺為難的,後來經過大佬們討論之後,通過一番思索畫圖得出這個也並不是很難,只不過是座標邊界判斷,cell在tableview上的frame是可以知道的,然後用cell.y與contentOffset.y 以及 contentOffset.y + tableview.height比對即可
/// 判斷視訊滑動到邊界的問題 - (void)judgeScrollBoundaryWithVideoCell:(VideoTableViewCell *)currentCell{ if (self.playingCell != currentCell) { return; } ///!!! 邊界判斷 劃出去半個cell以上就停止播放 CGFloat currentCellHalfHeight = currentCell.height/2.0;//cell一半的高度 CGFloat offsetY = self.tableView.contentOffset.y;//頂部邊界 CGFloat bottomValue = offsetY + self.tableView.height; //底部邊界 //條件1 cell在螢幕上邊界移出去超過一半以上 if (currentCell.maxY > offsetY && currentCell.minY < offsetY) { BOOL condition1 = offsetY - currentCell.minY > currentCellHalfHeight; if (condition1) { [self.playerView pause]; [self.playingCell stopPlayVideoUI]; } } //條件2 cell在下邊界移出去超過一半以上 if (currentCell.maxY > bottomValue && currentCell.minY < bottomValue) { BOOL condition2 = bottomValue - currentCell.minY < currentCellHalfHeight; if (condition2) { [self.playerView pause]; [self.playingCell stopPlayVideoUI]; } } //可視區域恢復播放 if ((offsetY - currentCell.minY < currentCellHalfHeight) && /** 上邊界 */ (currentCell.maxY < bottomValue + currentCellHalfHeight) && /** 下邊界 */ self.playerView.state == StatePause /** 暫停的才恢復播放 其他狀態暫不處理*/) { [self.playerView resume]; [self.playerView seekToTime:0]; [self.playingCell startPlayVideoUI]; } }
參考了以下文章,特此鳴謝