移动端的
API
能力验证方案与PC端不同!不同!!不同!!!html即便须要使用的
API
都存在,也不必定能用,这一点和PC端是有很大区别的,国内的手机系统虽然都是基于Android
,但几乎都会通过各大厂商的定制,功能与原版Android
系统并非彻底一致的,在考察技术方案的时候必定要确认用demo
把功能跑起来才能够,别问我怎么知道的。前端
PC端基于Web API
的语音识别方案可参考《【Recorder.js+百度语音识别】全栈方案技术细节》一文。node
1. 调用Web API
的多媒体采集接口须要特定的域react
Web API
的多媒体接口是WebRTC技术在PC端的实现,因为多媒体采集涉及到用户隐私,因此在浏览器端调用这个接口须要在安全的域下才能被调起,安全的域是指如下三类:android
file:///
本地域http://localhost
本地web服务器https://
安全域前两类通常用于桌面应用和本地调试,实际网站上线部署须要以https
方式部署,如何部署https
及申请免费的CA证书等网上有不少文章讲解,本文再也不赘述。git
2. 手机浏览器几乎都不直接支持WebRTC
接口github
将PC端的Web应用以https
方式部署好以后,从手机浏览器直接访问时没法唤起录音接口权限认证,navigator.getUserMedia( )
方法一只返回permissionDenied
错误,不管是在Android6.0如下经过编辑manifest.xml
添加仍是Android6.0以上经过动态获取的方式取得RECORD_AUDIO
权限,网站均可以正常访问,相关的Web API
接口也都存在,但即便得到用户受权后也没法调起录音功能。笔者测试了UC浏览器,百度移动浏览器和Android6.0(API23)自带的浏览器,Android8.0(API26)自带的浏览器,结果是都不支持。web
o( ̄▽ ̄)d 既然从移动端直接访问Web应用时没法调起录音接口,至少是没法兼容不少系统和机型,若是不考虑直接原生开发Android的话,只有寄但愿于Hybrid的方案了。chrome
方案:express
在一个app中单页面全屏放置一个WebView组件,而后加载https方式部署的web应用。
理由:
手机浏览器没法支持的状况下,只能寄但愿于WebView
。WebView
是Android底层用于加载网页的组件,Android4.4版本之后已将内置的浏览器引擎更换为chromium,也就是chrome的内核,从Can I Use上查询的支持度是Android5.0以上的版本的WebView
都是支持WebRTC
接口的getUserMedia( )
方法的。
测试结果:
应用编译目标版本为API23
,在支持API23
(Android6.0)的虚拟机和真机中测试,均没法经过WebAPI
接口调起麦克风进行录音。在支持API26
(Android8.0)版本的虚拟机中,功能都可实现。最终在Can I Use中对于getUserMedia( )
方法支持度的统计信息的备注中,发现已知问题中在写明了:
简单地说就是这个方法在Android webview
,iOS
和PWA
基本都用不了。建议之后开发中可能用到一些不经常使用的API时完整地看一下相关信息。
结论:
Android8.0支持,Android支持度不佳,不建议使用。
方案:
官方网址:https://crosswalk-project.org/
利用crosswalk
,在进行app打包时,将webview
内核替换为xwalk
(crosswalk开发的基于chromium的浏览器内核),以扩展原生webview
的能力。
理由:
既然原生webview
功能被阉割,那么能够利用这个小型黑科技来把一个功能更强大的浏览器内核跟本身的应用打包在一块儿,笔者3年前在cordova
2.0-3.0版本流行的年代使用过这个技术,好处是的确能够扩展webview
的能力无疑,很差的地方在于app项目会直接增大80-90Mb的体积,固然经过几个版本的迭代,如今crosswalk能够针对手机内核类型生成不一样的包,app体积增量大约在20Mb,基本属于可接受范围。
测试结果:
遗憾地是这个项目一年前已经中止维护了,最后一版的官方脚手架工具也没法初始化新的工程,间接使用的方式分为两种,第一,下载crosswalk
的包,手动在android
工程中替换原生WebView
,对Hybrid开发者来讲难度较大且与hybrid技术兼容性不可控;另外一种方案在下一小节说明。
结论:
不建议使用,有那个精力真不如去研究一下可靠的hybrid方案。
方案:
官方网址:https://cordova.apache.org
codova
是一个很流行的hybrid方案,如今已经升级到8.0.0版本,它自己就是一个将web应用打包为app的解决方案。cordova
的基本原理是将通常UI
层操做和功能放在WebView
里实现,须要调用移动设备硬件或原生接口时,均经过添加cordova
插件的形式来实现,每个cordova
版本都会横跨支持若干个Android
版本,例如新的cordova7.0.0
在官方文档的说明中是支持android从4.4到8.1版本的,笔者认为很是适合小型hybrid开发团队使用。
理由:
值得一提的是cordova
拥有一个很是流行的移动端开发×××ionic
,如今已经迭代至4.0
阶段,这个技术笔者是有特殊感情的,当年ionic
还在alpha
版本的时候,笔者就在使用了,它是基于cordova+angular这个技术组合的,拥有清新且设计感极强的UI组件,很是值得尝试。另外,cordova
是拥有crosswalk
插件的,能够直接以插件的形式,在cordova
项目打包时加入crosswalk
,有相关需求的读者能够以一试,尤为是团队里没有Android开发人员也没有专门的设计人员的时候,ionic
出品的应用必定会让别人对你刮目相看。
测试结果:
笔者曾在使用cordova
3.3的时候就融入过crosswalk
,也经过cordova
插件成功调用过底层的GPS
,摄像头
及其余一些原生组件,当时是为了适配Android4.4版本。cordova7.0.0
的脚手架经测试在国内是可使用的,新建的工程不管是经过自带命令行仍是import进Android Studio来进行开发均可以打包为对应的工程,官方文档有很详细的调用各类底层接口的说明,网上也有cordova7.0.0+crosswalk
方案对应的技术贴。
笔者因为技术协议中指定技术栈的缘故,没法中途替换解决方案,故本次未进行测试。
结论:
可考虑做为总体解决方案进行尝试。
方案:
这是笔者本次使用的方案,因为web端采用React
技术栈完成的缘故,为了避免增长团队小伙伴的学习成本,移动端就选用了React-Native
的方案。这个方案既能够按照混合开发的方式来进行,也能够按照单个WebView
的方式来进行(已验证这种方案没法支持WebRTC
)。
可能不少人已经据说去年Airbnb
公开宣布再也不继续使用React-Native
做为移动端解决方案并作了详细的解释,当时也是不少人鼓吹说React-Native
要凉凉了。实际上Airbnb
在声明中说的很清楚,React-Native
是很是好的hybrid解决方案,他们所遇到的问题是当性能和用户体验优化到必定程度时,在hybrid技术的维护和开发上投入的人力过多了,整个项目的前端人员不只有Web前端,还有高级的Android
和IOS
人员来保障hybrid项目的推动,他们认为这样的人力成本相比于原生开发而言要高不少,因此更换了方案。听明白了吗?因此做为软件技术比国外落后不知道多少年的天朝码农,考虑实际的项目需求,尽管放心大胆地用就行了,跟风真的没什么价值。
理由:
热门的hybrid解决方案,和Web前端三驾马车之一的React
属同门,语法和组件结构类似度高,社区活跃且周边生态较好。
测试结果:
React-native
已经发布0.57.3
版本,但经测试0.55.4
在国内属于可正常新建工程的版本(使用react-native init XXX
命令建立的工程),0.56
大版本中发布的两个小版本均在初始打包时报错,命令行的提示连接到一个已知issue,但惋惜照作之后也未能打包成功,0.57
默认的Android-SDK是API27
,也就是Android8.1,对于经验不足的开发者来讲(好比我本身),太新的版本也不建议使用,除非你的项目是在指定机器上运行的。
React-native
也封装了WebView
组件,但很遗憾,直接加载web应用的方式经测试也没法调起getUserMedia( )
这个方法,因此最终只能经过混合开发的方案来实现(但回过头来想,跟经过WebView
来调用硬件接口相比,其实这种实现方式反而更符合逻辑)。
结论:
建议未掌握多语言混合开发能力的hybrid开发者尽量选用热门方案,理由很简单,全部的前端项目都有坑,但热门项目出了问题能够找大牛咨询。
WebRTC
技术录音相关的navigator.getUserMedia
,navigator.mediaDevices.getUserMedia
,AudioContext
这上面这几个方案中都是存在的,但事实是都没能在webview
中调起麦克风进行录音。固然
WebRTC
做为独立的标准和技术,也是能够融入Android工程的,但从前端开发者的角度来讲这条路就有点跑偏了,执着于WebRTC
或者团队里有原生开发者的小伙伴能够研究一下。
基本上只要多复用现成的组件,加上适量的定制,尽量不使用一些奇技淫巧,产品的流畅度基本区分不出来是不是Hybrid开发仍是Native开发,固然跟笔者的项目体量不是很大也有必定关系。
react-native-audio
地址:https://github.com/jsierles/react-native-audio
调用麦克风采集音频。
rn-fetch-blob
地址:https://github.com/joltup/rn-fetch-blob
在RN中从native层经过原生线程直接发送大致积二进制数据或文件,经过Bridge对象从Web发请求会形成性能问题。
Multer
模块
地址:https://github.com/expressjs/multer
Express
服务端中间件,用于接收客户端发送的大致积二进制数据或文件。
FFmpeg
工具
多媒体格式转换库。手机端采集编码的格式没法被百度语音识别接口直接识别,须要先进行重编码。node.js
开发者经过child_process
模块直接从代码中唤起命令行执行便可。
docxtemplater
模块
地址:https://docxtemplater.readthedocs.io/en/latest/
node.js
模块语音识别结果须要在后台生成docx
格式的文件(word文档),可以使用这个模块,使用方法和模板渲染引擎基本一致。
悬浮框
权限,不然可能白屏什么都不显示。WebRTC
在Android WebView
兼容性很差,IOS
内置浏览器不支持。react-native-audio
进行录音时,每一次调用Stop
以后,若要再次启动录音功能,必须先调用AudioRecorder.prepareRecordingAtPath( )
方法从新初始化,不然会红屏报错。WebView
组件必须设置ref={(webview)=>{this.webview = webview}}
,不然onMessage
属性没法监听到来自WebView
加载网页经过window.postMessage
发来的消息。TouchableHighlight
组件必须先设置onPress
属性的回调函数(能够为空函数),不然触摸变色的响应属性UnderlayColor
没法生效。Modal
组件在一个自定义组件中只能有一个(若是有多个必须经过条件判断只实例化一个),不然即便未显示的Modal
组件的Visible
属性设置为false
,其实例方法也会和另外一个Modal
组件发生重叠覆盖,可能出现的现象就是显示了第一个Modal
的界面,却执行了第二个Modal
的同名方法。