從WebRTC提供的示例工程peerconnection_client入手學習Webrtc

轉自:https://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的實現就是將接收到的視頻幀數據渲染到窗口上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章