android文件上传优化分享

主题

记录安卓端上传模块优化的经历。通过本次分享,咱们可以知道

  1. 一个文件经历了几个步骤才能从手机上传到服务端
  2. 能知道媒体文件压缩的原理

图片压缩源码https://github.com/Curzibn/Luban
视频压缩源码https://github.com/fishwjy/VideoCompressor

整个优化经历了两个阶段

  1. 第一阶段是上传模块重构,并且通过UI和数据的分离,提升了扩展性,逐步被运用到产品的各个模块中
  2. 第二阶段是上传尺寸的优化,通过对视频文件的压缩,大幅减少用户的上传等待时间。

chapter 1.上传框架重构

评估现有模块表现
  1. 使用中低配置手机运行apk,查看上传模块实际表现
  2. 使用Charles抓包工具,观察每个上传文件体积是否被压缩到合理范围、对上传模块发送的http请求按照功能对其分类,检查是否可以合并同类请求
  3. 退出上传,查看上传后续步骤是否被停止;大文件重新上传是否跳过已上传的数据块
  4. 查看上传后的结果是否正常播放、是否失真、音频异常
上传模块现存问题
  • UI和上传代码耦合在一起,难以拓展维护
  • 停止上传后仍然继续上传,说明流程控制有问题
  • 在上传时,对每个文件会进行尺寸压缩、计算md5值,比较费时
  • 每个文件上传前都会发送一次存在校验(根据文件md5值),导致在上传的场景中会发送多次http请求校验文件存在
  • 视频文件没有做压缩,导致上传费时
整体设计思路
上传设计思路.png
  1. 数据UI分离:使用观察模式,抽离UI部分代码。使用弱引用设置观察者,避免生命周期不一致引起的内存泄漏。
  2. 费时操作前置:在选择图片的步骤,开启异步线程压缩图片、计算md5,将费时操作提前处理掉(此步骤在mx4 pro上处理拍照的图片耗时100~200ms,基本上选择图片后就已经完成好了计算)
  3. 将文件上传成功的md5值保存在内存中,避免重复处理。
  4. 分次请求合并:向服务端开发者申请批校验的接口,将多个文件存在的http请求被合并成一个。
优化后 逻辑UML
上传步骤.png

文件切片

文件切片将一个大文件切成若干小文件进行上传,在上传失败的情况下,可以跳过已上传的小文件。
切片代码底层使用JDK的RandomAccessFile对文件提供数据读取
经测试,上传的瓶颈在于上行带宽,所以切片、上传时单线程任务,不会出现10个切片一起上传的情况。
切片目前设定为10MB一片,上传时,把当前的块的数据读取到内存中进行上传

切片步骤
  1. 对文件md5计算,向服务端校验文件是否已存在,是则提前结束
  2. 对文件进行切片,计算每片的md5值用于校验是否已上传。比如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. 批校验文件的切片md5值, 记录没有被上传过的切片下标,循环从源文件读取对应数据切片进行上传。切片数据流读到内存中性能最佳,但是需要谨慎考虑OOM问题;数据流保存到磁盘中,再循环每次1MB的读取比较稳健,但是性能稍差。本次重构提供了这两种切片方式都可以选择
  2. 所有数据切片上传成功后,向服务端发起一次文件合并请求,成功则结束,否则跳到步骤3。

chapter 2.媒体压缩

对于媒体资源来说,压缩就是在保证用户体验的情况下,尽可能地抹去用户感官之外的细节,达到降低文件尺寸的目的
1.音频的无损格式ape、flv 压缩到有损格式的Mp3,就是抹去了人听觉之外的音频细节
2.图片视频经过压缩,虽然放大N倍看细节会变得模糊,但是正常浏览下是可以接受的

举个例子
针对 1920*1080的屏幕截图,经过压缩后尺寸不变,但是降低采样率,文件体积从1MB降低到了200KB


图片压缩.png

压缩前.png
压缩后.png

图片压缩

压缩算法参考鲁班
通过等比例降低图片的采样率、分辨率、压缩质量等关键因素,大幅度减少输出的像素点数量,达到降低图片的体积的目的
在不影响浏览体验的前提下,能很大比例压缩图片体积

鲁班跑分.png

视频压缩

通过降低视频的分辨率、码率等关键因素,降低视频的体积。
压缩方案可选1:第三方so库FFmpeg软解 2:使用安卓原生MediaCodec 硬解
因为压缩效率、引入体积等问题,我们选择了MediaCodec方案
我们采用的压缩策略是分辨率450*800,码率是1.5M

视频压缩UML.png

在选择微信作为对比标杆的情况下,我们达到了这个标准

压缩结果.png

视频压缩UI

视频压缩1.png
视频上传1.png

总结

通过这两个阶段的重构,安卓端的上传模块初步形成了一个完整的体系,能够满足产品的使用需求,被广泛的应用到各个产品线的业务模块中。

备注

码率
码率是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。
通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件
1920x1080分辨率的视频,码率应该在8Mb以上。
1080x720的分辨率,应该在5Mb左右
720x576分辨率,应该在3Mb左右
640x480分辨率,应该在1.5Mb左右
320x240的分辨率,应该在600Kb左右。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容