1. 程式人生 > >React Native在直播應用中的實踐

React Native在直播應用中的實踐

React Native是近年來最值得花時間學習的移動開發新技術,其在不斷進化、成熟的同時,效能也在持續提升。卜赫主要分享了React Native Pili在開發過程中的設計斟酌和踩過的坑。以下是正文:

React Native是什麼

React Native的iOS和Android版本目前是由官方在維護,Windows版本是微軟做了遷移,淘寶有把React Native移植到Web上,另外還有工程師已經把它移植到了OS X上了。所以在將來如果你會React Native,就會很容易成為一個全端工程師。

React Native用的是ReactJS語法。其他的跨平臺方案一般是先編譯成中間碼再在虛擬機器中執行,例如Java和.Net,React Native卻不太一樣,因為跨平臺是非常難的,平臺檢視會有很大差異。React Native的思路是讓我們學習這種開發模式後可以用這套模式去開發任何平臺的應用,即所謂的「learn once ,write anywhere」。但是開發的程式碼會稍微有些不同,例如在Web端會寫一些HTML的Tag,在React Native中則會寫一些抽象出來的原生元件的Tag。

React Native和原有的Hybrid框架有何區別呢?首先,它是用原生元件去渲染的,而不是用WebView,後面的優勢劣勢也是因此產生的。其次,它的響應速度也不像是在手機瀏覽器裡面跑的WebApp,它所有的頁面都是Native。另外,它的動畫也不是CSS模擬的,而是一些原生動畫,這個則可以給使用者帶來非常好的體驗。

當然Hybrid框架也有一些優勢,比如你可以用你想用的所有前端庫,並且也確實做到了跨平臺,但是隨著React Native的不斷進步——幾乎支援所有的平臺,這個優勢正在慢慢地被蠶食。

React Native本身是一個UI框架,它更多的像一個庫。原來前端可能都是大的嚇人,需要把通訊、MVC等全部解決了,而React Native只是一個UI,只需用它來寫介面,其他的問題你自己去解決即可。你選擇哪種架構,React Native並不關心,它只專注地把UI部分做好。當然,這也會帶來一些問題,因為所有的東西都是檢視,做的時候會帶來一些挑戰。

直播簡介

圖片描述

圖 1

知道了React Native後,我們來了解下直播。瞭解直播前,讓我們先理性地認識一下什麼是視訊。視訊大家每天都看,但是到底什麼是視訊呢?其實它是一個封裝,主要封裝了三部分內容,如圖1所示。上面的部分是Metadata,下面是聲音,中間最主要的是圖片。它是用一些連續的圖片來欺騙我們的眼睛,當超過每秒24幀的時候,我們看起來就會是連續的。

圖片描述

圖 2

直播的模型比較簡單,如圖2所示。由主播發起,推送流到雲端,然後其他的人通過搜尋來觀看直播。直播的協議有很多,比較主流的有RTMP、HLS。RTMP協議是Adobe公司開發的,HLS則是蘋果開發的,它們的主要區別如圖3所示。

圖片描述

圖 3

其中,RTMP是用的TCP長連線,所以它是一個長連線協議。而HLS從本質上來講,是一個播放列表,持續不斷地更新這個播放列表,最終會產生一些ts的切片檔案。直接用蘋果的瀏覽器開啟之後就可以看HLS,有些Android也支援,但是HLS的延時比較長,超過10秒鐘。

圖片描述

圖 4

同時,它們具體的使用場景也有一些不同,如圖4所示。在即時互動的情況下,我們傾向於選用RTMP協議,例如在秀場應用中,如果一個土豪給主播發了一個紅包,但是主播10秒之後才互動就會很不好。而廣播協議HLS,則比較適用於做點播和回放,例如我們在看一個演唱會的時候,可能所有人在看這個演唱會都是延遲了10秒鐘,但是你不會關心這10秒鐘,因為每一秒都延時了10秒鐘。

一個直播應用需要多大開發量

相信映客、龍珠直播等直播APP大家都有用過,但是你是否知道一個直播應用需要多大開發量呢?圖5、圖6是我們開發的一個最簡單的直播應用的核心程式碼展示。

圖片描述

圖 5

圖片描述

圖 6

我們會發現,一個直播應用核心開發竟然只需2行程式碼。前面我們知道,直播模型就是一個推流和收流。圖5是推流的程式碼,裡面可以設定推到雲端的地址、推流的解析度、位元速率率等屬性,設定完後就可以推流,推流以後就可以播放了,播放的時候還可以設定播放的地址、硬體碼、軟體碼等屬性,如圖6。

