android文件上傳優(yōu)化分享

主題

記錄安卓端上傳模塊優(yōu)化的經(jīng)歷。通過本次分享迎罗,咱們可以知道

  1. 一個文件經(jīng)歷了幾個步驟才能從手機(jī)上傳到服務(wù)端
  2. 能知道媒體文件壓縮的原理

圖片壓縮源碼https://github.com/Curzibn/Luban
視頻壓縮源碼https://github.com/fishwjy/VideoCompressor

整個優(yōu)化經(jīng)歷了兩個階段

  1. 第一階段是上傳模塊重構(gòu),并且通過UI和數(shù)據(jù)的分離洼畅,提升了擴(kuò)展性坯临,逐步被運(yùn)用到產(chǎn)品的各個模塊中
  2. 第二階段是上傳尺寸的優(yōu)化,通過對視頻文件的壓縮坟岔,大幅減少用戶的上傳等待時間。

chapter 1.上傳框架重構(gòu)

評估現(xiàn)有模塊表現(xiàn)
  1. 使用中低配置手機(jī)運(yùn)行apk摔桦,查看上傳模塊實(shí)際表現(xiàn)
  2. 使用Charles抓包工具社付,觀察每個上傳文件體積是否被壓縮到合理范圍、對上傳模塊發(fā)送的http請求按照功能對其分類,檢查是否可以合并同類請求
  3. 退出上傳鸥咖,查看上傳后續(xù)步驟是否被停止燕鸽;大文件重新上傳是否跳過已上傳的數(shù)據(jù)塊
  4. 查看上傳后的結(jié)果是否正常播放、是否失真啼辣、音頻異常
上傳模塊現(xiàn)存問題
  • UI和上傳代碼耦合在一起啊研,難以拓展維護(hù)
  • 停止上傳后仍然繼續(xù)上傳,說明流程控制有問題
  • 在上傳時熙兔,對每個文件會進(jìn)行尺寸壓縮悲伶、計算md5值艾恼,比較費(fèi)時
  • 每個文件上傳前都會發(fā)送一次存在校驗(yàn)(根據(jù)文件md5值)住涉,導(dǎo)致在上傳的場景中會發(fā)送多次http請求校驗(yàn)文件存在
  • 視頻文件沒有做壓縮,導(dǎo)致上傳費(fèi)時
整體設(shè)計思路
上傳設(shè)計思路.png
  1. 數(shù)據(jù)UI分離:使用觀察模式钠绍,抽離UI部分代碼舆声。使用弱引用設(shè)置觀察者,避免生命周期不一致引起的內(nèi)存泄漏柳爽。
  2. 費(fèi)時操作前置:在選擇圖片的步驟媳握,開啟異步線程壓縮圖片、計算md5磷脯,將費(fèi)時操作提前處理掉(此步驟在mx4 pro上處理拍照的圖片耗時100~200ms蛾找,基本上選擇圖片后就已經(jīng)完成好了計算)
  3. 將文件上傳成功的md5值保存在內(nèi)存中,避免重復(fù)處理赵誓。
  4. 分次請求合并:向服務(wù)端開發(fā)者申請批校驗(yàn)的接口打毛,將多個文件存在的http請求被合并成一個。
優(yōu)化后 邏輯UML
上傳步驟.png

文件切片

文件切片將一個大文件切成若干小文件進(jìn)行上傳俩功,在上傳失敗的情況下幻枉,可以跳過已上傳的小文件。
切片代碼底層使用JDK的RandomAccessFile對文件提供數(shù)據(jù)讀取
經(jīng)測試诡蜓,上傳的瓶頸在于上行帶寬熬甫,所以切片、上傳時單線程任務(wù)蔓罚,不會出現(xiàn)10個切片一起上傳的情況椿肩。
切片目前設(shè)定為10MB一片,上傳時豺谈,把當(dāng)前的塊的數(shù)據(jù)讀取到內(nèi)存中進(jìn)行上傳

切片步驟
  1. 對文件md5計算郑象,向服務(wù)端校驗(yàn)文件是否已存在,是則提前結(jié)束
  2. 對文件進(jìn)行切片核无,計算每片的md5值用于校驗(yàn)是否已上傳扣唱。比如38mb的視頻,限定每片最大10mb,切出4片噪沙,最后一片8mb炼彪,其余10mb。
                    FileChannel fc = new RandomAccessFile(mSourceFile, "r").getChannel();
                    MappedByteBuffer byteBuffer;

                    for (int i = 0; i < mBlockCount; i++) {
                        long leftBlockSize = Math.min(mSourceFile.length() - i * mBlockSize, mBlockSize);
                        byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, i * mBlockSize, leftBlockSize).load();
                        mResultArray.add(new BlockInfoModel("", MD5Util.md5(byteBuffer), i));
                    }
                    fc.close();
  1. 批校驗(yàn)文件的切片md5值正歼, 記錄沒有被上傳過的切片下標(biāo)辐马,循環(huán)從源文件讀取對應(yīng)數(shù)據(jù)切片進(jìn)行上傳。切片數(shù)據(jù)流讀到內(nèi)存中性能最佳局义,但是需要謹(jǐn)慎考慮OOM問題喜爷;數(shù)據(jù)流保存到磁盤中,再循環(huán)每次1MB的讀取比較穩(wěn)健萄唇,但是性能稍差檩帐。本次重構(gòu)提供了這兩種切片方式都可以選擇
  2. 所有數(shù)據(jù)切片上傳成功后,向服務(wù)端發(fā)起一次文件合并請求另萤,成功則結(jié)束湃密,否則跳到步驟3。

