久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    Flutter 實(shí)現(xiàn)視頻全屏播放邏輯及解析

     看見就非常 2020-05-29

    一、前言

    相信做過移動(dòng)端視頻開發(fā)的同學(xué)應(yīng)該了解,想要實(shí)現(xiàn)視頻從普通播放到全屏播放的邏輯并不是很簡單,比如在 GSYVideoPlayer 中的動(dòng)態(tài)全屏切換效果,就使用了創(chuàng)建全新的 Surface 來替換實(shí)現(xiàn):

    • 創(chuàng)建全新的 Surface ,并將對(duì)于的 View 添加到應(yīng)用頂層的 DecorView 中;

    • 在全屏?xí)r將新創(chuàng)建的 Surface 并設(shè)置到 Player Core ;

    • 同步兩個(gè) View 的播放狀態(tài)參數(shù)和旋轉(zhuǎn)系統(tǒng)界面;

    • 退出全屏?xí)r移除 DecorView 中的 Surface,切換 List Item 中的 Surface 給 Player Core ,同步狀態(tài)。

    當(dāng)然,不同的播放內(nèi)核可能還需要做一些額外操作,但是這一切在 Flutter 中就變得極為簡單。

    事實(shí)上 Flutter 中實(shí)現(xiàn)全屏切換效果很簡單,后面會(huì)一并介紹為什么在 Flutter 上實(shí)現(xiàn)會(huì)如此簡單。

    二、實(shí)現(xiàn)效果

    如下圖所示是 Flutter 中實(shí)現(xiàn)后的全屏效果,而實(shí)現(xiàn)這個(gè)效果的關(guān)鍵就是跳堆棧就可以了!是的,F(xiàn)lutter 中簡單地跳頁面就能夠?qū)崿F(xiàn)無縫的全屏切換。

    如下代碼所示,首先在正常播放頁面下加入官方 video_player 插件的 VideoPlayer 控件,并且初始化 VideoPlayerController 用于加載需要播放的視頻并初始化,另外此處還用了 Hero 控件用于實(shí)現(xiàn)頁面跳轉(zhuǎn)過渡的動(dòng)畫效果。

      @override
      void initState() {
        super.initState();
        _controller = VideoPlayerController.network(
            'https://res./cw_145225549855002')
          ..initialize().then((_) {
            // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
            setState(() {});
          });
      }
      
     Container(
       height: 200,
       margin: EdgeInsets.only(
           top: MediaQueryData.fromWindow(
                   WidgetsBinding.instance.window)
               .padding
               .top),
       color: Colors.black,
       child: _controller.value.initialized
           ? Hero(
               tag: "player",
               child: AspectRatio(
                 aspectRatio: _controller.value.aspectRatio,
                 child: VideoPlayer(_controller),
               ),
             )
           : Container(
               alignment: Alignment.center,
               child: CircularProgressIndicator(),
             ),
     ))

    如下代碼所示,之后在全屏的頁面中同樣使用 Hero 控件和 VideoPlayer 控件實(shí)現(xiàn)過渡動(dòng)畫和視頻渲染。

    這里的 VideoPlayerController 可以通過構(gòu)造方法傳遞進(jìn)來,也可以通過 InheritedWidget 實(shí)現(xiàn)共享傳遞,只要是和前面普通播放界面的 controller 是同一個(gè)即可。

    Container(
         color: Colors.black,
         child: Stack(
           children: <Widget>[
             Center(
               child: Hero(
                 tag: "player",
                 child: AspectRatio(
                   aspectRatio: widget.controller.value.aspectRatio,
                   child: VideoPlayer(widget.controller),
                 ),
               ),
             ),
             Padding(
               padding: EdgeInsets.only(top: 25, right: 20),
               child: IconButton(
                 icon: const BackButtonIcon(),
                 color: Colors.white,
                 onPressed: () {
                   Navigator.pop(context);
                 },
               ),
             )
           ],
         ),
        )

    另外在 Flutter 中,只需要通過 SystemChrome.setPreferredOrientations 方法就可以快速實(shí)現(xiàn)應(yīng)用的橫豎屏切換。

    最后如下代碼所示,只需要通過 Navigator 調(diào)用頁面跳轉(zhuǎn)就可以實(shí)現(xiàn)全屏和非全屏的無縫切換了。

      Navigator.of(context)
                          .push(MaterialPageRoute(builder: (context) {
                        return VideoFullPage(_controller);
                      }));

    是不是很簡單,只需要 VideoPlayerHeroNavigator 就可以快速實(shí)現(xiàn)全屏切換播放的效果,那為什么在 Flutter 上可以這樣簡單的實(shí)現(xiàn)呢?

    三、實(shí)現(xiàn)邏輯

    之所以可以如此簡單地實(shí)現(xiàn)動(dòng)態(tài)化全屏效果,其實(shí)主要涉及到 video_player 插件在 Flutter 上的實(shí)現(xiàn):外接紋理 Texture

    因?yàn)?Flutter 中的控件基本上是平臺(tái)無關(guān)的,而其控件主要是由 Flutter Engine 直接繪制,簡單地說就是:原生平臺(tái)僅僅提供了一個(gè) Activity / ViewController 容器, 之后由容器內(nèi)提供一個(gè) Surface 給 Flutter Engine 用戶繪制。

    所以 Flutter 中控件的渲染堆棧是獨(dú)立的,沒辦法和原生平臺(tái)直接混合使用,這時(shí)候?yàn)榱四軌蛟?Flutter 中插入原生平臺(tái)的部分功能,Flutter 除了提供了 PlatformView 這樣的實(shí)現(xiàn)邏輯之外,還提供了 Texture作為 外接紋理的支持。

    如上圖所示,在《Flutter 完整實(shí)戰(zhàn)詳解》 中介紹過,Flutter 的界面渲染是需要經(jīng)歷 Widget -> RenderObject -> Layer 的過程,而在 Layer 的渲染過程中,當(dāng)出現(xiàn)一個(gè) TextureLayer 節(jié)點(diǎn)時(shí),說明這個(gè)節(jié)點(diǎn)使用了 Flutter 中的 Texture 控件,那么這個(gè)控件的內(nèi)容就會(huì)由原生平臺(tái)提供,而管理 Texture 主要是通過 textureId 進(jìn)行識(shí)別的

    舉個(gè)例子,在 Android 原生層中 video_player 使用的是 exoplayer 播放內(nèi)核,那么如上圖所示,VideoPlayerController 會(huì)在初始化的時(shí)候通過 MethodChannel 和原生端通信,之后準(zhǔn)備好播放內(nèi)核和 Surface,最后將對(duì)應(yīng)的 textureId 返回到 Dart 中

    所以在前面的代碼中,需要在全屏和非全屏頁面使用同一個(gè) VideoPlayerController,這樣它們就具備了同一個(gè) textureId

    具備同一個(gè) textureId 后,那么只要原生層不停止播放, textureId 對(duì)應(yīng)的原生數(shù)據(jù)就一直處于更新狀態(tài),而這時(shí)候雖然跳轉(zhuǎn)路由頁面,但不同的 VideoPlayer 內(nèi)部的 Texture 控件用的是同一個(gè) VideoPlayerController,也就是同一個(gè) textureId ,所以它們會(huì)呈現(xiàn)出通用的畫面。

    如下圖所示,這個(gè)過程簡單總結(jié)就是: Flutter 和原生平臺(tái)通過 PixelBuffer 為介質(zhì)進(jìn)行交互,原生層將數(shù)據(jù)寫入 PixelBuffer ,F(xiàn)lutter 通過注冊好的 textureId 獲取到 PixelBuffer 之后由 Flutter Engine 繪制

    最后需要注意的是,在 iOS 上在實(shí)現(xiàn)頁面旋轉(zhuǎn)時(shí), SystemChrome.setPreferredOrientations 方法可能會(huì)出現(xiàn)無效,這個(gè)問題在 issue #23913#13238 中有提及,這里可能需要自己多實(shí)現(xiàn)一個(gè)原生接口進(jìn)行兼容,當(dāng)然在 auto_orientation 或者 orientation 等第三方庫也進(jìn)行了這方面的兼容。

    另外 iOS 的頁面旋轉(zhuǎn)還確定是否打開了旋轉(zhuǎn)配置的開關(guān)

    資源推薦

    • 本文 Demo : flutter_video_full_controller

    • Github : https://github.com/CarGuo

    • 開源 Flutter 完整項(xiàng)目:https://github.com/CarGuo/GSYGithubAppFlutter

    • 開源 Flutter 多案例學(xué)習(xí)型項(xiàng)目: https://github.com/CarGuo/GSYFlutterDemo

    • 開源 Fluttre 實(shí)戰(zhàn)電子書項(xiàng)目:https://github.com/CarGuo/GSYFlutterBook

    • 開源 React Native 項(xiàng)目:https://github.com/CarGuo/GSYGithubApp

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請遵守用戶 評(píng)論公約

      類似文章 更多

      主站蜘蛛池模板: 国产精品自产拍在线观看| 中文字幕无码无码专区| 无码人妻精品一区二区三区下载| 老熟妇高潮一区二区三区| 日韩中文字幕亚洲精品| 乱码中字在线观看一二区| 男女性杂交内射女bbwxz| A男人的天堂久久A毛片| 同桌上课脱裙子让我帮他自慰| 国产精品一区在线蜜臀| 无码人妻丰满熟妇区毛片18| 日韩有码中文字幕国产| 成人欧美一区二区三区在线观看| 国产精品99中文字幕| 国产午夜无码视频在线观看| 亚洲一区二区偷拍精品| 免费日韩中文字幕高清电影| 午夜大片免费男女爽爽影院| 精品无人区一区二区三区| 老司机午夜精品视频资源| 西西午夜无码大胆啪啪国模| 亚洲高清WWW色好看美女| 国产高清不卡一区二区| 伊人久久大香线蕉成人| 国产中文字幕精品视频| 国产亚洲一区二区在线观看 | 妺妺窝人体色WWW在线一| 日本高清一区免费中文视频| 撕开奶罩揉吮奶头高潮AV | 亚洲成人精品综合在线| 国产激情视频一区二区三区| 色狠狠色噜噜AV一区| 久久人与动人物a级毛片| 人妻AV中文字幕一区二区三区| 亚洲欧美日韩愉拍自拍美利坚| 一夲道无码人妻精品一区二区| 亚洲一卡2卡3卡4卡精品| 欧美成本人视频免费播放| 亚洲中文字幕无码中字| 国产喷水1区2区3区咪咪爱AV| 国产高清色高清在线观看|