中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter視頻滾動播放的解決方案是什么

發布時間:2021-12-07 19:43:51 來源:億速云 閱讀:217 作者:柒染 欄目:移動開發

Flutter視頻滾動播放的解決方案是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

視頻列表滾動播放。

分類

視頻列表的播放規則一般需要和具體產品、交互確認,播放一般都是靜音的,根據露出坐標規律,常見的有兩大類:

固定位置播放

如滑動屏幕的中間位時,延遲若干毫秒自動播放。

固定索引+屏占比播放

如第一個符合屏占比的視頻可以自動播放;屏占比可以是當前視頻組件的高度百分比,也可以是屏幕上的固定位置;當我們把屏占比定位60%時,第一個視頻的可見區小于60%會暫停播放,觸發可見的下一個視頻。

更多相關學習內容看GitHub: https://github.com/Meng997998/AndroidJX
以下視頻內容學習vx:xx13414521

Flutter視頻滾動播放的解決方案是什么

有料視頻流

在開發安居客-有料內容Feed流時,我們遇到的交互是第二種,由于視頻貼出現不固定,待播放的位置也不固定。 在這種情況下要實現與Native一致的效果是一個不小的難題。

我們在開發過程中將這個問題進行了分解:

  • 滾動檢測:拋開視頻,單純設計一個組件,能夠按需檢測特定Widget

  • 視頻播放組件:引入視頻播放,將視頻控件根據滾動檢測要求,進行接入

組件原型

下面看一下我們設計的原型組件效果。

Flutter視頻滾動播放的解決方案是什么

video-play.gif

我們將視頻貼子用一個色塊進行占位。通過監聽滑動事件,當停止后,從屏幕頂端開始,遍歷當前視窗范圍內的控件,如果是視頻控件,并且在屏幕上的露出比符合預期,那么將其返回。供開發者后續處理。

核心流程如下圖所示:

Flutter視頻滾動播放的解決方案是什么

基于這個思路,我們開發了一個ScrollDetectListener組件:

  • 使用ScrollDetectListener包裹ListView,ListView為業務相關的視頻流帖子。

  • 視頻帖子使用MetaConsumer包裹;

Flutter視頻滾動播放的解決方案是什么

MetaConsumer(
  index: index,  data: data,  builder: (BuildContext context, VideoPlayModel model, Widget child) {    var play = model.playIndex == index;    return Container(
      width: MediaQuery.of(context).size.width,      alignment: Alignment.center,      height: 100,      padding: EdgeInsets.zero,      child: play ? Text('Playing $data') : Text('$data'),      color: play ? Colors.redAccent : Colors.grey[100] ?? Colors.grey,
  );
})

視頻檢測組件

通過原型完成必要的調試和優化之后,我們可以嘗試接入視頻控件。

Demo1

Flutter視頻滾動播放的解決方案是什么

Demo2

Flutter視頻滾動播放的解決方案是什么

在處理視頻的時候,需要注意的點也很多,比如:

  • 視頻貼的首幀預覽圖/封面圖,采用視頻首幀,會遇到視頻開頭是黑屏的問題,采用獨立封面圖相對效果會更好。

  • 視頻高寬比控制

  • 帖子狀態控制:待播放,加載中,播放,循環/靜音等

Flutter視頻滾動播放的解決方案是什么

其他方案

除了我們的實現方案,目前還可以找到的一個開源庫: inview_notifier_list。

這個開源庫它支持固定位置播放,也就是我們說的以第一種類型。

該項目提供了預覽效果和demo,非常良心的作者。

Demo1

Flutter視頻滾動播放的解決方案是什么

Demo2

Flutter視頻滾動播放的解決方案是什么

他的基本原理如下:

  • 設計了一個InViewState容器,繼承了ChangeNotify,用于記錄列表中的子Widget的context信息,InViewState state = InViewNotifierList.of(context);

  • 當視頻Widget執行build時,調用InViewState.addContext加入集合中

  • 同時視頻Widget本身需要用AnimatedBuilder將InViewState和視頻狀態進行關聯,也就是當InViewState更新時,重新構建視頻Widget

  • 什么時候更新InViewState呢?答案是滑動過程中。滑動的時候開始遍歷前面加入的視頻Widget的contxt,其實就是為了通過context難道控件最終的坐標,判斷是不是符合規則

  • 如果坐標位置命中規則,就會吧當前的控件的標識id緩存到一個集合中_currentInViewIds,然后通知觀察者數據變化了,所以AnimatedBuilder會觸發child的build

  • 在child的build時(也就是前面提到的視頻空間build),就會在判斷當前視頻的id是否在_currentInViewIds中,進行差異化繪制。

我們用一張圖來概括性大致流程:

Flutter視頻滾動播放的解決方案是什么

image

可以看到這里面有兩個集合,分別用那個有緩存控件的Context和名中控件數據。為了避免遍歷的性能問題,作者引入了緩存閾值,可以由使用者根據實際情況調整緩存context的個數。比如我們可以把個數設置為一個屏幕最多能展示的視頻條數。這樣很可能不超過5個。

///Add the widget's context and an unique string id that needs to be notified.void addContext({@required BuildContext context, @required String id}) {
  _contexts.add(_WidgetData(context: context, id: id));
}///Keeps the number of widget's contexts the InViewNotifierList should stored/cached for///the calculations thats needed to be done to check if the widgets are inView or not.///Defaults to 10 and should be greater than 1\. This is done to reduce the number of calculations being performed.void removeContexts(int letRemain) {  if (_contexts.length > letRemain) {
    _contexts = _contexts.skip(_contexts.length - letRemain).toSet();
  }
}

這個實現方案基本滿足的場景一的規則。并且實現了局部刷新的監聽。

下面我們看下場景二,如果要基于當前視頻的位置做計算,這個庫支持不了。

可以看到它暴露的參數: 視頻控件上邊緣差值,下邊緣差值值,視窗高度H

//Check if the item is in the viewport by evaluating the provided widget's isInViewPortCondition condition.
  isInViewport = _isInViewCondition(deltaTop, deltaBottom, vpHeight);

如果我們要計算視頻控件自身的露出情況,需要單獨獲取控件的坐標和大小來計算。如果進行二次開發,只需要將判定函數擴展一些參數即可。

這兩種方案,在檢測視頻貼的邏輯上分別采用了主動檢測和被動檢測; 最大差異是我們沒有將視頻貼提前添加到集合中,所以不用維護一個固定容量的緩存集合。

關于Flutter視頻滾動播放的解決方案是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安阳县| 盘锦市| 安泽县| 洮南市| 龙州县| 重庆市| 台江县| 杭州市| 尼勒克县| 潮州市| 四平市| 道孚县| 宁乡县| 五台县| 龙川县| 平利县| 黑山县| 通许县| 太保市| 东至县| 通山县| 文登市| 临颍县| 阳山县| 来凤县| 郯城县| 濮阳市| 罗源县| 大港区| 黑河市| 潜山县| 芦溪县| 安阳县| 永新县| 缙云县| 镶黄旗| 西吉县| 德兴市| 北海市| 兴海县| 高淳县|