写点什么

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

  • 2020-03-30
  • 本文字数:4055 字

    阅读完需:约 13 分钟

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

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

1. 调用 Web API 的多媒体采集接口需要特定的域

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



前两类一般用于桌面应用和本地调试,实际网站上线部署需要以 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)自带的浏览器,结果是都不支持。

二. 方案调研和新的坑

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


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


  • crosswalk


方案


利用 crosswalk,在进行 app 打包时,将 webview 内核替换为 xwalk(crosswalk 开发的基于 chromium 的浏览器内核),以扩展原生 webview 的能力。


理由:


既然原生 webview 功能被阉割,那么可以利用这个小型黑科技来把一个功能更强大的浏览器内核跟自己的应用打包在一起,笔者 3 年前在 cordova2.0-3.0 版本流行的年代使用过这个技术,好处是的确可以扩展 webview 的能力无疑,不好的地方在于 app 项目会直接增大 80-90Mb 的体积,当然通过几个版本的迭代,现在 crosswalk 可以针对手机内核类型生成不同的包,app 体积增量大约在 20Mb,基本属于可接受范围。


测试结果:


遗憾地是这个项目一年前已经停止维护了,最后一版的官方脚手架工具也无法初始化新的工程,间接使用的方式分为两种,第一,下载 crosswalk 的包,手动在 android 工程中替换原生 WebView,对 Hybrid 开发者来说难度较大且与 hybrid 技术兼容性不可控;另一种方案在下一小节说明。


结论:


不建议使用,有那个精力真不如去研究一下可靠的 hybrid 方案。


  • Cordova/ionic



方案


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 出品的应用一定会让别人对你另眼相看。


测试结果:


笔者曾在使用 cordova3.3 的时候就融入过 crosswalk,也通过 cordova 插件成功调用过底层的 GPS,摄像头及其他一些原生组件,当时是为了适配 Android4.4 版本。cordova7.0.0 的脚手架经测试在国内是可以使用的,新建的工程无论是通过自带命令行还是 import 进 Android Studio 来进行开发都可以打包为对应的工程,官方文档有很详细的调用各种底层接口的说明,网上也有 cordova7.0.0+crosswalk 方案对应的技术贴。


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


结论:


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


  • React-Native



方案:


官方网址


这是笔者本次使用的方案,由于 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 开发,当然跟笔者的项目体量不是很大也有一定关系。

四. 使用插件清单


调用麦克风采集音频。



在 RN 中从 native 层通过原生线程直接发送大体积二进制数据或文件,通过 Bridge 对象从 Web 发请求会造成性能问题。



Express 服务端中间件,用于接收客户端发送的大体积二进制数据或文件。



多媒体格式转换库。手机端采集编码的格式无法被百度语音识别接口直接识别,需要先进行重编码。node.js 开发者通过 child_process 模块直接从代码中唤起命令行执行即可。



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

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

1.真机调试时,需要摇晃手机,在配置菜单中填写内网 IP+端口号,否则会直接红屏报错。


2.真机调试时,需要在设置中开启应用的悬浮框权限,否则可能白屏什么都不显示。


3.WebRTC 在 Android WebView 兼容性不好,IOS 内置浏览器不支持。


4.react-native-audio 进行录音时,每一次调用 Stop 之后,若要再次启动录音功能,必须先调用 AudioRecorder.prepareRecordingAtPath( )方法重新初始化,否则会红屏报错。


5.WebView 组件必须设置 ref={(webview)=>gt;{this.webview = webview}},否则 onMessage 属性无法监听到来自 WebView 加载网页通过 window.postMessage 发来的消息。


6.TouchableHighlight 组件必须先设置 onPress 属性的回调函数(可以为空函数),否则触摸变色的响应属性 UnderlayColor 无法生效。


7.Modal 组件在一个自定义组件中只能有一个(如果有多个必须通过条件判断只实例化一个),否则即使未显示的 Modal 组件的 Visible 属性设置为 false,其实例方法也会和另一个 Modal 组件发生重叠覆盖,可能出现的现象就是显示了第一个 Modal 的界面,却执行了第二个 Modal 的同名方法。


本文转载自 华为云产品与解决方案 公众号。


原文链接:https://mp.weixin.qq.com/s/Isu-XAxBZyp5Q0AxswWiDQ


2020-03-30 17:391398

