flutter體積優(yōu)化,flutter 持久化

flutter圖片內(nèi)存優(yōu)化

按照給定尺寸進(jìn)行圖片的解碼,而不是解碼整個(gè)圖片的尺寸,用來(lái)減少內(nèi)存的占用。

成都創(chuàng)新互聯(lián)是一家專(zhuān)注于成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)與策劃設(shè)計(jì),川匯網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:川匯等地區(qū)。川匯做網(wǎng)站價(jià)格咨詢(xún):13518219792

官方文檔:

官方說(shuō)明:

Instructs Flutter to decode the image at the specified dimensions instead of at its native size.

This allows finer control of the size of the image in ImageCache and is generally used to reduce the memory footprint of ImageCache .

The decoded image may still be displayed at sizes other than the cached size provided here.

使用:

三方庫(kù): cached_network_image 限2.5.0之后版本才可用

設(shè)定最大的緩存寬度和高度 this.maxWidthDiskCache 、 this.maxHeightDiskCache

使用:

從相冊(cè)選取圖片,展示時(shí)使用指定尺寸寬高進(jìn)行處理。

使用三方庫(kù):

使用自定義 provider 來(lái)指定所需圖片的寬高:

AssetEntityImageProvider 傳入寬高和圖片原圖 AssetEntity 數(shù)據(jù)。

provider 中 key.entity.thumbDataWithSize 方法:

進(jìn)入 entity 中 thumbDataWithSize 方法:

進(jìn)入 _getThumbDataWithId 方法中,

進(jìn)入getThumb:

調(diào)用iOS原生的獲取圖片方法,

進(jìn)入 getThumbWithId 方法,

原生實(shí)現(xiàn)獲取置頂寬高縮略圖方法實(shí)現(xiàn):

使用 iOS 原生類(lèi) PHImageManager 的

來(lái)獲取縮略圖。

為什么Flutter開(kāi)發(fā)APP性能最接近原生,前端程序員請(qǐng)關(guān)注

Flutter是谷歌公司推出的跨終端的開(kāi)發(fā)框架,支持Android、iOS和WEB終端。1.0版在2018年12月5日發(fā)布,目前的最新版本是1.5,它采用的開(kāi)發(fā)語(yǔ)言是Dart,Dart也是谷歌開(kāi)發(fā)的計(jì)算機(jī)編程語(yǔ)言,語(yǔ)法類(lèi)似C,是編譯型語(yǔ)言:

hello world例子,打印字符串“Hello World!”:

1、沒(méi)有橋接層

React Native、Weex等技術(shù)都是跨終端的框架,然而性能跟原生App存在很大差距。這是由于它們的工作原理決定的:

React Native、Weex等技術(shù)多了一個(gè)橋接層,所以界面渲染會(huì)慢一些,由于UI渲染非常頻繁,想要不卡頓,基本上比較難,性能和用戶(hù)體驗(yàn)跟原生代碼有差距。而這恰恰是Flutter的優(yōu)勢(shì)所在:

Dart可以被編譯成不同平臺(tái)的本地代碼,讓Flutter不通過(guò)橋接層直接跟平臺(tái)通信,自然性能會(huì)快一些。

2、編譯執(zhí)行

JavaScript是解釋執(zhí)行的,Dart是編譯執(zhí)行的,性能誰(shuí)好一目了然。

3、Flutter Engine虛擬機(jī)

Flutter是依靠Flutter Engine虛擬機(jī)在iOS和Android上運(yùn)行的,F(xiàn)lutter Engine使用C/C++編寫(xiě),開(kāi)發(fā)人員通過(guò)Flutter框架直接和API在內(nèi)部進(jìn)行交互,所以具有輸入低延遲和UI渲染高幀速率的特點(diǎn)。除了這特點(diǎn)之外,F(xiàn)lutter還提供了自己的小部件,F(xiàn)lutter小部件是使用從React獲取靈感的現(xiàn)代框架構(gòu)建的。 中心思想是您使用小部件構(gòu)建UI。

