OMCS使用技巧 -- 攝像頭及其動態能力


      在開發類似視頻聊天的應用時,我們經常需要獲取攝像頭的相關信息;而在進行視頻聊天時,我們可能還希望有一些動態的能力。比如,在不中斷視頻聊天的情況下,切換一個攝像頭、或者修改攝像頭采集的分辨率或編碼質量等等。OMCS提供了很多有用的特性以支持上述需求。

一.枚舉攝像頭

      我們如何得知當前的計算機有哪些攝像頭了?

      OMCS提供了一個工具類OMCS.Tools.Camera,來幫助我們獲取這些信息。Camera有個靜態方法GetCameras,用於枚舉當前計算機上的所有攝像頭。 

  /// <summary>
  /// 枚舉當前計算機上的所有攝像頭設備。
  /// </summary>        
  public static List<CameraInformation> GetCameras()

      CameraInformation封裝了攝像頭的基本信息,其類圖如下所示:

   

      我們可以將GetCameras方法返回的列表直接綁定到Combox控件,效果如下所示: 

            

      默認情況下,IMultimediaManager使用的攝像頭的索引為0。如果索引為0的攝像頭不可用,或者,用戶指定使用其它的攝像頭,則可以將指定攝像頭的索引保存到配置文件。當客戶端程序啟動時,從配置文件中讀取該索引值,並將其賦值給IMultimediaManager的CameraDeviceIndex屬性。

二.獲取攝像頭支持的分辨率

      當選定了一個攝像頭,我們如何知道該攝像頭支持哪些采集分辨率、支持最高的幀頻是多少了?

      Camera提供了另一個靜態方法GetCameraCapability,來獲取目標攝像頭的能力信息。  

  /// <summary>
  /// 獲取目標攝像頭的能力信息(分辨率、最大幀頻)
  /// </summary>
  /// <param name="deviceIndex">目標攝像頭的索引</param>        
  public static List<CameraCapability> GetCameraCapability(int deviceIndex)

       CameraCapability類封裝了攝像頭的能力信息,其類圖如下所示:

   

      我們可以將GetCameraCapability方法返回的列表直接綁定到Combox控件,效果如下所示: 

     

三.動態切換攝像頭

      下面我們設想一種情況,假設我的電腦上裝有兩個可用的攝像頭, 我正在使用索引為0的攝像頭和我的朋友視頻聊天,某個時刻,我想在不中斷視頻聊天的情況下,切換到索引為1的攝像頭。這種需求就稱為動態切換攝像頭。

       OMCS支持動態切換攝像頭,並且操作相當簡單:我們只需要將IMultimediaManager的CameraDeviceIndex屬性賦值為要切換到的攝像頭的索引即可。

       切換會在OMCS內部自動進行,在很短的時間切換完成后,OMCS會將新攝像頭采集的視頻數據發送給各個guest。  

四.動態修改攝像頭的分辨率

       還記得QQ視頻聊天有這種能力,我們可以在視頻聊天的時候,選擇使用大窗口模式。這實際上就是使用攝像頭更高的分辨率來采集視頻,比如原始的采集分辨率為320*240,可切換到更高的640*480

       OMCS支持在不需要任何中斷的情況下,修改正在使用的攝像頭的采集分辨率。操作也是相當簡單:我們只需要將IMultimediaManager的CameraVideoSize屬性設置為目標分辨率大小即可。當然,如果設置的分辨率不被當前攝像頭所支持,則將拋出NotSupportedException。另外要注意,在編碼質量相同的情況下,視頻的分辨率越高,所輸出的碼流就越大,所要求的帶寬也越大。

        為了避免設置不恰當的分辨率給CameraVideoSize屬性,在賦值之前,我們可以通過OMCS.Tools.Camera的靜態方法Support來判斷目標攝像頭是否支持指定的分辨率: 

   /// <summary>
   /// 目標攝像頭是否支持采集指定的分辨率。
   /// </summary>     
   public static bool Support(int deviceIndex, Size videoSize)

五.動態調節編碼質量

      在客戶端運行的任何時候,我們都可以通過設置IMultimediaManager的CameraEncodeQuality屬性,來實時調整攝像頭采集的視頻的編碼質量。編碼質量越高(CameraEncodeQuality取值越小),對帶寬的要求就越高;反之亦然。

      當然,正如前面文章所介紹的,如果IMultimediaManager的AutoAdjustCameraEncodeQuality屬性被設置為true,則CameraEncodeQuality將會被OMCS自動調節以優先保證語音的清晰連貫,手動對CameraEncodeQuality的設置就不起作用了。

      如果我們將AutoAdjustCameraEncodeQuality設置為false,並且我們的應用自己能檢測到網絡狀態的實時變化,那么,我們就可以根據當前的網絡狀態,來手動調整CameraEncodeQuality。

六.控制視頻輸出

       設想這樣一種情況:我在進行視頻會議時,某個時間出於某種原因,我不想讓與會者看到我的視頻,一段時間后,我又希望恢復原樣。

       從節省帶寬的角度,最好的方式就是在這段時間內不輸出視頻幀。OMCS能簡單地實現這種控制:我們只需將IMultimediaManager的OutputVideo屬性設置為false,即可關閉視頻幀的輸出。

七.廣播時選擇丟棄視頻幀

       下面要設想的場景稍微復雜一點:在視頻會議時,我的視頻會發送給與會的每個人,假設我與每個與會者之間都建立的是P2P通道,視頻幀都經過P2P通道傳送。現在的問題時,每個P2P通道的質量是不一樣的,有的可能很快,有的可能很慢。我們假設到與會者A的通道非常慢,到其他與會者的通道質量都很好。那么,我們來分析一下在兩種廣播模式下,可能出現的情況。

1.同步廣播模式

      在同步廣播模式下,只有當某個視頻幀在所有的通道上都發送完畢時,才會去發送下一個視頻幀。這樣就會出現因為與A之間的通道緩慢,而導致其他與會者看到自己的視頻出現卡或不連貫的情況。

2.異步廣播模式

      在異步廣播模式下,視頻幀在所有的通道上都是異步發送的,這樣A通道的緩慢不會影響到其它的與會者。OMCS采用的就是這種模式。

      但是,由於通道A的緩慢,生產視頻幀的速度遠大於通道A消費視頻幀的速度,這就導致了需要使用更多的內存來緩存那些來不及發送的視頻幀。就客戶端進程看來,其所占用的內存會不斷增加,就像內存泄漏一樣。

      如何解決這個問題了?OMCS給出的方案是可以選擇在通道繁忙時丟棄幀。通過將IMultimediaManager的AllowDiscardFrameWhenBroadcast屬性設置為true,便可啟用這種方案。

      AllowDiscardFrameWhenBroadcast被啟用后,當一個新的視頻幀要通過某個P2P通道發送給對應的與會者時,會先檢測一下該P2P通道是否繁忙,如果繁忙,就取消該視頻幀在這個通道上的發送。這樣,就避免了內存無線增長的情況。但在這種方案下,那些通道比較慢的與會者,因為丟棄視頻幀的原因,看到別人的視頻可能就會出現馬賽克、卡、不連續的現象。

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com