(二)WebRTC手記之框架與介面

weixin_34067049發表於2015-09-20

轉自:http://www.cnblogs.com/fangkm/p/4370492.html

 

轉載請註明出處:http://www.cnblogs.com/fangkm/p/4370492.html

上一篇文章簡單地介紹了下WebRTC的協議流程,這一篇就開始介紹框架與介面。

一提到框架,本能地不知道從什麼地方入手了。曾經直接從Chromium專案對WebRTC的原始碼的整合方面入手,後來發現這個步子邁的太大了,看的越多,概念越混亂,看了半個月感覺也沒啥沉澱。還是從WebRTC提供的示例工程peerconnection_client入手比較輕便。先拋開音視訊流的構建和渲染流程,示例工程核心的程式碼結構如下:

從物件導向的視角來看,WebRTC的設計還是非常棒的,真正地做到了介面程式設計的概念,對WebRTC功能的使用都通過介面來進行,這樣最大程度上保證了WebRTC模組的可定製性,這樣就可以讓WebRTC更多地迴歸到描述協議的本質。如果WebRTC對這些介面的實現不能滿足你的業務需求,理論上你可以提供自己的實現邏輯。本圖中的PeerConnectionFactoryInterface和PeerConnectionInterface沒有這種定製的代表性,因為重新提供它們的實現邏輯的需求場景基本上不存在(即便不用重寫,但也支援引數的定製,具體請參見CreatePeerConnectionFactory的過載方法)。但是音視訊相關的介面定製的場景就很普遍了,比如Chromium瀏覽器整合WebRTC,但是音視訊採集需要走Chromium自己的音視訊模組,所以Chromium對WebRTC音視訊的採集介面重新做了實現適配,以後有機會肯定非常樂意分享下Chromium原始碼對WebRTC的整合,不過那也是在對WebRTC熟悉完之後的工作了。

圖中Conductor是該示例工程提供的核心業務類,整個WebRTC的使用都濃縮在這個類中。Conductor通過CreatePeerConnectionFactory方法建立了一個PeerConnectionFactoryInterface介面的實現物件,通過這個介面,可以建立關鍵的PeerConnectionInterface介面,PeerConnectionInterface介面是WebRTC的協議核心。此外,PeerConnectionFactoryInterface介面還提供了建立本地音視訊流的功能介面,這個部分稍後再述。根據圖中PeerConnectionInterface介面的成員方法可以看出,WebRTC通訊流程的互動介面基本上都在這裡面了,給Conductor的回撥通知是通過PeerConnectionObserver介面來完成。具體的互動流程請參見上一篇博文。

接下來分析本地音視訊的相關介面,由於音視訊內容較多,這裡先介紹下介面概念,不談具體實現(下一節專門講解WebRTC原生的音視訊採集),還是以peerconnection_client工程為例:

這裡涉及到非常多的音視訊相關介面,基本上都是概念性的,最怕遇到新的設計概念,主要是怕自己理解有誤差,下面談一下我對這些介面概念的理解:

MediaStream概念: 表示媒體流,由MediaStreamInterface介面抽象,每個媒體流都有一個唯一的標識(通過label成員方法返回),它由一系列的音訊Track(由AudioTrackInterface介面抽象)和視訊Track組成(由VideoTrackInterface介面抽象)。

Track概念:具體指上圖結構中AudioTrackInterface和VideoTrackInterface介面,Track表示的是在媒體流中軌的概念,AudioTrackInterface標識的是音訊軌,VideoTrackInterface標識的是視訊軌,一個MediaStreamInterface標識的媒體流中允許攜帶多個媒體軌資料,它們之間是獨立的,在編碼渲染的流程中各自處理。如果概念還很模糊,軌的概念就相當於音訊資料中的聲道概念(左聲道、右聲道)、視訊資料中的YUV場的概念。Track既然封裝了媒體軌資料,那就必然有個媒體源做為資料的提供者,如音訊Track由AudioSourceInterface介面作為資料來源提供者,視訊Track由VideoSourceInterface介面作為資料的提供者。有輸入介面就必然有輸出介面,這部分在該圖中只展示了視訊資料的輸出介面VideoRendererInterface,這裡的Render命名的意思並不是僅限於將視訊和音訊資料渲染出來,應該理解成輸出介面。

VideoSourceInterface:抽象視訊源介面供VideoTracks使用,同一個源可以被多個VideoTracks共用。視訊源接納了一個VideoCapturer介面,抽象視訊採集的邏輯,我們可以提供自己的VideoCapturer實現做為視訊資料的採集源。VideoCapturer是個關鍵的定製介面,比如Chromium原始碼就是自己實現了VideoCapturer介面而沒用原生的WebRTC採集實現,但Chromium的音視訊採集都在browser程式,因此它對VideoCapturer介面的實現要比想象的複雜,它需要從主程式接收到視訊幀資料然後觸發VideoCapturer的SignalFrameCaptured訊號。

AudioSourceInterface:概念上同VideoSourceInterface類似,抽象音訊源介面供AudioTracks使用,但是從原始碼中理解,這是個偽概念,因為沒有提供一個類似於VideoCapturer的AudioCapturer介面,這裡沒有音訊的採集邏輯,實際上WebRTC的音訊採集介面使用的是AudioDeviceModule,在建立PeerConnectionFactory的時候可以由外界定製,如果沒有,則內部建立AudioDeviceModuleImpl來實現此介面完成音訊裝置的採集工作。可能是功力不夠,反正我是不太理解音訊採集和視訊採集這種設計的不對稱性。如果也封裝一個AudioCapturer介面的概念,這樣可定製性是不是可以更高。

構建媒體流的過程基本上就是構建Video Track和Audio Track,並將其新增到Media Stream裡。在peerconnection_client工程中,Conductor依賴DeviceManagerInterface介面的CreateVideoCapturer方法建立一個當前可用的視訊裝置採集物件VideoCapturer,將它作為視訊採集源中的資料來源(通過掛接VideoCapturer的SignalVideoFrame訊號來接收視訊資料),此外MainWnd還建立了一個內部類VideoRenderer從VideoRendererInterface介面派生,並將其新增到Video Track中, VideoRenderer的實現就是將接收到的視訊幀資料渲染到視窗上。

下一篇開始分析WebRTC原生的音視訊本地採集模組。

相關文章