flutter中流式布局
流式布局(Liquid)的特点(也叫"Fluid") 是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。栅栏系统(网格系统),用户标签等。在Flutter中主要有Wrap和Flow两种Widget实现。
专注于为中小企业提供网站设计制作、成都做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业抚顺免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
在介绍Row和Colum时,如果子widget超出屏幕范围,则会报溢出错误,在Flutter中通过Wrap和Flow来支持流式布局,溢出部分则会自动折行。
上述有很多属性和Row的相同,其意义其实也是相同的,这里我就不一一介绍了,主要介绍下不同的属性:
我们一般很少会使用Flow,因为其过于复杂,需要自己实现子widget的位置转换,在很多场景下首先要考虑的是Wrap是否满足需求。Flow主要用于一些需要自定义布局策略或性能要求较高(如动画中)的场景。Flow有如下优点:
我们对六个色块进行自定义流式布局:
实现TestFlowDelegate:
可以看到我们主要的任务就是实现paintChildren,它的主要任务是确定每个子widget位置。由于Flow不能自适应子widget的大小,我们通过在getSize返回一个固定大小来指定Flow的大小,实现起来还是比较麻烦的。
Flutter TextTrue ios 视频渲染 YUV420 转换 BGRA
网易云信播放器 Flutter 封装
事情是这样的 我们公司的业务是有 视频播放这一块业务 而且 是基于网易云信的 视频服务的 做的开发 。公司的App开发框架是使用 Flutter , 那么问题来了 Flutter 怎么 实现视频播放嘞 , 官方给出的解决方案 是 ### video_player 这个库的 实现 是 原生端做视频解码 然后通过 Texture 的方式 映射到 Flutter 中 但是解码器 IOS 使用的是 官方的 AVPlayer (苹果官方提供的播放器 啥都好 就是不支持流媒体播放 ) Android 解码器则是 exoplayer 很好很nice
但是
网易云信的视频 是加密的 只有自己的 播放器sdk 在能解码播放 android 和 ios 都支持流媒体 so 只能自己封装
Android 使用 SurfaceTexture 衔接 视频流 正常 但是 ios emmm 网易云信 播放器 返回 的 编码格式 是 NELP_YUV420 就是 YUV420 直接映射到 Flutter 黑屏 但是有声音
因为Skia 引擎底层只支持了 BGRA 格式的视频数据 所以 和黑屏了
首先我们吧 YUV420 转换成 CVPixelBufferRef 方法如下
该方法依赖 libyuv 请自行导入
然后是 pixelBuffer To SampleBuffer
最后吧 SmapleBuffer 转换 BGRA
方法如何使用
Flutter开发--视频播放器
目前Flutter平台主流的两个播放器是video_player和fijkplayer
pub
github
1、Flutter平台官方插件,作者是国外的,有问题沟通比较困难,只能通过提交issue
2、硬解码
4、UI封装: better_player
基于video_player和Chewie的高级视频播放器。它解决了许多典型的用例,并且易于运行。
5、播放器宽高比例与视频内容宽高比例不一致时,会出现图像压缩变形的问题
6、调用原生内核播放器:iOS--AVPlayer, Android--ExoPlayer
7、对于分段源 m3u8 的播放不友好,如果一个切片播放超时,会导致整个播放都失败
8、better_player可以缓存视频,但不能自定义缓存的地址,只能指定key,和缓存的最大内存量(还未研究超出最大的话是不能缓存新的,还是删除最旧的)
9、better_player不能完全自定义UI,只能修改类中的一些开放属性,比如说icon图标,文字颜色啥的
10、无网络有缓存时,封面可以正常展示
11、better_player播放失败有手动retry的设计
pub
github
1、fijkplayer 是一个 Flutter 生态的媒体播放器,是对 ijkplayer 的 Flutter 封装,支持 Android 和 iOS。 fijkplayer 使用 ijkplayer 作为播放器内核,ijkplayer 使用 ffmpeg 进行音视频解封装和解码,同时添加了 Android 和 iOS 平台特有的硬件加速解码能力。
2 、国内有QQ群,但是活跃度也是不高。
3、可以缓存视频,可以自定义缓存的地址,方便后续的内存维护。
4、可以通过FijkPanelWidgetBuilder较大程度上自定义UI。
5、无网络有缓存视频时,无法展示封面,因为内部是通过imageProvider去加载网络图片的。
7、播放失败无手动retry的设计
1、两种播放器都是通过外接纹理方案 (Texture),将播放器视频画面渲染接入 flutter 中,性能上优于 PlatformView 的接入方法。
如何自己实现?
下面以video_palyer的iOS源码部分解释:
iOS用CVPixelBufferRef将渲染出来的数据存在内存中,Flutter engine会将Texture的数据在内存中直接进行映射无需通过Channel传输,然后Texture Widget就可以把你提供的这些数据显示出来。在我们传输数据的时候会需要将其与 TextureID 绑定,绑定的过程通过BasicMessageChannel实现数据流的传输,以做到实时展示的效果
flutter直播怎么实现?
flutter作为一个相对来说比较新兴的框架,相比于其他框架来说避免不了存在生态不完善的问题。要想实现flutter直播,可以接入即构科技的Express Flutter SDK,然后通过集成、初始化SDK、登录房间服务器、用户推送自己的本地音视频、拉取远端的音视频流等简单五个步骤实现简单的实时音视频场景进行直播。
Flutter动态化方案调研
腾讯课堂14M
今日头条3M
闲鱼22M
百度贴吧13M
蚂蚁财富56.8M
百度网盘14M
手机淘宝15M
贝壳找房8M
由粗粒度小组件动态拼装出页面,Native端已经有很多成熟的框架,如天猫的Tangram。
开发语言:iOS、Android
适用场景:快速迭代的活动营销页面
优点:无侵入,更新简单
缺点:提前预埋,扩展性差,灵活性差
以webview作为容器的app,历史悠久,最早到2011年。
开发语言:HTML
适用场景:双端严格一致的银行类app,容器类的支付宝小程序等
优点:动态更新,跨平台
缺点:性能,加载速度
UI用Xml+JS表达,用Native View渲染。
开发语言:Xml+JS
适用场景:双端严格一致的银行类app,容器类的支付宝小程序等
优点:native组件,生态成熟
缺点:三方库crash,性能缺陷
UI用Dart表达,用Dart engine渲染。
Flutter官方不支持动态化。原因是Flutter在 Release 模式下构建的是 AOT 编译产物,在 Debug 模式下构建的是 JIT ,AOT 依赖的 Dart VM 和 JIT 并不一样, JIT Release 并不支持 iOS 设备。可行的方案是:AOT 需要一个编译后的 “Dart VM”。抽离一份 DartVM 独立编译,再以动态库的形式引入项目。
开发语言:Dart
适用场景:iOS、Android、Web、Desktop、Embed
优点:性能最佳
缺点:增大包体积 20MB+
大厂的主流方案。UI用JS表达,用Dart engine渲染。
开发语言:JS、类JS
适用场景:iOS、Android
优点:性能最佳
缺点:需要掌握JS、Dart两个语言和框架
大厂的主流方案。UI用Dart表达,用Dart engineX渲染。
开发语言:Dart
适用场景:iOS、Android
优点:性能最佳
缺点:需要改造Dart engine
1、 美团外卖Flutter动态化实践
2、 携程App 首页动态化探索
3、 Flutter 动态化在最右 App 中的实践
4、 Flutter 动态化热更新的思考与实践
5、 NOW直播Flutter动态搜索列表页实现
6、 Flutter动态化的方案对比及最佳实现-闲鱼
7、 基于JavaScript 的MXFlutter
Flutter视频播放器,简洁!
注:亮度调节和音量调节gif无法体现,功能是ok的,其次默认Icon锁的close和open实在难以分辨。
环境:Flutter 2.8.1 channel stable ;Dart 2.15.1
需要音频播放器的看这里: Flutter音乐播放器
重点说下这个工具类,因为视频播放,涉及到状态改变有很多,笔者刚开始选择使用 InheritedWidget 来在众多的widget之间共享数据。但是总感觉这样有点繁琐,且不很优雅!
这里非广告,如果是使用 GetX 就很简单了,笔者也使用了 GetX 进行封装了,一泻千里的赶脚!,但是笔者还是那句话:刚开始接触Flutter的开发者不是很建议使用 GetX ,可以先熟悉下Flutter状态管理的基础原理再行使用。而且为了尽量简洁,还是不引入其他的第三方了。
我们选择对第三方插件进行封装的目的不外乎这几个:
于是笔者就写了一个工具类 VideoPlayerUtils ,专门且只用来处理播放器的所有业务。包括暂停、播放、跳转、调节音量、调节亮度、切换视频等操作。在所有的widget中不会引用关于 video_player 或其他第三方插件的任何信息, VideoPlayerUtils 负责widget与播放器之间的所有操作交互。后续优化迭代或更换播放器插件时,只需针对这个工具类进行修改,对所有widget不会有任何的影响,大大的解耦合了。
其中 VideoPlayerState :
提供以上的公共属性,可以通过 VideoPlayerUtils 来获取对应的值,使用 get 只读,使外界不会误修改这些属性,以保证数值的安全性。开发者可根据自身需要自行添加属性。
提供以上方法来处理播放器的所有业务。同样的开发者可根据自身需要自行添加或修改。
重点说下这个方法,是整个业务的核心方法,控制视频的播放或暂停。开发者只要遇到播放或暂停是均可调用此方法,具体是播放或暂停,内部根据传入的 url 自行判断,开发者不需要关心。
切换新视频也是使用此方法,传入的 url 与上次不一致,自动切换新视频。笔者可根据 statusListener 来监听播放状态的改变,以此处理自身逻辑。
这个也需要提下,视频播放器在播放新视频时会异步初始化,一般我们的操作是在 initState() 初始化,成功后再 setState() 。这里笔者遇到一个让人蛋疼的问题:
我们看 video_player 的使用:
VideoPlayer(controller) :widget中已经持有了controller。本来笔者封装的目的就是为了让widget与controller的之间解耦合。但此时的笔者。。。。
放弃不是不可能放弃的,这辈子都不会放弃的!
于是笔者取了巧,写了一个初始化监听器 initializedListener ,包换2个参数: bool,Widget ,初始化是否成功;其中widget为初始化成功返回需要展示的播放器UI,失败默认返回 const SizedBox() 。
到这里就可以简单使用了:
没看错,视频播放就是这么简单。
如果有更多的业务功能,笔者也按照自己的需求写了一套,同样的开发者可根据自身需要自行添加或修改。
VideoPlayerGestures 主要是处理手势的,比如快进、快退等跳转播放;左侧上下滑动调节亮度;右侧上下滑动调节音量;单击是否开启沉浸式播放,所有widget的隐藏与显示;双击播放、暂停等。
哦,还有 PercentageWidget 也放到这个文件下了,就是这玩意:
因为显示的百分比与手势相关,随着手势移动而更新。开发者可自行处理。
笔者处出于简单考虑,就按照整个UI的位置命名了。瞅一眼就知道是啥玩意。
同样的开发者可根据自身需要自行添加或修改。
就是这玩意:
同样的开发者可根据自身需要自行添加或修改。话说这个锁的 Icon 的open和close是真的难分辨!
就是这玩意:
同样的开发者可根据自身需要自行添加或修改。
这玩意是自定义的,别问,问就是跟产品干一架落了下风
主要就是自定义这玩意:
同样的开发者可根据自身需要自定义。
注:这里没有添加缓冲的进度,开发可查看 video_player 中的源码 VideoProgressIndicator ,按业务自行定义。
这玩意就是整合以上的widget,再考虑下全屏的安全区域,没啥东西。开发者可自行处理!
具体的实现监听器的思路, 看这里 。
自此一个漂亮的Flutter视频播放器就已经结束了。如果您觉得对您有些许帮助的话,欢迎 Star !
网站标题:flutter直播流,Flutter直播
分享地址:http://scgulin.cn/article/pheepg.html