评论

发布
暂无评论
发现更多内容

费时3个月啃烂了这份Redis技术笔记,我成功上岸进了字节

收到请回复

redis 架构 语言 & 开发 Java core redis 底层原理

首次发布!Java面试八股文让569人成功进入大厂,堪称2022最强面试八股文核心知识版!

退休的汤姆

Java 程序员 面经 秋招 Java八股文

设计模式的艺术 第十三章外观设计模式练习(为新开发的智能手机控制与管理软件提供一键备份功能。通过该功能可以将原本存储在手机中的通讯录、短信、照片、歌曲等资料一次性地全部复制到移动存储介质(如MMC卡或SD卡)中。实现过程中需要与多个已有的类进行交互)

代廉洁

设计模式的艺术

小六六学Netty系列之Java NIO(一)

自然

网络 9月月更 neety

如果你是Java程序员,你会选择Cloud Studio进行云端开发,放弃IDEA吗?

wljslmz

Java Cloud Studio 9月月更

在世界人工智能大会,看京东AI向产业奔涌

脑极体

设计模式的艺术 第十二章装饰设计模式练习(开发一个数据加密模块,可以对字符串进行加密。最简单的加密算法通过对字母移位来实现,同时提供了稍复杂的逆向输出加密和更高级的求模加密。用户先用最简单的算法加密,如果觉得不够,可以使用其他算法进行二次加密和三次加密)

代廉洁

设计模式的艺术

腾讯T4整合Spring+Spring MVC+MyBatis+Redis实现

退休的汤姆

Java 程序员 面经 Java工程师 秋招

DPDK技术学习路线总结,虚拟化专家之路

C++后台开发

后台开发 DPDK VPP OvS DPDK开发

完美!华为大佬手码20w字Redis全栈小册,原来Redis性能可压榨到极致

Java全栈架构师

数据库 redis 程序员 面试 后端

C++学习------cerrno头文件的作用与源码学习

桑榆

c++ 9月月更

Java工程师丨面试必会进程线程问答

陈橘又青

Java 面试 9月月更

数据治理的内核:元数据管理

小鲸数据

数据治理 数字化 元数据 元数据管理 元数据管理平台

C++后台开发学习路线(已多人拿下腾讯后台开发)

C++后台开发

后台开发 后端开发 C++后台开发 C++开发 腾讯后台开发

《游戏机图鉴》:发展、继承、崩溃、复兴,游戏机的前世今生

图灵社区

科普 游戏机

重学网络系列之(我的名字叫IP)

自然

网络 9月月更

常见的网络安全攻击及防御技术概述

阿泽🧸

网络安全 9月月更

如何成为资深的测试专家

穿过生命散发芬芳

测试 9月月更

秋招国内大厂最牛的Java面试八股文合集(全彩版),不接受反驳

退休的汤姆

Java 程序员 面经 Java工程师 秋招

数据存储与物联网

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

分布式技术难学?谷歌大神首发纯手撸ZK+Dubbo笔记,网友看完直呼NB

收到请回复

Java zookeeper 架构 分布式 语言 & 开发

设计模式的艺术 第十一章组合设计模式练习(开发一个界面控件库。界面控件分为两大类:一类是单元控件,例如按钮、文本框等;另一类是容器控件,例如窗体、中间面板等。试用组合模式设计该界面控件库)

代廉洁

设计模式的艺术

深入思考Schema管理的几个基本问题

HackMSF

挑战30天学完Python:Day1火力全开-初识Python(含系列大纲)

MegaQi

9月月更 挑战30天学完Python

2022-09-03:n块石头放置在二维平面中的一些整数坐标点上 每个坐标点上最多只能有一块石头 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。 给你一个长度为 n 的数组

福大大架构师每日一题

算法 rust 福大大

软件复杂性的来源与应对

源字节1号

软件开发 前端开发 后端开发 小程序开发

小六六学Netty系列之Java BIO

自然

网络 9月月更 neety

【大话 C 语言】春眠不觉晓,函数知多少?

Albert Edison

递归 C语言 函数 开发语言 9月月更

PANAMA: 共享机器学习集群的网内聚合框架

俞凡

大数据 架构 网络

基于React-Native0.55.4的语音识别项目全栈方案_文化 & 方法_华为云产品与解决方案_InfoQ精选文章