窗口小部件根據(jù)其當(dāng)前配置和狀態(tài)描述了它們的視圖。 當(dāng)窗口小部件的狀態(tài)發(fā)生更改時(shí),窗口小部件會(huì)重建其描述,框架將根據(jù)前面的描述進(jìn)行區(qū)分,以確定底層呈現(xiàn)樹(shù)從一個(gè)狀態(tài)轉(zhuǎn)換到下一個(gè)狀態(tài)所需的最小更改??梢灾苯釉贠S平臺(tái)提供的畫(huà)布上進(jìn)行描繪,也就是一些核心類(lèi)庫(kù)直接放到虛擬機(jī)里面,調(diào)用起來(lái)更快。

從它的系統(tǒng)結(jié)構(gòu)可以看出,類(lèi)似安卓的ART(Android Run Time)虛擬機(jī),同樣采用AOT(Ahead of TIme)技術(shù),會(huì)在APP安裝時(shí)就編譯成機(jī)器語(yǔ)言,不再解釋執(zhí)行,從而優(yōu)化了APP運(yùn)行的性能。

4、自帶渲染引擎

Flutter使用谷歌自己的Skia渲染引擎,而Android系統(tǒng)自帶Skia引擎,iOS平臺(tái)上Flutter也會(huì)把Skia引擎打包到APP中,從而實(shí)現(xiàn)了高效渲染。而React Native通過(guò)橋接層訪(fǎng)問(wèn)原生UI,操作頻繁就容易出性能問(wèn)題。

綜合所述,F(xiàn)lutter 是性能最接近原生代碼 的一種開(kāi)發(fā)框架,未來(lái)也會(huì)是構(gòu)建谷歌Fuchsia應(yīng)用的主要方式,前途不可限量,唯一的問(wèn)題就是需要學(xué)習(xí)一門(mén)新的語(yǔ)言:Dart,而有Java或者C#語(yǔ)言基礎(chǔ)的程序員會(huì)比較容易學(xué)習(xí)。

flutter引入第三方插件報(bào)錯(cuò)xxx-Swift.h file not found解決辦法及原因

問(wèn)題算是解決了,但是為什么會(huì)這樣呢,我們習(xí)以為常的use_frameworks!有什么作用呢,知其然也要知其所以然,帶著疑問(wèn)我進(jìn)行了下一步的探索 。

首先我們要了解下靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)還有Framework。

靜態(tài)庫(kù):(.a)在編譯時(shí)會(huì)將庫(kù)copy一份到目標(biāo)程序中,編譯完成之后,目標(biāo)程序不依賴(lài)外部的庫(kù),也可以運(yùn)行。缺點(diǎn): 會(huì)使應(yīng)用程序變大。

動(dòng)態(tài)庫(kù):(.dylib)編譯時(shí)只存儲(chǔ)了指向動(dòng)態(tài)庫(kù)的引用。可以多個(gè)程序指向這個(gè)庫(kù),在運(yùn)行時(shí)才加載,不會(huì)使應(yīng)用體積變大,但是運(yùn)行時(shí)加載會(huì)損耗部分性能,并且依賴(lài)外部的環(huán)境,如果庫(kù)不存在或者版本不正確則無(wú)法運(yùn)行(我的項(xiàng)目無(wú)法運(yùn)行就是這一步出問(wèn)題了)。

Framework:實(shí)際上是一種打包方式,將庫(kù)的二進(jìn)制文件,頭文件和有關(guān)的資源文件打包到一起,方便管理和分發(fā)。

CocoaPods 通過(guò)use_frameworks來(lái)控制是否是用Framework。

如果不使用use_frameworks!則會(huì)使用static libraries 方式生成.a文件。

如果使用use_frameworks!則會(huì)使用dynamic frameworks 方式生成.framework文件。

在純oc的項(xiàng)目中,一般不使用frameworks,但是在pod導(dǎo)入的swift項(xiàng)目,必須要使用use_frameworks!,我這個(gè)flutter項(xiàng)目也是用pod導(dǎo)入的第三方庫(kù),所以必須加入use_frameworks!,特此記錄下,免得以后踩同樣的坑!

Flutter動(dòng)態(tài)化方案調(diào)研

