您的位置:首页 > Web前端 > React

基于React-Native0.55.4的语音识别项目全栈方案

2018-10-24 07:16 926 查看

移动端的

API
能力验证方案与PC端不一样!不一样!!不一样!!!

即使需要使用的

API
都存在,也不一定能用,这一点和PC端是有很大区别的,国内的手机系统虽然都是基于
Android
,但几乎都会经过各大厂商的定制,功能与原版
Android
系统并不是完全一致的,在考察技术方案的时候一定要确认用
demo
把功能跑起来才可以,别问我怎么知道的。

一. 移动端直接访问Web应用?

PC端基于

Web API
的语音识别方案可参考《【Recorder.js+百度语音识别】全栈方案技术细节》一文。

1. 调用

Web API
的多媒体采集接口需要特定的域

Web API
的多媒体接口是WebRTC技术在PC端的实现,由于多媒体采集涉及到用户隐私,所以在浏览器端调用这个接口需要在安全的域下才能被调起,安全的域是指以下三类:

  • file:///
    本地域
  • http://localhost
    本地web服务器
  • https://
    安全域

前两类一般用于桌面应用和本地调试,实际网站上线部署需要以

https
方式部署,如何部署
https
及申请免费的CA证书等网上有很多文章讲解,本文不再赘述。

2. 手机浏览器几乎都不直接支持

WebRTC
接口

将PC端的Web应用以

https
方式部署好之后,从手机浏览器直接访问时无法唤起录音接口权限认证,
navigator.getUserMedia( )
方法一只返回
permissionDenied
错误,无论是在Android6.0以下通过编辑
manifest.xml
添加还是Android6.0以上通过动态获取的方式取得
RECORD_AUDIO
权限,网站都可以正常访问,相关的
Web API
接口也都存在,但即使获得用户授权后也无法调起录音功能。笔者测试了UC浏览器,百度移动浏览器和Android6.0(API23)自带的浏览器,Android8.0(API26)自带的浏览器,结果是都不支持。

二. 方案调研和新的坑

o( ̄▽ ̄)d 既然从移动端直接访问Web应用时无法调起录音接口,至少是无法兼容很多系统和机型,如果不考虑直接原生开发Android的话,只有寄希望于Hybrid的方案了。

2.1 WebView

  • 方案

    在一个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支持度不佳,不建议使用。

2.2 crosswalk

  • 方案

    官方网址: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方案。

2.3 Cordova/ionic

  • 方案

    官方网址: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
    方案对应的技术贴。

    笔者由于技术协议中指定技术栈的缘故,无法中途替换解决方案,故本次未进行测试。

  • 结论:

    可考虑作为整体解决方案进行尝试。

2.4 React-Native

  • 方案

    官方网址:https://reactnative.cn

    这是笔者本次使用的方案,由于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
或者团队里有原生开发者的小伙伴可以研究一下。

三. React-Native方案的整体架构

基本上只要多复用现成的组件,加上适量的定制,尽可能不使用一些奇技淫巧,产品的流畅度基本区分不出来是否是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
    工具

    地址:http://ffmpeg.org/

    多媒体格式转换库。手机端采集编码的格式无法被百度语音识别接口直接识别,需要先进行重编码。

    node.js
    开发者通过
    child_process
    模块直接从代码中唤起命令行执行即可。

  • docxtemplater
    模块

    地址:https://docxtemplater.readthedocs.io/en/latest/

    node.js
    模块语音识别结果需要在后台生成
    docx
    格式的文件(word文档),可使用这个模块,使用方法和模板渲染引擎基本一致。

五. RN开发细节和遇到的坑

  1. 真机调试时,需要摇晃手机,在配置菜单中填写内网IP+端口号,否则会直接红屏报错。
  2. 真机调试时,需要在设置中开启应用的
    悬浮框
    权限,否则可能白屏什么都不显示。
  3. WebRTC
    Android WebView
    兼容性不好,
    IOS
    内置浏览器不支持。
  4. react-native-audio
    进行录音时,每一次调用
    Stop
    之后,若要再次启动录音功能,必须先调用
    AudioRecorder.prepareRecordingAtPath( )
    方法重新初始化,否则会红屏报错。
  5. WebView
    组件必须设置
    ref={(webview)=>{this.webview = webview}}
    ,否则
    onMessage
    属性无法监听到来自
    WebView
    加载网页通过
    window.postMessage
    发来的消息。
  6. TouchableHighlight
    组件必须先设置
    onPress
    属性的回调函数(可以为空函数),否则触摸变色的响应属性
    UnderlayColor
    无法生效。
  7. Modal
    组件在一个自定义组件中只能有一个(如果有多个必须通过条件判断只实例化一个),否则即使未显示的
    Modal
    组件的
    Visible
    属性设置为
    false
    ,其实例方法也会和另一个
    Modal
    组件发生重叠覆盖,可能出现的现象就是显示了第一个
    Modal
    的界面,却执行了第二个
    Modal
    的同名方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: