UITableView 視頻自動播放功能總結

概述

最近應項目需求,實如今 tableView中添加視頻自動播放功能,產品功能相似與微博的視頻信息流播放樣式,爲此實現了好一段時間,如今把當初實現的方法以及內容記錄於此,以便後續回顧以及查看。git

思路

視頻屏幕居中播放github

由於以前沒有作過這樣的功能,因此也是作了很多調研工做,由於微博的視頻很具備表明性,因此以此爲研究對象,構思了一下相關的播放邏輯內容。算法

微博視頻自動播放

注意到微博視頻播放是居中位置播放,也就是說距離中心位置最近的視頻播放 cell 進行自動播放,而其餘 cell 中的視頻處於中止狀態,顯然這是一個屏幕居中選定視頻的一個算法,而這個算法也這是控制視頻播放的核心內容。爲此實現它也有了相應的思路,而這塊內容大體能夠分爲三個步驟:數組

  1. 找出當前屏幕中已經正在顯示的 cell,用數組存起來
  2. 在數組中找出距離屏幕中央最近的 cell
  3. 存儲第二個步驟中找出的 cell(牽扯到後續播放以及中止)

使用單例進行視頻的有序播放bash

仔細看了一下微博的視頻播放,會發現信息流中的視頻始終都是一個視頻在播放,不管怎麼滑動,都是一個視頻在當前播放,我想這麼作無疑也是兩點,一是保證視頻播放的惟一性,二則是減小內存的佔用。若是每一個 cell 中都添加一個視頻播放器的話,也會佔用很多內存吧。還有一點就是,若是設計成單例進行視頻播放的話,整個信息流中視頻播放體系就會變得很好控制,邏輯也會變得愈發清晰。因此這種狀況下的視頻播放設計成單例播放無疑是最好的選擇。網絡

控制滾動判斷視頻播放的時機ide

由於要不斷的找出在屏幕中顯示的 cell,以及要比較出當前離屏幕中最近的視頻cell,因此這個過程若是放在 tableView 中的 didScrollview 方法中判斷的話,會在滑動的時候瘋狂比較查找,這樣作顯然是很差的。因此滾動過程當中咱們儘可能不去判斷這些邏輯,在滾動中止的時候再去觸發判斷的邏輯,這樣既可以知足自動播放的功能,也省去了來回比較的邏輯過程。因此咱們能夠在 tableview 的scrollViewDidEndDraggingscrollViewDidEndDecelerating回調中進行判斷。ui

實現

有了思路,接下來就是實現了,其實實現方式多種多樣,重在思想。spa

視頻屏幕居中播放設計

該功能的實現實際上主要在於找到當前屏幕中距離屏幕中線距離最近的 cell,而後選中 cell,讓其進行播放也就達到了播放的目的,代碼以下:

/* 進行視頻自動播放斷定邏輯判斷 */
- (void)handleScrollPlay{
    
    LCVideoCell *cell = (LCVideoCell *)[self getMinCenterCell];
    
    if (cell && ![self.playingCell isEqual:cell]) {
        
        NSLog(@"當前的 cell 存在,是%ld",cell.tag);
        cell.backgroundColor = [UIColor redColor];
        
        if (self.playingCell) {
            LCVideoCell *playingCell = (LCVideoCell *)self.playingCell;
            playingCell.backgroundColor = [UIColor whiteColor];
        }
        
        self.playingCell = cell;
        
    }
    
    
    
}

/* 獲取距離屏幕最中間的cell */
- (id)getMinCenterCell{
    
    CGFloat minDelta = CGFLOAT_MAX;
    
    //屏幕中央位置
    CGFloat screenCenterY = SCREEN_HEIGHT * 0.5;
    //當前距離屏幕中央最近的cell
    id minCell = nil;
    
    for (id cell in self.visibleCells) {
        
        if ([cell isKindOfClass:[LCVideoCell class]]) {
            
            LCVideoCell *videoCell = (LCVideoCell *)cell;
            //獲取當前 cell 的居中點座標
            CGPoint cellCenterPoint = CGPointMake(videoCell.frame.origin.x, videoCell.frame.size.height * 0.5 + videoCell.frame.origin.y);
            //轉換當前的 cell 的座標
            CGPoint coorPoint = [videoCell.superview convertPoint:cellCenterPoint toView:nil];
            CGFloat deltaTemp =  fabs(coorPoint.y - screenCenterY);
            
            if (deltaTemp < minDelta) {
                minCell = videoCell;
                minDelta = deltaTemp;
            }
            
        }
        
    }
    
    return minCell;
    
}


複製代碼

判斷當前的播放的 cell 是否已經移動到屏幕外面

這個判斷邏輯主要是實如今移出到屏幕外以後,視頻應該中止的功能,因此爲此咱們須要寫一個方法去判斷當前播放的 cell 的可見性。以及在滾動圖中實時判斷當前的播放的cell是否已經移動到屏幕外面。判斷的代碼以下:

/* 當前播放的視頻是否劃出屏幕 */
- (BOOL)playingCellIsOutScreen{

    if (!self.playingCell) {
        
        return YES;
    }
    
    LCVideoCell *videoCell = (LCVideoCell *)self.playingCell;
    
    //當前顯示區域內容
    CGRect visiableContentZone = [UIScreen mainScreen].bounds;
    
    //向上滾動
    if(self.scrollDirection == LC_SCROLL_UP){
        
        //找到滾動時候的正在播放視頻的cell底部的y座標點,計算出當前播放的視頻是否移除到屏幕外
        CGRect playingCellFrame = videoCell.frame;
        
        //當前正在播放視頻的座標
        CGPoint cellBottomPoint = CGPointMake(playingCellFrame.origin.x, playingCellFrame.size.height + playingCellFrame.origin.y);
        
        //座標系轉換(轉換到 window座標)
        CGPoint coorPoint = [videoCell.superview convertPoint:cellBottomPoint toView:nil];
        
        return CGRectContainsPoint(visiableContentZone, coorPoint);
        
        
    }
    
    //向下滾動
    else if(self.scrollDirection == LC_SCROLL_DOWN){
        
        //找到滾動時候的正在播放視頻的cell底部的y座標點,計算出當前播放的視頻是否移除到屏幕外
        CGRect playingCellFrame = videoCell.frame;
        
        //當前正在播放視頻的座標
        CGPoint orginPoint = CGPointMake(playingCellFrame.origin.x, playingCellFrame.origin.y);
        
        //座標系轉換(轉換到 window座標)
        CGPoint coorPoint = [videoCell.superview convertPoint:orginPoint toView:nil];
        
        return CGRectContainsPoint(visiableContentZone, coorPoint);
        
    }
    
    else{
        
        return NO;
    }
    
    
    return YES;
}

複製代碼

效果

視頻自動選擇播放的效果以下所示

總結

視頻的居中播放思想就是這樣,固然播放器以及網絡的判斷應該是播放器播放內部的處理方案了,但願可以給正在開發或者想要開發視頻自動選擇播放的同窗們一點小小的啓發。

Demo

Demo 點我

相關文章
相關標籤/搜索