Home » Code » webview与native交互实现录音功能简要记录

webview与native交互实现录音功能简要记录

近期跟app开发人员联合做这么一个功能,在app内置浏览器上实现HTML网页的录音功能。众所周知,到了HTML5,理论上是可以网页直接访问麦克风实现录音的。但理论终究是理论,HTML5提出的诸多新功能,实际得到广泛应用的又有多少。拿这个录音来说,什么出于用户隐私,有的浏览器是不支持的,或者压根不知道要怎么设置才能访问得到麦克风。就算能访问得到麦克风,也有编码慢支持格式少体积大等等问题,实际使用体验也不理想,这事还得靠native。

首先要解决的是webview中js跟native的通信问题,我不是负责app的,粗略看应该是使用的第三方库,比如,

对于Android: https://github.com/lzyzsd/JsBridge
对于IOS: https://github.com/marcuswestin/WebViewJavascriptBridge

它们的API基本是一致的,估计要做些统一处理,具体不清楚了。使用方法也简单,js和native分别注册好方法,供对方调用就好了。关键的一点,录好的音频数据怎么传出来,互相调用能传的参数基本都是字符串。一开始考虑将音频转换为Binary二进制字符串传递,实测不靠谱,native调用js的方法把这个Binary字符串作为参数根本没有反应。后又考虑转换为更通用一点的base64字符串才可以。

另外一个麻烦点就是格式问题,html播放原生支持的只有mp3和wav及ogg,最适合的当然是mp3,体积较小应用泛大家也都认识,wav太大了,ogg可能游戏里边用得多点。但是,无论是Android还是IOS都不原生支持编码mp3,需要加入第三方库,这就麻烦了,粗略估计app体积得增加1M多。这对上边人的来说是不能接受的,因为这个功能可能不太常用,增加体积是大事,对app的宣传推广等都会增加成本,不能这么搞!那native编码的时候就只能选Android和IOS都原生支持的amr格式,这种格式体积非常小1秒1~2K的大小,录个1分钟也是几十K传输什么的太easy了,声音质量也是OK的,但特么的html5对它压根不认识(W3C的人怎么做事的?),播放分享什么的就极不方便。网上各种方案,什么嵌入苹果quicktime player之类的,拜托,这是在手机网页里边。

试过在js里边进行转码,是有库可以用:https://github.com/jpemartins/amr.js,转为wav,但也只是解决了本地播放的问题,如果远程保存的是amr格式的音频,只有这个远程地址,如果跨域,js拿不到音频数据,根本就谈不上解码了。而且实测,js转码速度真是较慢,用户点了没有播放还延迟个几秒甚至更久什么的,肯定不行。而且,有一个比较严重的问题,Safari在进行转码运算的时候,页面卡住无法滑动,要是耗上将近10秒以上,肯定被用户发现,体验十分不OK。在这里特别说明:对于Android的浏览器,base64之后的amr音频是可以直接播放的,无须转码(把它当wav看),IOS和桌面浏览器都是不行的,比较奇怪。但对于远程文件如果是amr,Android浏览保持跟其他浏览器一样不支持。

最终选择后端转码,一开始想PHP硬来把amr解码再编码为mp3,这个脑洞太大,找了很久都找不到现成的类库之类的,看mp3编码原理自己整?等看懂天就已经亮了。有个PHP-FFMpeg神马的,一看,好像是专为Laravel做的似的,还一堆依赖,弄啥咧。问运维,自己服务器是否有ffmpeg?被说不行,怎么可以自己处理,太占用资源了,没有的,用七牛!那就只能如此了,开始担心七牛转码会不会太慢,要不要等上几秒十几二十秒的,实测并没有,付费的还算比较快,10来秒的音频基本秒转!这么快的话,连试听都直接使用后端返回的mp3地址来播放不就好了。使用七牛的PHP SDK是可以直接上传二进制数据的,见:https://github.com/qiniu/php-sdk/blob/master/src/Qiniu/Storage/UploadManager.php

此外,还得考虑录音过程中用户刷新页面、关闭页面、跳转其他页面、切换后台这些事。其中,刷新、跳转js在Android中是能够监听得到的,就是beforeunload事件,IOS中的Safari是不行的,看苹果官方文档写着”Deprecated,use pagehide instead,试了所谓pagehide,压根没法弹出信息,也没法阻止。考虑到还有关闭与切换后台,应该是native干这事比较好。经测试跳转、关闭、刷新应该都是可以提醒并放弃的(切换后台估计不能),但最后提需求的人说不必了,所有用户主动的影响录音的操作一律停掉录音不用提醒。嗯,It’s my pleasure!

现在我在想,刚录完试听上次录音的时候,为何不交给native来解决?那不省事了?!😅

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.