騰訊課堂14M

今日頭條3M

閑魚(yú)22M

百度貼吧13M

螞蟻財(cái)富56.8M

百度網(wǎng)盤(pán)14M

手機(jī)淘寶15M

貝殼找房8M

由粗粒度小組件動(dòng)態(tài)拼裝出頁(yè)面,Native端已經(jīng)有很多成熟的框架,如天貓的Tangram。

開(kāi)發(fā)語(yǔ)言:iOS、Android

適用場(chǎng)景:快速迭代的活動(dòng)營(yíng)銷(xiāo)頁(yè)面

優(yōu)點(diǎn):無(wú)侵入,更新簡(jiǎn)單

缺點(diǎn):提前預(yù)埋,擴(kuò)展性差,靈活性差

以webview作為容器的app,歷史悠久,最早到2011年。

開(kāi)發(fā)語(yǔ)言:HTML

適用場(chǎng)景:雙端嚴(yán)格一致的銀行類(lèi)app,容器類(lèi)的支付寶小程序等

優(yōu)點(diǎn):動(dòng)態(tài)更新,跨平臺(tái)

缺點(diǎn):性能,加載速度

UI用Xml+JS表達(dá),用Native View渲染。

開(kāi)發(fā)語(yǔ)言:Xml+JS

適用場(chǎng)景:雙端嚴(yán)格一致的銀行類(lèi)app,容器類(lèi)的支付寶小程序等

優(yōu)點(diǎn):native組件,生態(tài)成熟

缺點(diǎn):三方庫(kù)crash,性能缺陷

UI用Dart表達(dá),用Dart engine渲染。

Flutter官方不支持動(dòng)態(tài)化。原因是Flutter在 Release 模式下構(gòu)建的是 AOT 編譯產(chǎn)物,在 Debug 模式下構(gòu)建的是 JIT ,AOT 依賴(lài)的 Dart VM 和 JIT 并不一樣, JIT Release 并不支持 iOS 設(shè)備??尚械姆桨甘牵篈OT 需要一個(gè)編譯后的 “Dart VM”。抽離一份 DartVM 獨(dú)立編譯,再以動(dòng)態(tài)庫(kù)的形式引入項(xiàng)目。

開(kāi)發(fā)語(yǔ)言:Dart

適用場(chǎng)景:iOS、Android、Web、Desktop、Embed

優(yōu)點(diǎn):性能最佳

缺點(diǎn):增大包體積 20MB+

大廠(chǎng)的主流方案。UI用JS表達(dá),用Dart engine渲染。

開(kāi)發(fā)語(yǔ)言:JS、類(lèi)JS

適用場(chǎng)景:iOS、Android

優(yōu)點(diǎn):性能最佳

缺點(diǎn):需要掌握J(rèn)S、Dart兩個(gè)語(yǔ)言和框架

大廠(chǎng)的主流方案。UI用Dart表達(dá),用Dart engineX渲染。

開(kāi)發(fā)語(yǔ)言:Dart

適用場(chǎng)景:iOS、Android

優(yōu)點(diǎn):性能最佳

缺點(diǎn):需要改造Dart engine

1、 美團(tuán)外賣(mài)Flutter動(dòng)態(tài)化實(shí)踐

2、 攜程App 首頁(yè)動(dòng)態(tài)化探索

3、 Flutter 動(dòng)態(tài)化在最右 App 中的實(shí)踐

4、 Flutter 動(dòng)態(tài)化熱更新的思考與實(shí)踐

5、 NOW直播Flutter動(dòng)態(tài)搜索列表頁(yè)實(shí)現(xiàn)

6、 Flutter動(dòng)態(tài)化的方案對(duì)比及最佳實(shí)現(xiàn)-閑魚(yú)

7、 基于JavaScript 的MXFlutter

flutter 常見(jiàn)問(wèn)題之a(chǎn)pp體積為何比較大

細(xì)心的開(kāi)發(fā)者會(huì)發(fā)現(xiàn)flutter構(gòu)建的App體積比native的大一些,是什么原因造成App體積大呢?

