直播带货已成为近年来最热的“风口”,已成为电商升级的新突破口。闲鱼作为国内最大的二手交易平台市场,直播带货也成为推动成交的强烈需求。但是闲鱼直播原先接入外部提供的直播sdk,存在以下几个痛点问题:
因此闲鱼想基于直播sdk的一些能力,做一套跨平台直播sdk,减少开发维护成本。考虑到闲鱼在flutter技术栈上有一定技术积累,新版直播通过Flutter实现跨平台开发(支持ios,android),再接入闲鱼的全链路日志系统,能解决目前闲鱼直播面临的问题。
在设计开发之初,我们定下了几条原则:
如果放到native层,那么flutter就会做的很薄,仅提供有限的接口能力。这样会带来一个问题:如果我们想修改一个业务逻辑,实际上还得改三处代码(android,ios,flutter),开发成本和原来差不多。
如果放到flutter层,那么修改业务代码只需要改flutter一处即可,真正做到跨平台。
对照线上老native闲鱼直播间的很多功能,我们发现核心部分主要有:视频播放,评论,分享,关注,分享,宝贝口袋等等(下图左)。这其中难点涉及到如何划分:哪些是核心能力,必须依赖native能力?哪些能flutter化?首先我们从视觉角度分析,可将直播间拆解为以下三层:播放渲染层,互动容器层,UI层(见下图右)。 播放渲染层:作用是渲染拉流数据,完成视频播放,业务无关。我们可以复用底层拉流和编解码能力,播控控逻辑上移到flutter层。
互动渲染层:基于动态容器完成渲染,完成一些互动玩法(例如直播间红包,拍卖组件等)。这个动态容器是基于native层,但是依赖上层桥能力可以进行上移到flutter,完成动态化。
UI层:UI交互层,比如分享,评论,关注,点赞等以及feed流框架等。这层纯UI交互,完全可以用flutter化。
最终我们得到如下新版flutter直播框架图
直播必然离不开视频播放,播放器作为核心能力,方案选型至关重要。目前开源的flutter播放器主要分为以下几类:
播放器类型 | 介绍 | 特点 |
---|---|---|
video_player | 跨三端播放器(android/ios/web) 底层依赖Exoplayer(android),AVPlayer(ios) | 官方支持,兼容性好,迭代及时。api使用较为复杂;底层依赖难以切换 |
ijkplayer系列播放器 | 基于ijkplayer封装的播放器插件 | 相比官方插件,迭代频率低,点赞人数少些 |
引入第三方插件播放器会带来几个问题:造成包体积增大,维护风险未知;闲鱼底层播放器并非基exoplayer,这样造成播放器管理不统一;引入外来库容易造成库版本冲突。因此我们决定自研一套基于闲鱼环境的播放器。采用方案是基于外接纹理,将native创建的纹理id传递到flutter层进行展示,具体原理自行查阅,不在此展开。 其中,我们遇到一个难题:播放器的状态管理做过播放器业务的同学都知道,播放器内部是个状态机。如果调用时序不合理,很容易发生crash。常见的做法是在播放器上再封装一层sdk层,内部做状态维护和管理,过滤掉不合法的状态操作。这次我们决定将sdk层业务逻辑全部上移到flutter层,但是flutter和native直接是通过methodChannel进行通信的,methodChannel是异步的。这会造成上层播放状态和底层的播放状态是不一致的。考虑两种case:
// 视频prepare
void load() async {
...
}
// 播放
void play async() {
...
}
// 暂停
void pause async() {
...
}
// 情况1:加载中立即调用play
load();
play(); // 不生效
// 情况2:频繁点击暂停/播放
play();
pause();
play();
pause();
....
调用不生效
线程卡顿
针对上述问题存在的问题,我们在flutter层做了更为细致状态管理。对于异步调用加入了另外两种状态:过渡态和期望态。
例如:
当我们有加载动作load,会将播放器状态设置为过渡态(load_pending),处于此状态下将不会响应特定的操作(比如play);如果此时调用了play方法,播放器仅仅会记录下期望态wantedState=playing;
当加载完成后native会通知flutter层状态改变,从load_pending->loaded。此时我们会校验当前状态是否和期望态是否相等。由于当前为loaded 不等于期望态playing,我们会帮用户补上一次play操作(见下图)。
同样当频繁调用play/pause方法时,我们会将播放器状态设置成过渡态(play_pending/pause_pending),此状态不响应播放暂停操作,而仅仅改变用户的期望态;当native通知flutter层操作状态改变完成后,再校验一次期望态是否和当前状态是否相等,如果不相等再做响应操作
过渡态/期望态
对于带货直播来说,互动玩法是个必不可少的重要元素。每逢重点促销节日,各种运营活动接踵而来。一个不需要跟版,全版本覆盖的动态层容器有着非常大的吸引力。我们参考了直播sdk中native实现方案,将动态层容器桥接到原生的h5容器(可以理解成webView)。
PlatformView桥接到动态容器层
事实上,我们将动态层容器桥接到native这是远远不够的。我们最需要解决的问题是:容器依赖的能力注入。
容器依赖能力就是h5互动组件通过jsBridge,获取到原生native运行时环境数据能力。
原先直播sdk中将apiBridge能力设计成全局单例,这在feed流的直播场景下存在一定隐患。例如从第一个直播间将滑到第二个直播间过程中,可能同时存在两个native容器向apiBridge拿数据。如果这个数据是全局公用的,那没问题。但是有个apiBridge方法是获取当前直播间详情数据(getLiveDetailData),这必然造成有个直播间拿到的数据不正确。
因此我们在设计API Bridge的时候,采用多实例方案。每个直播间分配一个bridge实例(并不耗内存),同时为每个直播间建立一个单独的methdChannel,native容器和bridge单独走这个通道进行通信。这样便能彻底解决上面消息的隐患问题(下图左)。
我们将apidBridge逻辑彻底flutter化的同时,也提供了动态注册api Bridge的能力,不需要修改native侧代码(上图右)。目前互动层容器已随flutter直播间上线并且经历了双十一的考验。目前线上运行的h5组件包括红包组件,拍卖组件,更多直播组件等。
当然我们在实践的过程也遇到很多坑:
直播场景下小窗播放并不是什么新鲜事情。当从直播页面切到后台,屏幕上会显示另外一个小窗显示直播画面。android平台下,实现原理是通过windowManager将渲染层view add到window中去。
我们在实现第一版小窗播放的时候,是通过新起一个播放器的方式将画面渲染到一个window 的SurfaceView中,由于加载耗时的影响,这会造成播放不连贯。
我们做了进一步的优化,复用原来的直播播放器,切换渲染层surface。将原来的外接纹理surface进行detach,attach小窗surface。这样视频流并没有中断,只是切换了渲染层,做到了真正的无缝切换效果。
直播间存各种各样消息需要传递,可靠的底层消息通道至关重要。我们需要抽离出单独的消息模块便于业务复用。消息模块flutter化,抹平端差异。考虑到直播有相当成熟的消息中间件,我们讲消息模块做成单独的插件,上层提供统一的消息处理接口。
其中消息传递免不了native和dart层通信。考虑到消息有两大类型:控制类和数据类,我们采用了双管道通信,其中控制消息类采用methodChannel(基于方法粒度);native层产生的数据消息采用eventChannel通知到flutter层(频繁通信,单向)。
设计之初我们想做的是一个“直播场”,任何直播源都能接入进来。比如接入淘宝直播,优酷直播,或者闲鱼自己的直播等等。但是不同来源的直播就会面临数据协议不同,UI样式也无法统一的难题。因此保留组件动态替换能力是非常有必要的。
常见做法是站在组件UI的角度,UI雏形下拥有一定的定制能力,由子类覆写。比如组件种icon图标的定制,图标点击事件处理等等。这种继承方式会牺牲一定的灵活性,定制化能力不够强。
而我们站在直播能力的角度,为每个组件赋予不同能力,通过组合的方式进行组装,这样灵活性会更强。
目前闲鱼直播间大致划分成上面几个组件:LivePage/LiveCell/LiveInteractive/LivePlayer/LiveComment等。每个组件会承担一定能力角色,具体分工如下:
不同组件之间难免会有数据进行共享和通信,这样会造成一定的耦合。为了最大程度的降低这种耦合,这边基于轻量级的Knight框架进行通信,其基本原理仍然采用观察者模式。比如:LivePage作为直播间详情数据提供者,它会将共享数据声明出去(declare),使用方(LiveCell/LiveInteractive)回通过require方法进行订阅。当共享数据源发生变化,会通知到使用方。
目前新版直播间在7.2.40版本已经全量上线,总版本uv占比达到九成以上,暂无线上舆情问题
经历了双十一流量峰值考验,线上红包问题取得超预期效果间,给直播间用户增长带来很大促进作用。
这篇文章系统讲述了我们闲鱼创新小组在flutter直播化所做的一些努力,希望能给大家带来一些启发和收获。未来我们还有许多工作需要进一步探索:1 PlatformView 兼容性问题需要解决,以及相关内存流畅度优化 2 做一款真正意义上的flutter播放器,将编解码数据直接对接到flutter层,实现真正意义上的跨平台。道阻且长,行则将至,行而不辍,则未来可期。
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。