chapter 2.媒體壓縮

對于媒體資源來說四敞,壓縮就是在保證用戶體驗(yàn)的情況下泛源,盡可能地抹去用戶感官之外的細(xì)節(jié),達(dá)到降低文件尺寸的目的
1.音頻的無損格式ape忿危、flv 壓縮到有損格式的Mp3达箍,就是抹去了人聽覺之外的音頻細(xì)節(jié)
2.圖片視頻經(jīng)過壓縮,雖然放大N倍看細(xì)節(jié)會變得模糊铺厨,但是正常瀏覽下是可以接受的

舉個例子
針對 1920*1080的屏幕截圖缎玫,經(jīng)過壓縮后尺寸不變,但是降低采樣率努释,文件體積從1MB降低到了200KB


圖片壓縮.png

壓縮前.png
壓縮后.png

圖片壓縮

壓縮算法參考魯班
通過等比例降低圖片的采樣率碘梢、分辨率、壓縮質(zhì)量等關(guān)鍵因素伐蒂,大幅度減少輸出的像素點(diǎn)數(shù)量煞躬,達(dá)到降低圖片的體積的目的
在不影響瀏覽體驗(yàn)的前提下,能很大比例壓縮圖片體積

魯班跑分.png

視頻壓縮

通過降低視頻的分辨率逸邦、碼率等關(guān)鍵因素恩沛,降低視頻的體積。
壓縮方案可選1:第三方so庫FFmpeg軟解 2:使用安卓原生MediaCodec 硬解
因?yàn)閴嚎s效率缕减、引入體積等問題雷客,我們選擇了MediaCodec方案
我們采用的壓縮策略是分辨率450*800,碼率是1.5M

視頻壓縮UML.png

在選擇微信作為對比標(biāo)桿的情況下桥狡,我們達(dá)到了這個標(biāo)準(zhǔn)

壓縮結(jié)果.png

視頻壓縮UI

視頻壓縮1.png
視頻上傳1.png

總結(jié)

通過這兩個階段的重構(gòu)搅裙,安卓端的上傳模塊初步形成了一個完整的體系皱卓,能夠滿足產(chǎn)品的使用需求,被廣泛的應(yīng)用到各個產(chǎn)品線的業(yè)務(wù)模塊中部逮。

備注

碼率
碼率是數(shù)據(jù)傳輸時單位時間傳送的數(shù)據(jù)位數(shù),一般我們用的單位是kbps即千位每秒娜汁。
通俗一點(diǎn)的理解就是取樣率,單位時間內(nèi)取樣率越大兄朋,精度就越高掐禁,處理出來的文件就越接近原始文件
1920x1080分辨率的視頻,碼率應(yīng)該在8Mb以上颅和。
1080x720的分辨率傅事,應(yīng)該在5Mb左右
720x576分辨率,應(yīng)該在3Mb左右
640x480分辨率峡扩,應(yīng)該在1.5Mb左右
320x240的分辨率蹭越,應(yīng)該在600Kb左右。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末有额,一起剝皮案震驚了整個濱河市般又,隨后出現(xiàn)的幾起案子彼绷,更是在濱河造成了極大的恐慌巍佑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寄悯,死亡現(xiàn)場離奇詭異萤衰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)猜旬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門脆栋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洒擦,你說我怎么就攤上這事椿争。” “怎么了熟嫩?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵秦踪,是天一觀的道長。 經(jīng)常有香客問我掸茅,道長椅邓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任昧狮,我火速辦了婚禮景馁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逗鸣。我一直安慰自己合住,他們只是感情好绰精,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著透葛,像睡著了一般茬底。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上获洲,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天阱表,我揣著相機(jī)與錄音,去河邊找鬼贡珊。 笑死最爬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的门岔。 我是一名探鬼主播爱致,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼寒随!你這毒婦竟也來了糠悯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤妻往,失蹤者是張志新(化名)和其女友劉穎互艾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讯泣,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纫普,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了好渠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昨稼。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拳锚,靈堂內(nèi)的尸體忽然破棺而出假栓,到底是詐尸還是另有隱情,我是刑警寧澤霍掺,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布匾荆,位于F島的核電站,受9級特大地震影響抗楔,放射性物質(zhì)發(fā)生泄漏棋凳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一连躏、第九天 我趴在偏房一處隱蔽的房頂上張望剩岳。 院中可真熱鬧,春花似錦入热、人聲如沸拍棕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绰播。三九已至骄噪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蠢箩,已是汗流浹背链蕊。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谬泌,地道東北人滔韵。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像掌实,于是被迫代替她去往敵國和親陪蜻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容