上面的那些程式碼為何如此簡單,裡面都隱藏了哪些細節呢?其實我們在背後做了很多工作,而且用了不止一種語言。React Native是JS語言,它是跑在iOS和Android上的。但是我們在做的過程中,並沒有用JS做視訊的編解碼,也沒有用JS去實現RTMP的協議,主要原因是一些效能問題無法解決。最終採用的方案是JS+Objective-C+Java,即在Android裡使用JS+Java,在iOS裡面使用Objective-C,然後在最上層用一個統一的API。對應用層工程師而言是跨平臺的,即你在Android和iOS裡面寫的程式碼是完全一樣的,但是底層我們會用Java和Objective-C做一定的適配工作。以某個APP為例,圖7是推流部分,最上面的Streaming是用JS來寫的,下面效能關鍵的部分是用Objective-C來寫的,比如推流有一個預覽的檢視,有一個協議的推流的管理器,然後還有一個編碼器。播放部分與推流類似,如圖8所示。上面是一個Preview的JS適配在Android的方案,下面基本是用Native來寫的,有一個播放頁面和播放流的管理器,包括是硬解碼還是軟解碼。

圖片描述

圖 7

圖片描述

圖 8

所以總結下來,不管在底層的React Native有多少的狀態,我們最終都能通過JS和Native Code把它們隱藏在所有的細節裡,最終展現給開發者看的只有一個最終頁面和夠用的屬性,即Preview View和Player View。

API 的設計與呼叫

React Native是以View為中心的,所以在設計React Native API的時候,強制要求我們API的設計風格和訪問方式統一化,主要有「檢視」和「屬性」這兩個概念,這無疑對API設計者的功力要求更高了。

首先來看佈局管理,佈局管理其實是告訴大家這個介面是什麼樣的,目前React Native支援如下一些屬性,如圖9所示。

從經驗來看,這些屬性基本上可以滿足絕大部分的開發需求了,你可以儘量做一些彈性的佈局、按比例的佈局,因為你可以拿到裝置的整個層高寬度和高度,進而做一些百分比佈局。

圖片描述

圖 9

然後是配置管理,如圖10所示。所謂的配置管理,就是那些一旦設定就不需要改變的東西,因為你的介面一旦確定了,你是要推哪些流和位元速率,這些在整個推流過程中是不變的。因此,這個配置是相對比較靜態的配置。

圖片描述

圖10

後面是狀態管理,如圖11所示。狀態顯然與配置不一樣,因為它是可以變的,例如使用者可以切換是否靜音或畫面大小縮放比例等。

圖片描述

圖 11

接著是動作管理,如圖12所示。這部分可能與過去的設計有一些差異,之前在設計API的時候,動作一般會用方法來解決。這裡實際也是一個狀態,因為你的API不會觸發底層的狀態改變。但是它是反過來的,是先宣告目前的狀態,然後再根據當前的狀態去實際的調離底層的方法,是開始推流還是停止推流。

圖片描述

圖 12

圖13是事件管理,與原生的API也不同。這裡可以是一個本地函式或者閉包,當某個事件過來的時候可以呼叫你的函式。

圖片描述

圖 13

前面介紹瞭如何做API設計,那麼工程師該如何去呼叫API呢?答案是狀態驅動,如圖14所示。首先要在當前的介面初始化一個變數,意味有一個這樣的變量表示當前是不是靜音,然後在建立Streaming的時候,Streaming的Muted狀態是等於該變數的,這樣它們兩個就繫結在一起了。初始化時,Streaming處於靜音的狀態,然後比如說有一個按紐的回撥方法去觸發變數的改變,React Native發現當前的狀態發生改變後,就會把所有的屬性做一個diff,這是React Native一個比較核心的效能優化點,diff後發現Streaming的Muted屬性發生變化,就會通知底層的Native程式碼,這樣就完成了靜音的操作。開始和停止推流也是類似的,只要把state設成某一個狀態然後去改變它就可以了。

圖片描述

圖 14

我們用了這麼多程式碼,它們之間的佈局可能會非常不同,那麼最終是該如何把這些東西融合在一起,去適配它們呢?React Native本身是採用了W3C的新標準,即彈性盒子,它的方式是設計一些相對的佈局,例如你的元素是都靠左,還是都靠右,還是在中間,還是分散它,還是等距離等。當然這只是一方面,它的整個規範是比較複雜的,這裡面只簡單講了一個屬性,具體可以參考連結(https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/)。圖15是Flex Box佈局標準的一部分。

圖片描述

圖 15

圖片描述

圖 16

圖16是Android Streaming View的一個介面樹。我們可以看到它的頁面有很多層次,中間還有一個對焦框。其實我們只關心最外面的一層,最終應用開發者使用最外面一層的View即可,對裡面的檢視並不關心。在Android中我們一般會用XML Layout去佈局,但是在設計一個API的時候,給使用者很多種方式顯然是不太合適的。當你給了使用者一個XML,然後說用我們的API的時候,在Android裡面還要再去改XML,如果對方是一個Web開發者,它通過React Native技術進入了移動開發領域,看到這個XML之後會感覺很慌,因為並不知道這個是什麼。同理,iOS裡面也是一樣的,裡面可能會要用到Auto Layout。這些都是不太推薦的。所以在Android裡面,我們是直接用程式碼進行佈局,它的核心介面結構並不是太複雜。iOS裡面也是直接保持了最外層的View和裡面的View大小一致。但最終開發者使用的,都是用Flex Box來佈局。

在開發直播應用的時候,還有一個比較重要的內容,就是如何優雅地獲取和釋放硬體資源。我們知道,在iOS裡面這並不是問題,因為iOS會根據你的應用狀況去釋放和獲取資源,但是在Android裡卻可能是個問題。在Android裡面,你如果在後臺錄影或錄聲音會比較危險,這個時候React Native比較貼心地提供了類似的方法,你可以去監聽主Activity的做法,然後對應地在你的視圖裡面做一些響應,去釋放一些硬體。

React Native應用中的一些坑

如今,React Native發展得非常迅速,版本升級也是非常頻繁。去年大概10月份的時候還是0.14版本,現在已經是0.26版本了,迭代速度非常快,一兩週可能就會發一個版本。發新版本時,有的時候可以平滑地升級,但是有的時候會非常地痛苦,那麼究竟是升級還是不升級呢?不升級,繫結在某一個版本持續使用,這種選擇可能更適用於那種平臺本身已經非常成熟的情況。而現在React Native的發展速度極快了,導航欄已經發布了三個版本,新的元件在不斷地釋出,效能也在持續地優化。例如原來是在JS的執行緒裡面去執行動畫,而JS是單執行緒的,執行動畫時會對介面產生一定的影響,所以他們在嘗試在其他執行緒中執行動畫。最近還支援了3Dtouch等。因此,最好是緊跟React Native版本更新,至少不要延遲超過兩個版本。

然而升級的過程中,也伴隨著諸多不適。

第一個是React Native在0.14版本以後,整個圖片的載入方式都變了。原因是原來的圖片載入方式非常草率,基本上是你估計在哪裡然後給你渲染出來就好了。但是大家知道在Android和iOS裝置上,會有不同的解析度大小。後來的版本採用了靜態編譯的方式來解決這個問題,但是從0.14版本往上升的時候,需要你重新做一大堆的事情去手動升級。

第二個是0.19版本時,Java裡面的一個Annotation的包移動了位置,這個小小的升級卻產生了非常大的影響,導致所有的第三方的元件都要改動後重新編譯,因為所有第三方的擴充套件組建都非常依賴Annotation。這個過程當中,可能一時興起寫了一個元件丟在那兒不維護了,就會導致了大量的第三方庫不可用,而這個問題是非常嚴重的。第三是在你每次升級Node.js版本之後,並沒有提示要把所有的依賴性檔案都刪除,這樣可能會帶來一系列問題,而React Native的issues列表裡面可能至少有5%都是因為這個問題導致的。

相關推薦

React Native直播應用實踐

React Native是近年來最值得花時間學習的移動開發新技術,其在不斷進化、成熟的同時,效能也在持續提升。卜赫主要分享了React Native Pili在開發過程中的設計斟酌和踩過的坑。以下是正文: React Native是什麼 React Native的i

Redux中介軟體在ReactReact-Native專案架構應用實踐

前言 在MVVM框架模式獨攬天下的今天,React憑藉其獨特的設計思想,深入的設計理念,開闢了一條嶄新的康莊大道,實屬是一個重大的突破,為什麼這麼說呢?因為React論其設計思想,充其量只是MVVM種的V而已,對於大量而且複雜的資料來講,自身處理上顯得

react-native項目使用iconfont自定義圖標庫

復制 light 自定義 文檔 tabbar lin ext HR sta 1. 安裝react-native-vector-icons yarn add react-native-vector-icons react-native link 如果沒有關聯成功的話,

React-Native開發過程遇到的一些報錯以及一些常用命令

1、升級node(對安裝包安裝或者低版本的如6.11.4不生效) 1>檢視node版本,沒安裝的請先安裝;  $  node -v 2>清除node快取; $  sudo npm cache clean -f  3>安裝node版本管理工具'n';

React Native App應用架構設計

在上一篇介紹了React Native開發環境搭建,我們已經可以在本地成功執行一個helloword應用了,本節將開始詳細分析如何搭建一個React Native App應用架構,並支援完整本地執行預覽。前言現在已經有很多腳手架工具,如ignite,支援一鍵建立一個React

React Native學習過程遇到的坑

本文將記錄React Native學習過程中所遇到的各種各樣的坑…… 在學習過程中,執行官方的demo,是必不可少的學習手段,所以我們興致盎然的從github上下載了React Native,結果在執

Windows10環境下React Native打包的個人實踐

參考文件: ReactNative 中文網 ReactNactive qq群 搭建React Native for Android Windows開發環境    最近剛剛升級了win10,發現win10

React Native Android 開發遇到的坑

react native 更新非常活躍,下面的總結可能在後續會被完善修改好,根據react native 版本情況採用下面的方法, 我在使用的時間是 2015年12月10日。 網路請求方式,我使用官網的示例程式碼並沒用成功,簡單修改後才能使用 示例

[React Native]去掉WebStorm黃色警告

用WebStorm開發RN難免會碰到一大堆黃色警告。就像下面這樣。 其實這個錯誤並不會影響開發,但是作為一個上升處女座的,我很難忍。於是各種想辦法。 上網查了半天發現這篇文章 http://b

React-Native移動應用自動化測試框架Detox簡介

經過開發的鼎力相助,終於把RN的自動化測試框架研究通過了,目前環境已搭建並結合APP執行第一個Demo成功了。 1框架介紹(Detox) 它是為移動端APP打造的灰盒端到端自動化測試框架。 可用於React-Native開發的APP,使用js測試框架test或moc

3.React Native在Android自定義Component和Module

React Native最終展示的UI全是Native的UI,將Native的資訊封裝成React方便的呼叫。那麼Native是如何封裝成React呼叫的?Native和React是如何互動的? ViewManager UI元件:將Native的UI暴露

React native修改state的陣列

    今天遇到在react native中修改state中子項為陣列的情況,一直賦值不成功,後來查資料發現native中陣列是引用,不能直接對引用賦值,查詢資料的時候找到了該網頁: 修改陣列項的時候要返回一個新陣列,可以用擴充套件運算子...加上新的項! 後來完美解

React Native Android 應用層實戰淪陷記

1 背景 一眨眼又一年快要過去了,原計劃今年的最後一個小目標(React Native)看樣子要留尾巴到明年了,React Native 想說愛你不容易。怎麼評價你呢?應用層 JSX 編寫還是很友好的,尼瑪框架接入的各種鍋卻讓人痛哭不已,萬事開頭難,對

直播應用新增Faceu效果

在我寫的上篇文章 中,介紹了美顏濾鏡的實現原理,已經能夠體會到GPUImage 的強大。本文將要介紹的Faceu貼紙效果也是基於GPUImage實現的,demo我放在了GitHub上。 1.核心原理        Faceu貼紙效果其實就是在人臉上貼一些圖片,同時這些圖片是跟隨著人臉的位置改變的。如果我們不

組裝者模式在React Native項目的一個實戰案例

ops 多個 靈活 實戰 一個 some true ams 開發 前言 在實際的開發中,如果遇到多個組件有一些共性,我們可以提取一個BaseItem出來,然後在多個組件中進行復用,一種方式是通過繼承的方式,而今天我們要說的是另一種方式--組裝者模式。 什麽是組裝者模式? 就

React Native在特贊的應用實踐

使用 anywhere node.js 交互操作 網關 初始 andro -- 所有 基於React技術棧構建開發前端項目,並使用React Native開發特贊移動APP 目前正在使用Node.js開發和維護特贊服務網關,希望Node.js能夠在更輕量級的微服務架構中發

基於React Native的跨三端應用架構實踐

作者|陳子涵 編輯|覃雲 “一次編寫, 到處執行”(Write once, run anywhere ) 是很多前端團隊孜孜以求的目標。實現這個目標,不但能以最快的速度,將應用推廣到各個渠道,而且還能節省大量人力物力。 React Native 的推出,為跨平臺的開發帶來了新的曙光。 雖然 Facebo

React Native模組之Share呼叫系統分享應用實踐

前言 對於原生應用開發而言,呼叫系統匹配的應用進行分享是非常常見操作,今天我們來看一下,RN中如何封裝這一個操作的。 方法 RN中存在一個模組Share, 即為呼叫匹配的app進行分享操作。 在iOS中,通過呼叫一個包含’action’,’activit

React Native學習筆記之--向原生應用整合RN頁面

React Native學習筆記之–向原生應用中整合RN頁面 根據在官方文件的學習要向已有的原生專案中新增RN元件最重要的就是以下幾步: 1.Understand what React Native components you want to in

React-Native之IOS本地模組的應用實踐分享(僅此一篇足以...)

前言 React-Native從誕生至今,火熱程度已經不言而喻,在不斷的框架迭代過程中,RN也提供了豐富的元件,以供開發者使用,但是在實際應用中,我們可能需要更為豐富的互動元件,但是RN中又沒有及時提供,這時候我們就需要使用RN的本地模組,本地模組即可