其實(shí)flutter 在release時(shí)App體積和native的大小差不多,而debug時(shí)體積通常會(huì)大。debug版本體積較大是為了Hot reload和快速編譯。如果有flutter開(kāi)發(fā)經(jīng)驗(yàn)的朋友都體驗(yàn)過(guò),如果您修改一下App的背景顏色,只需save一下就可以立刻看到修改后效果。我稱(chēng)之為“像藝術(shù)家一樣在創(chuàng)造App”,因此為了實(shí)現(xiàn)這些目標(biāo),提高開(kāi)發(fā)的效率,debug將占用全部資源。而當(dāng)我們構(gòu)建release版時(shí),flutter又會(huì)采用AOT策略,提高App運(yùn)行效率,release版只打包必需的資源,因而體積又會(huì)減少。

另外,flutter團(tuán)隊(duì)也一直在尋找減小程序大小的方法。

Flutter浪潮下的音視頻研發(fā)探索

文/陳爐軍

整理/LiveVideoStack

大家好,我是阿里巴巴閑魚(yú)事業(yè)部的陳爐軍,本次分享的主題是Flutter浪潮下的音視頻研發(fā)探索,主要內(nèi)容是針對(duì)閑魚(yú)APP在當(dāng)下流行的跨平臺(tái)框架Flutter的大規(guī)模實(shí)踐,介紹其在音視頻領(lǐng)域碰到的一些困難以及解決方案。

分享內(nèi)容主要分為四個(gè)方面,首先會(huì)對(duì)Flutter有一個(gè)簡(jiǎn)單介紹以及選擇Flutter作為跨平臺(tái)框架的原因,其次會(huì)介紹Flutter中與音視頻關(guān)系非常大的外接紋理概念,以及對(duì)它做出的一些優(yōu)化。之后會(huì)對(duì)閑魚(yú)在音視頻實(shí)踐過(guò)程中碰到的一些Flutter問(wèn)題提出了一些解決方案——TPM音視頻框架。最后是閑魚(yú)Flutter多媒體開(kāi)源組件的介紹。

Flutter

Flutter是一個(gè)跨平臺(tái)框架,以往的做法是將音頻、視頻和網(wǎng)絡(luò)這些模塊都下沉到C++層或者ARM層,在其上封裝成一個(gè)音視頻的SDK,供UI層的PC、iOS和Android調(diào)用。

而Flutter做為一個(gè)UI層的跨平臺(tái)框架,顧名思義就是在UI層也實(shí)現(xiàn)了一個(gè)跨平臺(tái)開(kāi)發(fā)??梢灶A(yù)想的是未Flutter發(fā)展的好的話(huà),會(huì)逐漸變?yōu)橐粋€(gè)從底層到UI層的一個(gè)全鏈路的跨平臺(tái)開(kāi)發(fā),技術(shù)人員分別負(fù)責(zé)SDK和UI層的開(kāi)發(fā)。

在Flutter之前已經(jīng)有很多跨平臺(tái)UI解決方案,那為什么選擇Flutter呢?

我們主要考慮性能和跨平臺(tái)的能力。

以往的跨平臺(tái)方案比如Weex,ReactNative,Cordova等等因?yàn)榧軜?gòu)的原因無(wú)法滿(mǎn)足性能要求,尤其是在音視頻這種性能要求幾乎苛刻的場(chǎng)景。

而諸如Xamarin等,雖然性能可以和原生App一致,但是大部分邏輯還是需要分平臺(tái)實(shí)現(xiàn)。

我們可以看一下,為什么Flutter可以實(shí)現(xiàn)高性能:

原生的native組件渲染以IOS為例,蘋(píng)果的UIKit通過(guò)調(diào)用平臺(tái)自己的繪制框架QuaztCore來(lái)實(shí)現(xiàn)UI的繪制,圖形繪制也是調(diào)用底層的API,比如OpenGL、Metal等。

而Flutter也是和原生API邏輯一致,也是通過(guò)調(diào)用底層的繪制框架層SKIA實(shí)現(xiàn)UI層。這樣相當(dāng)于Flutter他自己實(shí)現(xiàn)了一套UI框架,提供了一種性能超越原生API的跨平臺(tái)可能性。

