百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Flutter 实现视频全屏播放逻辑及解析

cac55 2024-09-20 12:51 28 浏览 0 评论

作者:恋猫de小郭

前言

相信做过移动端视频开发的同学应该了解,想要实现视频从普通播放到全屏播放的逻辑并不是很简单,比如在 GSYVideoPlayer 中的动态全屏切换效果,就使用了创建全新的 Surface 来替换实现:

  • 创建全新的 Surface ,并将对于的 View 添加到应用顶层的 DecorView 中;
  • 在全屏时将新创建的 Surface 并设置到 Player Core ;
  • 同步两个 View 的播放状态参数和旋转系统界面;
  • 退出全屏时移除 DecorView 中的 Surface,切换 List Item 中的 Surface 给 Player Core ,同步状态。

当然,不同的播放内核可能还需要做一些额外操作,但是这一切在 Flutter 中就变得极为简单。

事实上 Flutter 中实现全屏切换效果很简单,后面会一并介绍为什么在 Flutter 上实现会如此简单。

实现效果

如下图所示是 Flutter 中实现后的全屏效果,而实现这个效果的关键就是跳堆栈就可以了!是的,Flutter 中简单地跳页面就能够实现无缝的全屏切换。

如下代码所示,首先在正常播放页面下加入官方 video_player 插件的 VideoPlayer 控件,并且初始化 VideoPlayerController 用于加载需要播放的视频并初始化,另外此处还用了 Hero 控件用于实现页面跳转过渡的动画效果。

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.network(
        'https://res.exexm.com/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 控件实现过渡动画和视频渲染。

这里的 VideoPlayerController 可以通过构造方法传递进来,也可以通过 InheritedWidget 实现共享传递,只要是和前面普通播放界面的 controller 是同一个即可。

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 方法就可以快速实现应用的横竖屏切换。

最后如下代码所示,只需要通过 Navigator 调用页面跳转就可以实现全屏和非全屏的无缝切换了。

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

是不是很简单,只需要 VideoPlayer 、Hero 和 Navigator 就可以快速实现全屏切换播放的效果,那为什么在 Flutter 上可以这样简单的实现呢?

实现逻辑

之所以可以如此简单地实现动态化全屏效果,其实主要涉及到 video_player 插件在 Flutter 上的实现:外接纹理 Texture 。

因为 Flutter 中的控件基本上是平台无关的,而其控件主要是由 Flutter Engine 直接绘制,简单地说就是:原生平台仅仅提供了一个 Activity / ViewController 容器, 之后由容器内提供一个 Surface 给 Flutter Engine 用户绘制。

所以 Flutter 中控件的渲染堆栈是独立的,没办法和原生平台直接混合使用,这时候为了能够在 Flutter 中插入原生平台的部分功能,Flutter 除了提供了 PlatformView 这样的实现逻辑之外,还提供了 Texture作为 外接纹理的支持。

如上图所示,在《Flutter 完整实战详解》 中介绍过,Flutter 的界面渲染是需要经历 Widget -> RenderObject -> Layer 的过程,而在 Layer 的渲染过程中,当出现一个 TextureLayer 节点时,说明这个节点使用了 Flutter 中的 Texture 控件,那么这个控件的内容就会由原生平台提供,而管理 Texture 主要是通过 textureId 进行识别的。

举个例子,在 Android 原生层中 video_player 使用的是 exoplayer 播放内核,那么如上图所示,VideoPlayerController 会在初始化的时候通过 MethodChannel 和原生端通信,之后准备好播放内核和 Surface,最后将对应的 textureId 返回到 Dart 中。

所以在前面的代码中,需要在全屏和非全屏页面使用同一个 VideoPlayerController,这样它们就具备了同一个 textureId。

具备同一个 textureId 后,那么只要原生层不停止播放, textureId 对应的原生数据就一直处于更新状态,而这时候虽然跳转路由页面,但不同的 VideoPlayer 内部的 Texture 控件用的是同一个 VideoPlayerController,也就是同一个 textureId ,所以它们会呈现出通用的画面。

如下图所示,这个过程简单总结就是: Flutter 和原生平台通过 PixelBuffer 为介质进行交互,原生层将数据写入 PixelBuffer ,Flutter 通过注册好的 textureId 获取到 PixelBuffer 之后由 Flutter Engine 绘制。

最后需要注意的是,在 iOS 上在实现页面旋转时, SystemChrome.setPreferredOrientations 方法可能会出现无效,这个问题在 issue #23913 和 #13238 中有提及,这里可能需要自己多实现一个原生接口进行兼容,当然在 auto_orientation 或者 orientation 等第三方库也进行了这方面的兼容。

另外 iOS 的页面旋转还确定是否打开了旋转配置的开关。

资源推荐

本文 Demo : flutter_video_full_controller
Github : https://github.com/CarGuo
开源 Flutter 完整项目:https://github.com/CarGuo/GSYGithubAppFlutter
开源 Flutter 多案例学习型项目: https://github.com/CarGuo/GSYFlutterDemo
开源 Fluttre 实战电子书项目:https://github.com/CarGuo/GSYFlutterBook
开源 React Native 项目:https://github.com/CarGuo/GSYGithubApp


转载自:CSDN博主「恋猫de小郭」的原创文章
原文链接:https://blog.csdn.net/ZuoYueLiang/article/details/104371429

相关推荐

无力吐槽的自动续费(你被自动续费困扰过吗?)

今天因为工作需要,需要在百度文库上下载一篇文章。没办法,确实需要也有必要,只能老老实实的按要求买了个VIP。过去在百度文库上有过类似经历,当时为了写论文买了一个月的VIP,后面也没有太注意,直到第二个...

百度文库推出“文源计划”创作者可一键认领文档

11月7日,百度文库发布了旨在保护创作者权益的“文源计划”。所谓“文源计划”,即为每一篇文档找到源头,让创作者享受更多的权益。据百度文库总经理李小婉介绍,文源计划分为三部分,分别是版权认证、版权扶持和...

有开放大学学号的同学,百度文库高校版可以用了。

还在网上找百度文库的下载方式,只要从身边的朋友在读开放大学的,那他(她)的学号就可以登陆到国家开放大学图书馆,还使用百度文库高校版来下载。与百度文库稍有不同,但足够使用了。现转国图链接如下:htt...

搜索资源方法推荐(搜索资源的方法)

今天msgbox就要教大家如何又快又准的搜到各类资源,第一点,排除干扰百度搜索出来啊经常前排展示它的产品以及百度文库,如何去除呢?很简单,后面输入空格减号百度文库,比如你搜高等数学百度文库很多,只要后...

一行代码搞定百度文库VIP功能(2021百度文库vip账号密码共享)

百度文库作为大家常用查资料找文档的平台,大多数文档我们都可以直接在百度文库找到,然而百度文库也有让人头痛的时候。好不容易找到一篇合适的文档,当你准备复制的时候他却提示你需要开通VIP才能复制~~~下载...

百度文库文档批量上传工具用户说明书

百度文库文档批量上传工具用户说明书1、软件主要功能1、批量上传文档到百度文库,支持上传到收费、VIP专享、优享以及共享。2、支持自动分类和自动获取标签3、支持多用户切换,一个账户传满可以切换到...

百度文库现在都看不到文档是否上传成功,要凉了吗?

打开知识店铺,百度文库文档里显示都是下载这一按键,上传的文档也看不到是否成功?咋情况,要取消了吗?没通过审核的也不让你删除,是几个意思,想通吃吗?现在百度上传文档也很费劲,有时弄了半天的资料上传审核过...

微信推广引流108式:利用百度文库长期分享软文引流

百度文库相对于百度知道、百度百科来说,操作上没那么多条条框框,规则上也相对好把握些。做一条百度知道所花费的精力一般都会比做一条百度文库的要多些,老马个人操作下来觉得百度文库更好把握。但见仁见智吧,今天...

职场“避雷”指南 百度文库推出标准化劳动合同范本

轰轰烈烈的毕业季结束了,众多应届生在经过了“职场海选”后,已正式成为职场生力军的一员。这一阶段,除了熟悉业务,签订劳动合同、了解职场福利也迅速被提上日程。而随着国人法律意识的增强,百度文库内《劳动合同...

《百度文库》:素材精选宝库(百度文库官网首页)

《百度文库》:独特功能助力选择高质量素材在当今信息爆炸的时代,如何高效地获取并利用有价值的素材成为了许多人面临的挑战。而《百度文库》作为百度公司推出的一款在线文档分享平台,凭借其丰富的资源、强大的功能...

深度整合和开放AI能力 百度文库和网盘推出内容操作系统「沧舟OS」

【TechWeb】4月25日消息,Create2025百度AI开发者大会上,百度文库和百度网盘推出全球首个内容操作系统——沧舟OS。基于沧舟OS,百度文库APP全新上线「GenFlow超能搭子」...

女子发现大二作业被百度文库要求付费下载,律师:平台侵权,应赔偿

近日,28岁的黎女士在百度百科搜索家乡的小地名时,发现了自己在大二完成的课题作业。她继续搜索,发现多个平台收录了该文,比如豆丁网和文档之家等,有的还设置了付费或积分下载。2月15日,九派新闻记者以用户...

2016杀入百度文库的新捷径,只有少数人才知道的喔

百度的产品在SEO优化中的分量真不用多说,其实很多人都像我一样一直在找捷径。但是我经常发现很多人都是在用死方法。比如发贴吧发帖而不知道去申请一个吧主,知道自问自答而不知道去申请一个合作资格。口碑和贴吧...

百度文库付费文档搜索方法(百度文库付费文档搜索方法有哪些)

一直以来,百度文库中无论是个人中心还是个人主页,都没有像淘宝一样的店内搜索功能,连最近新开的知识店铺也没有设计店内搜索功能,这无论是对上传用户还是下载用户都不方便,上传用户想要搜索自己的文档无法办到...

供读者免费使用!泰达图书馆机构版百度文库新年上新啦

在泰达图书馆读者使用百度文库数字资源不需要VIP,免-费-用!惊不惊喜?快来了解一下吧……新年伊始,为满足区域企业、高校、科研院所以及居民群众在教学、科研及学习过程中,对各类文献资源的需求,泰达图书馆...

取消回复欢迎 发表评论: