我个人是倾向于第一种实现方式的,因为h5本身存在许多兼容性问题,再加上Android本身被各个国产厂商魔改,而且也有h5也有性能问题,h5播放视频也会有卡顿,全屏,手机硬件交互等等问题,总之我是很不推荐第二种方案的。但但但是呢,我们的产品说微博,微信h5播放视频不是挺好的么,视频播放那么流畅,也没有什么卡顿,兼容性问题呢。这我还能说什么呢,产品都坚持了,而且两周一个迭代周期也不允许我有什么可多说的了,只好按照产品的意愿做了撒,况且视频播放器那一套流程,各种状态的控制也挺复杂的,这些问题都交由h5开发的同学去考虑吧。
在确定了由h5进行视频的展示,预览,播放后,就开始寻找我们如何把视频数据传递给h5,按照项目里面已有的h5与原生的交互方案,使用JSBridge进行数据交互,但是数据有大小限制,视频动不动就几十M,即使将视频压缩,也还是不能完全保证能够把数据传递过去;然后就是使用webview的 input_file 机制,调起系统的文件选择器,选择文件,但是缺点是每次只能选择一个文件,而且界面UI不能自定义,这个方案也被放弃了;然后又尝试了把文件转化为二进制流传递给h5,但是发现h5根本无法识别,这种方案又失败了;最后在网上找到一种似乎可行的方案,那就是在本地启动一个本地服务器,然后定义一个文件请求接口,h5调起原生的视频选择控件选择一个视频后,我们把文件路径和本地服务器地址传给h5,然后h5点击预览时就通过这个接口把文件路径传给我,本地服务器在收到请求后,根据文件路径找到文件,然后把文件流返给h5,h5在拿到文件流后进行视频的播放。这种方案看来可行,而且也有成功的案例,比如局域网投屏和文件传输都是用的这种方案。
在确定了使用本地服务器实现文件传输方案后,就要着手实现了。由于之前没有做过而且项目时间比较紧,就在全球最大的同性交友网站上找寻找看有没有比较优秀的开源库,最后找到了几个比较好的三方库,经过比较选择了 AndServer ,根据说明文档就开始开发。首先,通过gradle方式引进项目
然后对项目进行简单的封装,也方便后续进行方案的替换
先实现一个Service,对服务进行启动和停止的控制
Service静态注册
NetUtils是一个工具类,主要是获取本地的IP地址
这里说一下我为什么要绑定127.0.0.1的本地地址,因为我们项目中有缓存机制,选择的视频在切换网络过后还要求能够预览,如果绑定动态分配的ip地址,那么在切换网络过后,可能会造成ip地址发生变化,之前h5选择的资源文件会无法预览,如果我们绑定127.0.0.1,无论是切换网络还是完全关闭网络,都可以访问到之前选择的文件资源(只要本地文件没有删除),并且只有在本应用内才能够访问到,安全性提高。
接下来就是ServerManager,AndServer的全局控制类
本地服务状态监听接口类定义
最后是文件请求Controler,处理文件请求响应
这里需要注意的一点是,如果你的文件路名含有&特殊字符,那么fileId请求参数就会被自动截断。遇到这种情况,一般有两种处理方式,第一种是使用post请求,把参数放在body中;第二种方式是我们在把文件路径传递给h5之前,我们先进行编码,将特殊字符替换掉,然后我们在收到请求后,去寻找本地文件之前对编码的路径进行还原
最后再对启动入口进行一次封装,对外提供启动服务的入口
然后在你需要使用服务之前,调用initWebServer()启动服务就可以了,需要注意一点的就是,你可能需要全局监听网络变化,网络变化后,你需要重启一次服务才能够访问到资源
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)