但是我們說(shuō)一個(gè)框架最終性能怎樣,其實(shí)取決于設(shè)計(jì)者和開(kāi)發(fā)者。至于現(xiàn)在到底是一個(gè)什么狀況:

在閑魚(yú)的實(shí)踐中,我們發(fā)現(xiàn)在正常的開(kāi)發(fā)沒(méi)有特意的去優(yōu)化UI代碼的情況下,在一些低端機(jī)上,F(xiàn)lutter界面的流暢性是比Native界面要好的。

雖然現(xiàn)在閑魚(yú)某些場(chǎng)景下會(huì)有卡頓閃退等情況,但是這是一個(gè)新事物發(fā)展過(guò)程中的必然問(wèn)題,我們相信未來(lái)性能肯定不會(huì)成為限制Flutter發(fā)展的瓶頸的。

在閑魚(yú)實(shí)踐Flutter的過(guò)程中,混合棧和音視頻是其中比較難解決的兩個(gè)問(wèn)題,混合棧是指一個(gè)APP在Flutter過(guò)程中不可能一口氣將所有業(yè)務(wù)全部重寫(xiě)為Flutter,所以這是一個(gè)逐步迭代的過(guò)程,這期間原生native界面與Flutter界面共存的狀態(tài)就稱(chēng)之為混合棧。閑魚(yú)在混合棧上也有一些比較好的輸出,例如FlutterBoost。

外接紋理

在講音視頻之前需要簡(jiǎn)要介紹一下外接紋理的概念,我們將它稱(chēng)之為是Flutter和Frame之間的橋梁。

Flutter渲染一幀屏幕數(shù)據(jù)首先要做的是,GPU發(fā)出的VC信號(hào)在Flutter的UI線(xiàn)程,通過(guò)AOT編譯的機(jī)器碼結(jié)合當(dāng)前Dart Runtime,生成Layer Tree UI樹(shù),Layer Tree上每一個(gè)葉子節(jié)點(diǎn)都代表了當(dāng)前屏幕上所需要渲染的每一個(gè)元素,包含了這些元素渲染所需要的內(nèi)容。將Layer Tree拋給GPU線(xiàn)程,在GPU線(xiàn)程內(nèi)調(diào)用Skia去完成整個(gè)UI的渲染過(guò)程。Layer Tree中有PictureLayer和TextureLayer兩個(gè)比較重要的節(jié)點(diǎn)。PictureLayer主要負(fù)責(zé)屏幕圖片的渲染,F(xiàn)lutter內(nèi)部實(shí)現(xiàn)了一套圖片解碼邏輯,在IO線(xiàn)程將圖片讀取或者從網(wǎng)絡(luò)上拉取之后,通過(guò)解碼能夠在IO線(xiàn)程上加載出紋理,交給GPU線(xiàn)程將圖片渲染到屏幕上。但是由于音視頻場(chǎng)景下系統(tǒng)API太過(guò)繁多,業(yè)務(wù)場(chǎng)景過(guò)于復(fù)雜。Flutter沒(méi)有一套邏輯去實(shí)現(xiàn)跨平臺(tái)的音視頻組件,所以說(shuō)Flutter提出了一種讓第三方開(kāi)發(fā)者來(lái)實(shí)現(xiàn)音視頻組件的方式,而這些音視頻組件的視頻渲染出口,就是TextureLayer。

在整個(gè)Layer Tree渲染的過(guò)程中,TextureLayer的數(shù)據(jù)紋理需要由外部第三方開(kāi)發(fā)者來(lái)指定,可以把視頻數(shù)據(jù)和播放器數(shù)據(jù)送到TextureLayer里,由Flutter將這些數(shù)據(jù)渲染出來(lái)。

TextureLayer渲染過(guò)程:首先判斷Layer是否已經(jīng)初始化,如果沒(méi)有就創(chuàng)建一個(gè)Texture,然后將Texture Attach到一個(gè)SufaceTexture上。

這個(gè)SufaceTexture是音視頻的native代碼可以獲取到的對(duì)象,通過(guò)這個(gè)對(duì)象創(chuàng)建的Suface,我們可以將視頻數(shù)據(jù)、攝像頭數(shù)據(jù)解碼放到Suface中,然后Flutter端通過(guò)監(jiān)聽(tīng)SufaceTexture的數(shù)據(jù)更新就可以順利把剛才創(chuàng)建的數(shù)據(jù)更新到它的紋理中,然后再將紋理交給SKIA渲染到屏幕上。

然而我們?nèi)绻枰肍lutter實(shí)現(xiàn)美顏,濾鏡,人臉貼圖等等功能,就需要將視頻數(shù)據(jù)讀取出來(lái),更新到紋理中,再將GPU紋理經(jīng)過(guò)美顏濾鏡處理后生成一個(gè)處理后的紋理。按Flutter提供的現(xiàn)有能力,必須先將紋理中的數(shù)據(jù)從GPU讀出到CPU中,生成Bitmap后再寫(xiě)入Surface中,這樣在Flutter中才能順利的更新到視頻數(shù)據(jù),這樣做對(duì)系統(tǒng)性能的消耗很大。

通過(guò)對(duì)Flutter渲染過(guò)程分析,我們知道Flutter底層需要渲染的數(shù)據(jù)就是GPU紋理,而我們經(jīng)過(guò)美顏濾鏡處理完成以后的結(jié)果也是GPU紋理,如果可以將它直接交給Flutter渲染,那就可以避免GPU-CPU-GPU這樣的無(wú)用循環(huán)。這樣的方法是可行的,但是需要一個(gè)條件,就是OpenGL上下文共享。

OpenGL

在說(shuō)上下文之前,得提到一個(gè)和上線(xiàn)文息息相關(guān)的概念:線(xiàn)程。

Flutter引擎啟動(dòng)后會(huì)啟動(dòng)四個(gè)線(xiàn)程:

第一個(gè)線(xiàn)程是UI線(xiàn)程,這是Flutter自己定義的UI線(xiàn)程,主要負(fù)責(zé)GPU發(fā)出的VSync信號(hào)時(shí)候用當(dāng)前Dart編譯的機(jī)器碼和當(dāng)前運(yùn)行環(huán)境創(chuàng)建出Layer Tree。

還有就是IO線(xiàn)程和GPU線(xiàn)程。和大部分OpenGL處理解決方案中一樣,F(xiàn)lutter也采取一個(gè)線(xiàn)程責(zé)資源加載,一部分負(fù)責(zé)資源渲染這種思路。

兩個(gè)線(xiàn)程之間紋理共享有兩種方式。一種是EGLImage(IOS是 CVOpenGLESTextureCache)。一種是OpenGL Share Context。Flutter通過(guò)Share Context來(lái)實(shí)現(xiàn)紋理共享,將IO線(xiàn)程的Context和GPU線(xiàn)程的Context進(jìn)行Share,放到同一個(gè)Share Group下面,這樣兩個(gè)線(xiàn)程下資源是互相可見(jiàn)可以共享的。

Platform線(xiàn)程是主線(xiàn)程,F(xiàn)lutter中有一個(gè)很奇怪的設(shè)定,GPU線(xiàn)程和主線(xiàn)程共用一個(gè)Context。并且在主線(xiàn)程也有很多OpenGL 操作。

這樣的設(shè)計(jì)會(huì)給音視頻開(kāi)發(fā)帶來(lái)很多問(wèn)題,后面會(huì)詳細(xì)說(shuō)。

音視頻端美顏處理完成的OpenGL紋理能夠讓Flutter直接使用的條件就是Flutter的上下文需要和平臺(tái)音視頻相關(guān)的OpenGL上下文處在一個(gè)Share Group下面。

由于Flutter主線(xiàn)程的Context就是GPU的Context,所以在音視頻端主線(xiàn)程中有一些OpenGL操作的話(huà),很有可能使Flutter整個(gè)OpenGL被破壞掉。所以需要將所有的OpenGL操作都限制在子線(xiàn)程中。

