OMCS 开发手册(11) -- 深入摄像头、麦克风、扬声器
在开发类似视频聊天的应用时,我们经常需要获取音视频设备的相关信息;而在进行视频聊天时,我们可能还希望有一些动态的能力。比如,在不中断视频聊天的情况下,切换一个摄像头、或者修改摄像头采集的分辨率或编码质量、或者暂时屏蔽话筒的输出,等等。OMCS提供了很多有用的特性以支持上述需求。
一.摄像头
1.枚举摄像头
我们如何得知当前的计算机有哪些摄像头了?
OMCS提供了一个工具类OMCS.Windows.Camera,来帮助我们获取这些信息。Camera有个静态方法GetCameras,用于枚举当前计算机上的所有摄像头。
/// <summary> /// 枚举当前计算机上的所有摄像头设备。 /// </summary> public static List<CameraInformation> GetCameras()
CameraInformation封装了摄像头的基本信息,我们可以将GetCameras方法返回的列表直接绑定到Combox控件,效果如下所示:
默认情况下,IMultimediaManager使用的摄像头的索引为0。如果索引为0的摄像头不可用,或者,用户指定使用其它的摄像头,则可以将指定摄像头的索引保存到配置文件。当客户端程序启动时,从配置文件中读取该索引值,并将其赋值给IMultimediaManager的CameraDeviceIndex属性。
2.获取摄像头支持的分辨率
当选定了一个摄像头,我们如何知道该摄像头支持哪些采集分辨率、支持最高的帧频是多少了?
Camera提供了另一个静态方法GetCameraCapability,来获取目标摄像头的能力信息。
/// <summary> /// 获取目标摄像头的能力信息(分辨率、最大帧频) /// </summary> /// <param name="deviceIndex">目标摄像头的索引</param> public static List<CameraCapability> GetCameraCapability(int deviceIndex)
CameraCapability类封装了摄像头的能力信息,我们可以将GetCameraCapability方法返回的列表直接绑定到Combox控件,效果如下所示:
3.动态切换摄像头
下面我们设想一种情况,假设我的电脑上装有两个可用的摄像头, 我正在使用索引为0的摄像头和我的朋友视频聊天,某个时刻,我想在不中断视频聊天的情况下,切换到索引为1的摄像头。这种需求就称为动态切换摄像头。
OMCS支持动态切换摄像头,并且操作相当简单:我们只需要将IMultimediaManager的CameraDeviceIndex属性赋值为要切换到的摄像头的索引即可。切换会在OMCS内部自动进行,在很短的时间切换完成后,OMCS会将新摄像头采集的视频数据发送给各个guest。
4.动态修改摄像头的分辨率
还记得QQ视频聊天有这种能力,我们可以在视频聊天的时候,选择使用大窗口模式。这实际上就是使用摄像头更高的分辨率来采集视频,比如原始的采集分辨率为320*240,可切换到更高的640*480。
OMCS支持在不需要任何中断的情况下,修改正在使用的摄像头的采集分辨率。操作也是相当简单:我们只需要将IMultimediaManager的CameraVideoSize属性设置为目标分辨率大小即可。当然,如果设置的分辨率不被当前摄像头所支持,则将抛出NotSupportedException。另外要注意,在编码质量相同的情况下,视频的分辨率越高,所输出的码流就越大,所要求的带宽也越大。
为了避免设置不恰当的分辨率给CameraVideoSize属性,在赋值之前,我们可以通过OMCS.Tools.Camera的静态方法Support来判断目标摄像头是否支持指定的分辨率:
/// <summary> /// 目标摄像头是否支持采集指定的分辨率。 /// </summary> public static bool Support(int deviceIndex, Size videoSize)
5.动态调节编码质量
在客户端运行的任何时候,我们都可以通过设置IMultimediaManager的CameraEncodeQuality属性,来实时调整摄像头采集的视频的编码质量。编码质量越高,CameraEncodeQuality取值越小,对带宽的要求就越高;反之亦然。
注意,如果IMultimediaManager的AutoAdjustCameraEncodeQuality属性被设置为true,则CameraEncodeQuality将会被OMCS自动调节以优先保证语音的清晰连贯,手动对CameraEncodeQuality的设置就不起作用了。如果我们将AutoAdjustCameraEncodeQuality设置为false,并且我们的应用自己能检测到网络状态的实时变化,那么,我们就可以根据当前的网络状态,来手动调整CameraEncodeQuality。
6.控制视频输出
设想这样一种情况:我在进行视频会议时,某个时间出于某种原因,我不想让与会者看到我的视频,一段时间后,我又希望恢复原样。
从节省带宽的角度,最好的方式就是在这段时间内不输出视频帧。OMCS能简单地实现这种控制:我们只需将IMultimediaManager的OutputVideo属性设置为false,即可关闭视频帧的输出。
二.麦克风
1.枚举麦克风
我们如何得知当前的计算机配有哪些麦克风设备了?
OMCS提供了一个工具类OMCS.Windows.SoundDevice,来帮助我们获取这些信息。SoundDevice有个静态方法GetMicrophones,用于枚举当前计算机上的所有麦克风。
/// <summary> /// 枚举当前计算机上的所有麦克风设备。 /// </summary> public static List<MicrophoneInformation> GetMicrophones()
MicrophoneInformation封装了麦克风的基本信息,我们可以将GetMicrophones方法返回的列表直接绑定到Combox控件,效果如下所示:
默认情况下,IMultimediaManager使用的麦克风的索引为0。如果索引为0的麦克风不可用,或者,用户指定使用其它的麦克风,则可以将指定麦克风的索引保存到配置文件。当客户端程序启动时,从配置文件中读取该索引值,并将其赋值给IMultimediaManager的MicrophoneDeviceIndex属性。
2.控制声音输出
设想这样一种情况:我在进行视频会议时,某个时间出于某种原因,我不想让与会者听到我的声音,一段时间后,我又希望恢复原样。
从节省带宽的角度,最好的方式就是在这段时间内不输出声音数据。OMCS能简单地实现这种控制:我们只需将IMultimediaManager的OutputAudio属性设置为false,即可关闭视音帧数据的输出。
三.扬声器
1.枚举扬声器
我们如何得知当前的计算机配有哪些扬声器设备了?
OMCS.Windows.SoundDevice有个静态方法GetSpeakers,用于枚举当前计算机上的所有扬声器。
/// <summary> /// 枚举当前计算机上的所有扬声器设备。 /// </summary> public static List<SpeakerInformation> GetSpeakers()
SpeakerInformation封装了扬声器的基本信息,我们可以将GetSpeakers方法返回的列表直接绑定到Combox控件,效果如下所示:
默认情况下,IMultimediaManager使用的扬声器的索引为0。如果索引为0的扬声器不可用,或者,用户指定使用其它的扬声器,则可以将指定扬声器的索引保存到配置文件。当客户端程序启动时,从配置文件中读取该索引值,并将其赋值给IMultimediaManager的SpeakerIndex属性。
2.声卡是否安装
OMCS.Windows.SoundDevice的静态方法IsSoundCardInstalled,用于判断当前计算机的声卡是否正常安装。
/// <summary> /// 当前计算机是否安装了声卡。 /// </summary> public static bool IsSoundCardInstalled()
3.音量放大
如果已经将计算机的音量调到最大,还是觉得MicrophoneConnector播放的声音很小,那么,可以通过设置IMultimediaManager的VolumeAmplifyFactor来放大声音。
/// <summary> /// 输出音量的放大系数。取值范围1~10。默认值1(表示不放大)。可以在运行时动态修改。 /// </summary> int VolumeAmplifyFactor { get; set; }
4.静音
如果希望某个MicrophoneConnector不播放声音,则可以将MicrophoneConnector的Mute属性设为true。
/// <summary> /// 是否静音。默认值false。 /// </summary> bool Mute { get; set; }
四.设备报错
当第一个guest连接到Owner的某设备时,该设备会自动启动运行,如果启动时设备发生错误,则Owner方和Guest方都能得到相应的通知。
Owner方:IMultimediaManager的DeviceErrorOccurred事件会触发。
/// <summary> /// 当本地多媒体设备报错时,会触发该事件。参数为 MultimediaDeviceType - 错误描述 /// </summary> event CbGeneric<MultimediaDeviceType, string> DeviceErrorOccurred;
Guest方:相应的多媒体连接器的ConnectEnded事件触发,表明连接失败,且其事件参数通常为ConnectResult.DeviceInvalid。
相关内容:语音视频设备测试
--------------------------------------------------------------------------------------------
阅读 更多OMCS开发手册系列文章。
Q Q:168757008