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通道是否繁忙,如果繁忙,就取消该视频帧在这个通道上的发送。这样,就避免了内存无线增长的情况。但在这种方案下,那些通道比较慢的与会者,因为丢弃视频帧的原因,看到别人的视频可能就会出现马赛克、卡、不连续的现象。

 

时间: 2025-01-29 21:29:02

OMCS使用技巧 -- 摄像头及其动态能力的相关文章

《圣殿祭司的ASP.NET4.0专家技术手册》----2-3 C# 4.0静态基础融入动态能力

2-3 C# 4.0静态基础融入动态能力 圣殿祭司的ASP.NET4.0专家技术手册 在了解静态与动态语言后,大家直觉上可能会以为这是二元的对立,非黑即白,不是静态语言,就是动态语言.但您是否想过静态和动态之间是可以兼具或混合的可能性?例如,静态语言为获取动态语言优点,而融入了一些动态语言的功能,然后又保持静态语言的优势,如类型安全.优化.高效率. 是的,.NET 4.0正是以这个方向去改造,在原本C#.VB静态语言基础上,加上动态语言的一些特性与优势,这样就达到以静态为主,动态为辅之目的,让C

Flash技巧:谈动态滚动文本框制作方法

动态|技巧|文本框 再看代码之前,请先看看下面的说明,这会对理解代码有很大的帮助:http://www.huoshan.org/shiyan/gundongtiao/gundongtiao.htm 下面是滚动条中所有的代码://%%%%%%%%%%%%%%%%接口变量%%%%%%%%%%%%////接收父剪辑文本域名字var wenben_txt = _parent.wenben_txt;//---------滚动初始化---------////此变量是滑块的初始高度,现在设置为最高,也就占满上

浅析Eclipse建模框架(EMF)及其动态能力

如果给定一个模型,那么EMF能够自动生成Java源代码-该源码允许你创建.查询.更新.串行化.反串行化.检验和追踪你的模型实例的变化.EMF提供了一组有效的反射API并且允许你用动态的(非生成的)模型进行工作. 一.引言 Eclipse建模框架(EMF)是一个Java开源框架与代码生成工具-用于基于结构化的模型来构建工具和其它应用程序.在Eclipse平台在用户界面和文件级上提供一个强有力的集成框架的同时,EMF加强了这种能力来实现工具和应用程序之间良好粒度的数据分享. 类似于其它的Java绑定

JSP技巧:发送动态图像

你是否曾经想过从jsp页面(或者servlet)中发送动态产生的图像?这篇技巧告诉你如何做.要运行这里的代码,你需要一个Tomcat或者其他支持JSP 1.1的web服务器. 当一个web页面带有image/jpeg (或者其他的图像格式)的MIME类型被发送时,你的浏览器将那个返回结果当作一个图像,然后浏览器显示图像,作为页面的一部分或者完全作为图像自身.要为你的jsp页面设置MIME类型,你需要设置页面的contentType属性:<%@ page contentType="image

专家答疑:虚拟世界中的动态能力规划

1.数据挖掘定义与分类 数字档案馆,作为传统实体档案馆在信息时代的新型组织形式,是实体档案馆在信息时代不断创新和发展的必然,是迎接知识经济时代挑战,拓展传统实体档案馆功能,满足用户需求,提供个性化.多样化服务的关键,也是提高社会档案意识的新契机.那么,如何从数字档案馆浩如烟海的大量数字化资源中提炼.挖掘出有价值的,对数字档案馆进行知识积累.知识创新有着数据支撑作用的有效信息,这是未来数字档案馆建设所面临的重要课题.数据挖掘技术正是解决这一难题的有效途径,数据挖掘是当今计算机领域的热点,其成果也广

PHP技巧:优化动态网页技术PHP程序的12条技巧

1.If a method can be static, declare it static. Speed improvement is by a factor of 4. 1.如果一个函数可以声明为静态的,那么就用静态的,速度是改进的一个因素4. 2.# Avoid magic like __get, __set, __autoload 2.避免使用__get, __set, __autoload等魔术函数 3.require_once() is expensive 3.require_onc

JavaScript动态检验密码强度的实现方法_javascript技巧

平时我们会在某些网站的注册页面或者更改密码的页面发现当我们输入密码时,会有一个类似于进度条的长条进行提示用户输入的密码强度.如下图: 我看到有些人用几张不同的图片来替换,这样似乎可以,但是不太好.所以我通过其他方式实现. 实质上这是根据用户输入的不同密码强度来改变 颜色区域的长度. 密码强度这个横条实质是一个div,其他标记也可以,div里面有一个span标记,我就是通过改变span的长度和颜色来表现密码的强度的.原理很简单,但是在操作过程中,可能会遇到一些问题很头疼. 1.先在html页面里面

Javascript的动态增加类的实现方法_javascript技巧

1.我们可以为每一个实例对象增加方法.也就是说我们在每次使用'类'之外的方法时候,都需要创建一次. function Dog(){ window.alert('I am a dog!'); } var dog1=new Dog();//实例化一个对象 //现在由于类Dog功能单一,无法满足对象dog1的需要,现在就要考虑为对象dog1新增加一个方法 function eat(){ window.alert('I like eat bone!'); } dog1.Dog_eat=eat; dog1

js实现动态改变字体大小代码_javascript技巧

在很多大网站上为了提高用户方便阅读文字,都提供有字体大小选择功能,以适应不同年龄段人群的阅读需求,其实这种功能实现起来也很简单,修改起来也方便,字体大号由你来定,默认字体大小可以CSS页面中定义,一般网页的标准字体是9pt,也就是12px: 实例代码一: <!DOCTYPE html> <html> <head> <title>修改字体大小.html</title> <meta http-equiv="keywords"