通過(guò)上述這兩個(gè)條件的處理,我們就可以在沒(méi)有增加GPU消耗的前提下實(shí)現(xiàn)美顏和濾鏡等等功能。

TPM

在經(jīng)過(guò)demo驗(yàn)證之后,我們將這個(gè)方案應(yīng)用到閑魚(yú)音視頻組件中,但改造過(guò)程中發(fā)現(xiàn)了一些問(wèn)題。

上圖是攝像頭采集數(shù)據(jù)轉(zhuǎn)換為紋理的一段代碼,其中有兩個(gè)操作:首先是切進(jìn)程,將后面的OpenGL操作都切到cameraQueue中。然后是設(shè)置一次上下文。然后這種限制條件或者說(shuō)是潛規(guī)則往往在開(kāi)發(fā)過(guò)程中容易被忽略的。而這個(gè)條件一旦忽略后果就是出現(xiàn)一些莫名其妙的詭異問(wèn)題極難排查。因此我們就希望能抽象出一套框架,由框架本身實(shí)現(xiàn)線(xiàn)程的切換、上下文和模塊生命周期等的管理,開(kāi)發(fā)者接入框架以后只需要安心實(shí)現(xiàn)自己的算法,而不需要關(guān)心這些潛規(guī)則還有其他一些重復(fù)的邏輯操作。

在引入Flutter之前閑魚(yú)的音視頻架構(gòu)與大部分音視頻邏輯一樣采用分層架構(gòu):

1:底層是一些獨(dú)立模塊

2:SDK層是對(duì)底層模塊的封裝

3:最上層是UI層。

引入Flutter之后,通過(guò)分析各個(gè)模塊的使用場(chǎng)景,我們可以得出一個(gè)假設(shè)或者說(shuō)是抽象:音視頻應(yīng)用在終端上可以歸納為視頻幀解碼之后視頻數(shù)據(jù)幀在各個(gè)模塊之間流動(dòng)的過(guò)程,基于這種假設(shè)去做Flutter音視頻框架的抽象。

咸魚(yú)Flutter多媒體開(kāi)源組件

整個(gè)Flutter音視頻框架抽象分為管線(xiàn)和數(shù)據(jù)的抽象、模塊的抽象、線(xiàn)程統(tǒng)一管理和上下文同一管理四部分。

管線(xiàn),其實(shí)就是視頻幀流動(dòng)的管道。數(shù)據(jù),音視頻中涉及到的數(shù)據(jù)包括紋理、Bit Map以及時(shí)間戳等。結(jié)合現(xiàn)有的應(yīng)用場(chǎng)景我們定義了管線(xiàn)流通數(shù)據(jù)以Texture為主數(shù)據(jù),同時(shí)可以選擇性的添加Bit Map等作為輔助數(shù)據(jù)。這樣的數(shù)據(jù)定義方式,避免重復(fù)的創(chuàng)建和銷(xiāo)毀紋理帶來(lái)的性能開(kāi)銷(xiāo)以及多線(xiàn)程訪(fǎng)問(wèn)紋理帶來(lái)的一些問(wèn)題。也滿(mǎn)足一些特殊模塊對(duì)特殊數(shù)據(jù)的需求。同時(shí)也設(shè)計(jì)了紋理池來(lái)管理管線(xiàn)中的紋理數(shù)據(jù)。

模塊:如果把管線(xiàn)和數(shù)據(jù)比喻成血管和血液,那框架音視頻的場(chǎng)景就可以比喻成器官,我們根據(jù)模塊所在管線(xiàn)的位置抽象出采集、處理和輸出三個(gè)基類(lèi)。這三個(gè)基類(lèi)里實(shí)現(xiàn)了剛才說(shuō)的線(xiàn)程切換,上下文切換,格式轉(zhuǎn)換等等共同邏輯,各個(gè)功能模塊通過(guò)集成自這些基類(lèi),可以避免很多重復(fù)勞動(dòng)。

線(xiàn)程:每一個(gè)模塊初始化的時(shí)候,初始化函數(shù)就會(huì)去線(xiàn)程管理的模塊去獲取自己的線(xiàn)程,線(xiàn)程管理模塊可以決定給初始化函數(shù)分配新的線(xiàn)程或者已經(jīng)分配過(guò)其他模塊的線(xiàn)程。

