工作中,第二个比较独立的项目是一个 IM 聊天应用,我负责 H5 版本的开发,功能比较简单,可以发送文字图片,以及播放原生客户端发来的语音消息。
即时通讯自然要用 websocket,接口也比较简单,主要精力在于理解 websocket 服务相关消息协议上,相关文档乱到让你无法想象,通常没有人会告诉你该怎么做,他们只会扔给你一个链接。
我花了大量时间精力,把一堆文档转换成代码,区区三百行,浪费了很多时间,效率低下,但又不可避免,工作向来如此。如果需要我给同事讲清楚这套协议,最多一上午就明明白白了,不是我自信,而是这真的很简单,我只是做了团队中第一个去踩坑的人。
键盘遮挡输入框
h5 无法控制原生输入法,各种机型对虚拟键盘弹起行为的处理机制不一,我们的测试同学非常贴心,与键盘有关的 bug 各种场景一个个算,一共有十来个,表象其实只有一个:键盘遮挡输入框。
IM 输入框通常都被设计为吸附于底部,虚拟键盘弹起 输入框要随着上移,安卓还好,ios 对 fixed 的处理有点异常,这个问题网上已经有成功的解决方案了,设置一个定时器,不断的去 scrollIntoView
就好了。iphoneX 在虚拟键盘弹起的时候又有了另外的处理机制,只得针对具体机型,具体系统版本做兼容,无非多写几行if else
。
这个 bug,只能尽力兼容,我自认为已经做到很好,心想绝逼能兼容 90%以上的场景,但并没有令测试满意,坐地铁的时候打开手机试试别人家的输入框,想做到完美,这真是个业界难题。
IOS 拍照,照片被旋转
图片预览用到 FileReader
接口,上传进度是 ajax 的onUploadProgress
事件,都没有问题。
这里的兼容性主要在于 ios 拍照,图片会被旋转。解决思路是根据旋转角度,用 canvas 再给转回来就可以了,照片相关信息通过exif-js
这个库可以轻松获取。
语音消息播放
安卓和 ios 客户端最早给的是spx
音频格式,spx
格式比较小,适合大量语音消息的传输,但 h5 audio
标签是无法直接播放spx
格式的,网上大部分都是在服务器端转成 mp3
或者 wav
,h5 直接加载转码后的格式播放,我主要是苦于没有找到浏览器端可解码spx
格式的 js 库,经过沟通,我们抛弃了spx
,采用amr
格式。
github 有可用的解码库对AMR 格式解码,播放则使用强大的 AudioContext
接口,这个接口非常强大,audio 标签显得确实有点太弱了。
这里有个需要注意的问题:android 可以正常播放 amr
文件,主要原因是 amr 文件的采样频率是 8000 ,ios 支持到 20000 多,如果用超过 8000 的频率播放,语音速度会很快,ios 的解决办法是加频率的同时加帧数。当然,如果选择用 mp3 或者 wav,可以天然避免很多问题。
详细代码,撩我。
总结
这篇属于述职里要求的:技术成长与积累,以及典型事件介绍。
说今天满满的全是干货,有点吹牛了,前端踩坑主要在兼容各种设备上,解决兼容性问题其实对编码能力没有多少帮助,也体现不出技术能力,但现状就是这样,工作向来如此。
详细代码,demo 我会整理好上传到 github,有需要的可以一起交流。