基於React-Native0.55.4的語音識別項目全棧方案

移動端的API能力驗證方案與PC端不同!不同!!不同!!!html

即便須要使用的API都存在,也不必定能用,這一點和PC端是有很大區別的,國內的手機系統雖然都是基於Android,但幾乎都會通過各大廠商的定製,功能與原版Android系統並非徹底一致的,在考察技術方案的時候必定要確認用demo把功能跑起來才能夠,別問我怎麼知道的。前端

一. 移動端直接訪問Web應用?

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

2.1 WebView

  • 方案express

    在一個app中單頁面全屏放置一個WebView組件,而後加載https方式部署的web應用。

  • 理由

    手機瀏覽器沒法支持的狀況下,只能寄但願於WebViewWebView是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( )方法支持度的統計信息的備註中,發現已知問題中在寫明瞭:

基於React-Native0.55.4的語音識別項目全棧方案

簡單地說就是這個方法在Android webviewiOSPWA 基本都用不了。建議之後開發中可能用到一些不經常使用的API時完整地看一下相關信息。

  • 結論:

    Android8.0支持,Android支持度不佳,不建議使用。

2.2 crosswalk

  • 方案

    官方網址:https://crosswalk-project.org/

    利用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方案。

2.3 Cordova/ionic

基於React-Native0.55.4的語音識別項目全棧方案

  • 方案

    官方網址: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出品的應用必定會讓別人對你刮目相看。

  • 測試結果

    筆者曾在使用cordova3.3的時候就融入過crosswalk,也經過cordova插件成功調用過底層的GPS攝像頭及其餘一些原生組件,當時是爲了適配Android4.4版本。cordova7.0.0的腳手架經測試在國內是可使用的,新建的工程不管是經過自帶命令行仍是import進Android Studio來進行開發均可以打包爲對應的工程,官方文檔有很詳細的調用各類底層接口的說明,網上也有cordova7.0.0+crosswalk方案對應的技術貼。

    筆者因爲技術協議中指定技術棧的緣故,沒法中途替換解決方案,故本次未進行測試。

  • 結論:

    可考慮做爲總體解決方案進行嘗試。

2.4 React-Native

基於React-Native0.55.4的語音識別項目全棧方案

  • 方案

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

    這是筆者本次使用的方案,因爲web端採用React技術棧完成的緣故,爲了避免增長團隊小夥伴的學習成本,移動端就選用了React-Native的方案。這個方案既能夠按照混合開發的方式來進行,也能夠按照單個WebView的方式來進行(已驗證這種方案沒法支持WebRTC)。

    可能不少人已經據說去年Airbnb公開宣佈再也不繼續使用React-Native做爲移動端解決方案並作了詳細的解釋,當時也是不少人鼓吹說React-Native要涼涼了。實際上Airbnb在聲明中說的很清楚,React-Native是很是好的hybrid解決方案,他們所遇到的問題是當性能和用戶體驗優化到必定程度時,在hybrid技術的維護和開發上投入的人力過多了,整個項目的前端人員不只有Web前端,還有高級的AndroidIOS人員來保障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方案的總體架構

基於React-Native0.55.4的語音識別項目全棧方案

基本上只要多複用現成的組件,加上適量的定製,儘量不使用一些奇技淫巧,產品的流暢度基本區分不出來是不是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. WebRTCAndroid 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的同名方法。
相關文章
相關標籤/搜索