這樣有三個(gè)好處:

一是可以根據(jù)需要去決定一個(gè)線(xiàn)程可以?huà)燧d多少模塊,做到線(xiàn)程間的負(fù)載均衡。第二,多線(xiàn)程并發(fā)式能夠保證模塊內(nèi)的OpenGL操作是在當(dāng)前線(xiàn)程內(nèi)而不會(huì)跑到主線(xiàn)程去,徹底避免Flutter的OpenGL 環(huán)境被破壞。第三,多線(xiàn)程并行可以充分利用CPU多核架構(gòu),提升處理速度。

從Flutter端修改Flutter引擎將Context取出后,根據(jù)Context創(chuàng)建上下文的統(tǒng)一管理模塊,每一個(gè)模塊在初始化的時(shí)候會(huì)獲取它的線(xiàn)程,獲取之后會(huì)調(diào)用上下文管理模塊獲取自己的上下文。這樣可以保證每一個(gè)模塊的上下文都是與Flutter的上下文進(jìn)行Share的,每個(gè)模塊之間資源都是共享可見(jiàn)的,F(xiàn)lutter和音視頻native之間也是互相共享可見(jiàn)的。

基于上述框架如果要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的場(chǎng)景,比如畫(huà)面實(shí)時(shí)預(yù)覽和濾鏡處理功能,

1:需要選擇功能模塊,功能模塊包括攝像頭模塊、濾鏡處理模塊和Flutter畫(huà)面渲染模塊,

2:需要配置模塊參數(shù),比如采集分辨率、濾鏡參數(shù)和前后攝像頭設(shè)置等,

3:在創(chuàng)建視頻管線(xiàn)后使用已配置的參數(shù)創(chuàng)建模塊

4:最后管線(xiàn)搭載模塊,開(kāi)啟管線(xiàn)就可以實(shí)現(xiàn)這樣簡(jiǎn)單的功能。

上圖為整個(gè)功能實(shí)現(xiàn)的代碼和結(jié)構(gòu)圖。

結(jié)合上述音視頻框架,閑魚(yú)實(shí)現(xiàn)了Flutter多媒體開(kāi)源組件。

組要包含四個(gè)基本組件分別是:

1:視頻圖像拍攝組件

2:播放器組件

3:視頻圖像編輯組件

4:相冊(cè)選擇組件

現(xiàn)在這些組件正在走內(nèi)部開(kāi)源流程。預(yù)計(jì)9月份,相冊(cè)和播放器會(huì)實(shí)現(xiàn)開(kāi)源。

后續(xù)展望和規(guī)劃

1:實(shí)現(xiàn)開(kāi)頭所說(shuō)的從底層SDK到UI的全鏈路的跨端開(kāi)發(fā)。目前底層框架層和模塊層都是各個(gè)平臺(tái)各自實(shí)現(xiàn),反而是Flutter的UI端進(jìn)行了跨平臺(tái)的統(tǒng)一,所以后續(xù)會(huì)將底層也按照音視頻常用做法把邏輯下沉到C++層,盡可能的實(shí)現(xiàn)全鏈路跨平臺(tái)。

2:第二部分內(nèi)容為開(kāi)源共建,閑魚(yú)開(kāi)源的內(nèi)容不僅包括拍攝、編輯組件,還包括了很多底層模塊,希望有開(kāi)發(fā)者在基于Flutter開(kāi)發(fā)音視頻應(yīng)用時(shí)可以充分利用閑魚(yú)開(kāi)源出的音視頻模塊能力,搭建APP框架,開(kāi)發(fā)者只要去負(fù)責(zé)實(shí)現(xiàn)特殊需求模塊就可以,盡可能的減少重復(fù)勞動(dòng)。

當(dāng)前名稱(chēng):flutter體積優(yōu)化,flutter 持久化
本文網(wǎng)址:http://muchs.cn/article12/phijgc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、定制開(kāi)發(fā)、搜索引擎優(yōu)化、企業(yè)建站、Google小程序開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)