OMCS开发手册(00) -- 概述一文中提到:任何一个OMCS的Client都有两种身份,Owner和Guest。多媒体设备管理器就是工作于OMCS客户端,并以Owner的身份管理本地所有的多媒体设备的。多媒体设备管理器对象是OMCS在客户端的核心对象,其在整个运行周期内一直存在,并会根据guest的请求自动启动或停止某个多媒体设备。
一.多媒体设备
像本地的摄像头、麦克风、电子白板等都属于多媒体设备,多媒体设备的类型使用枚举MultimediaDeviceType表示:
/// <summary>
/// 多媒体设备的类型。
/// </summary>
public enum MultimediaDeviceType
{
/// <summary>
/// 摄像头。
/// </summary>
Camera = 0,
/// <summary>
/// 话筒。
/// </summary>
Microphone,
/// <summary>
/// 桌面。
/// </summary>
Desktop,
/// <summary>
/// 电子白板。
/// </summary>
WhiteBoard
}
目前的OMCS支持MultimediaDeviceType定义的4种多媒体设备类型,所有的多媒体设备都由多媒体管理器IMultimediaManager统一管理。
(1) 客户端以Owner身份提供本地的多媒体设备供其它客户端访问。
(2) 各种类型的多媒体设备对应的类Class都是internal的,属于OMCS的内部对象,开发人员不需要对其进行任何编程。取而代之的是,开发人员可以通过IMultimediaManager来间接获取多媒体设备的有关状态和信息。
二.多媒体设备管理器详解
作为OMCS客户端的核心对象,多媒体管理器的主要职责为:
(1)管理本地的所有多媒体设备实例,设置设备参数,以及在合适的时间启动或停止某个多媒体设备。
(2)与OMCS服务器通信,并管理与OMCS服务器的连接的状态。
(3)创建P2P通道。在多媒体连接器发起到目标设备的连接请求时,同时异步创建到目标Owner的双向P2P通道。
(4)访问控制。允许或拒绝某个guest到本地某个设备的连接请求。
上述这些职责,可以通过多媒体设备管理器的接口OMCS.Passive.IMultimediaManager的定义体现出来。
1.属性
IMultimediaManager接口中所有的属性定义如下:
AgileIPE ServerIPE {get; }
/// <summary>
/// 当前登录用户的ID。
/// </summary>
string CurrentUserID { get; }
/// <summary>
/// 要使用的麦克风的索引。
/// </summary>
int MicrophoneDeviceIndex { get; set; }
/// <summary>
/// 要使用的摄像头的索引。
/// </summary>
int CameraDeviceIndex { get; set; }
/// <summary>
/// 当前多媒体管理器是否可用?
/// </summary>
bool Available { get; }
/// <summary>
/// 是否将话筒采集到的音频输出给Guest。
/// </summary>
bool OutputAudio { get; set; }
/// <summary>
/// 多媒体访问控制器。
/// </summary>
IMultimidiaGateway MultimidiaGateway { set; }
/// <summary>
/// 摄像头捕捉的视频的编码质量。取值0~31。取值越小,越清晰。可以在运行时动态修改。
/// </summary>
int CameraEncodeQuality { get; set; }
/// <summary>
/// [从Owner的角度]是否根据音频反馈以及视频丢帧情况自动调整视频编码质量。默认值为true。
/// </summary>
bool AutoAdjustCameraEncodeQuality { get; set; }
/// <summary>
/// 本地桌面的编码质量。取值0~31。取值越小,越清晰。可以在运行时动态修改。
/// </summary>
int DesktopEncodeQuality { get; set; }
/// <summary>
/// [从Guest的角度]在连接器连接到设备之前,是否自动先尝试创建P2P通道。默认值为true。必须在初始化前设置才有效。
/// </summary>
bool P2PChannelEnabled { get; set; }
/// <summary>
/// 记录OMCS日志的文件路径,默认值为在运行目录下的OmcsLog.txt文件。
/// </summary>
string OmcsLogPath { get; set; }
/// <summary>
/// 是否记录安全日志。默认值为false。
/// </summary>
bool SecurityLogEnabled { get; set; }
ServerIPE只读属性显示了当前多媒体管理器连接的OMCS服务器的地址。
CurrentUserID只读属性可以获取当前登录的用户的UserID。只有在多媒体管理器初始化(Initialize方法)成功之后,该属性才有效。
CameraDeviceIndex和MicrophoneDeviceIndex属性用于分别设置要使用的本地摄像头和麦克风的索引,如果当前机器接有多个摄像头或者话筒,则可以通过这两个属性来明确指定要使用哪个设备。在大多数情况下,这两个属性设为0即可,其默认值也是0。
Available 属性显示了当前多媒体管理器是否与OMCS服务器成功建立了连接并完成了初始化,而处于可用状态。只有该属性为true时,多媒体管理器才可以正常使用。
OutputAudio属性用于控制是否输出采集到的音频数据给guest。比如在视频会议中,我们可以只将当前发言人的OutputAudio设为true,而将其它成员的OutputAudio设为false,以减少带宽和避免杂音。
IMultimidiaGateway用于控制来访者Guest对本地多媒体设备的连接请求。IMultimidiaGateway接口定义如下:
public interface IMultimidiaGateway
{
/// <summary>
/// 是否允许来访者连接本地多媒体设备。该方法应尽快返回。
/// </summary>
/// <param name="guestID">来访者的UserID</param>
/// <param name="deviceType">多媒体设备的类型</param>
bool AllowConnect(string guestID, MultimediaDeviceType deviceType);
}
比如,当来访者要连接本地的多媒体设备时,OMCS首先会调用IMultimidiaGateway的AllowConnect方法,如果该方法返回true,则允许对方的此次连接;如果返回false,则拒绝对方的此次连接,对方将会得到连接失败的回复。
OMCS提供了默认的IMultimidiaGateway实现 -- DefaultMultimidiaGateway,其对于AllowConnect方法的实现总是返回true。我们可以根据应用要求的设备访问控制策略,自己实现IMultimidiaGateway,并将其注入到MultimidiaManager的MultimidiaGateway属性。 在实现IMultimidiaGateway接口时,要注意所有方法都应该尽快返回,否则,可能导致来访者请求超时(默认为30秒)。
CameraEncodeQuality以及DesktopEncodeQuality属性可以控制摄像头采集到的视频和桌面的编码质量。质量越好,视频就越清晰,所需的带宽也就越大;反之亦然。
AutoAdjustCameraEncodeQuality属性用于控制是否开启视频质量自动调节功能。OMCS内部内置了一套音频/视频优化策略,其可以根据音频反馈以及视频丢帧的情况自动调整视频编码质量,以优先保证音频的清晰与流畅。如果该属性设为true,将开启这套内置策略。如果该属性开启,则CameraEncodeQuality属性的设置,将不再有效;但是我们仍然可以通过CameraEncodeQuality属性读取到当前视频的编码质量。
P2PChannelEnabled 属性用于控制在连接某Owner的设备之前,是否先尝试与其创建P2P通道。
OmcsLogPath 多媒体管理器会捕获内部产生的所有异常,并将其记录到OmcsLogPath指定的日志文件。其默认是运行目录下的OmcsLog.txt文件。但是,如果我们将基于OMCS的客户端程序安装在C盘,那么在win7下以普通身份运行起来后,是没有权限写运行目录的,这时,我们通常将日志路径设在“我的文档”的目录下面。
2.方法
IMultimediaManager接口中所有的方法定义如下:
/// <summary>
/// 与多媒体服务器建立连接,并初始化本地多媒体管理器。
/// </summary>
/// <param name="userID">当前登录的用户ID。</param>
/// <param name="password">当前登录的用户的密码。</param>
/// <param name="serverIP">OMCS服务器IP</param>
/// <param name="serverPort">OMCS服务器端口</param>
void Initialize(string userID,string password, string serverIP, int serverPort);
/// <summary>
/// 主动断开来访者guest到本地多媒体设备的连接。
/// </summary>
/// <param name="guestID">来访者的用户ID</param>
/// <param name="deviceType">设备类型</param>
/// <param name="notifyGuest">是否通知对方。如果通知对方,对方的连接器将触发Disconnected事件。</param>
void DisconnectGuest(string guestID, MultimediaDeviceType deviceType ,bool notifyGuest);
/// <summary>
/// 主动断开所有来访者到本地多媒体设备的连接。
/// </summary>
/// <param name="notifyGuest">是否通知对方。如果通知对方,对方的连接器将触发Disconnected事件。</param>
void DisconnectGuest(bool notifyGuest);
/// <summary>
/// 获取所有连接到当前多媒体设备的Guest列表。
/// </summary>
List<string> GetGuests(MultimediaDeviceType deviceType);
/// <summary>
/// 查询本地的某设备是否正在工作?
/// </summary>
/// <param name="deviceType">设备类型</param>
/// <returns>工作中?</returns>
bool DeviceIsWorking(MultimediaDeviceType deviceType);
Initialize方法在使用多媒体管理器之前,首先要调用Initialize方法将其进行初始化,初始化将做如下几件事情:
(1)与目标OMCS服务器建立连接。
(2)使用参数传入的帐号密码进行登录。
(3)如果登录成功,则初始化本地的多媒体设备。
注意,如果与服务器连接失败,或者帐号密码错误,则将抛出相应的异常。只有Initialize方法成功返回后,其它的方法才能被正常调用。
DisconnectGuest 方法用于Owner主动断开某个guest或所有guest到本地某设备的连接,该方法为Owner提供了一种主动性的权利。
剩下的几个方法,像DeviceIsWorking、GetGuests等,比较容易理解,就不再赘述。
3.事件
IMultimediaManager接口中所有的事件定义如下:
/// <summary>
/// 当与媒体服务器的连接断开时,触发此事件。
/// </summary>
event CbGeneric ConnectionInterrupted;
/// <summary>
/// 当与媒体服务器重连成功时,触发此事件。
/// </summary>
event CbGeneric ConnectionRebuildSucceed;
/// <summary>
/// 当某个guest连接到当前设备时,触发此事件。参数为guestID - MultimediaDeviceType
/// </summary>
event CbGeneric<string, MultimediaDeviceType> DeviceConnected;
/// <summary>
/// 当某个guest从当前设备断开时,触发此事件。参数为guestID - MultimediaDeviceType
/// </summary>
event CbGeneric<string, MultimediaDeviceType> DeviceDisconnected;
多媒体管理器初始化成功后,与OMCS服务器的长连接就建立了。当与OMCS服务器的连接断开时,将触发ConnectionInterrupted事件。而且多媒体管理器内部自动使用了断线重连机制,当网络恢复后,会自动重连OMCS服务器,如果重连成功,将会触发ConnectionRebuildSucceed事件。我们可以通过ConnectionInterrupted事件、ConnectionRebuildSucceed事件、以及Available属性来监控多媒体管理器与OMCS服务器之间的连接状态。
当某个guest连接到本地的某多媒体设备时,将触发DeviceConnected事件;当某个guest与本地的某多媒体设备断开时,将触发DeviceDisconnected事件。这两个事件的参数都指明了设备的类型和guest的UserID。
三.Singleton模式
可以想象,一般在一个进程中,我们只需要一个多媒体管理器实例。那么,我们可以以Singleton模式来使用多媒体管理器。
在设计OMCS时,IMultimediaManager接口的实现类MultimediaManager是internal的,在OMCS外部,我们看不到它的存在,所以也就没有办法new一个MultimediaManager实例。而OMCS已经为我们提供了MultimediaManagerFactory静态类,让我们更方便地以单件模式使用多媒体管理器实例,其GetSingleton方法直接返回这个单件。
本文主要从作为设备的Owner的角度出发,讨论了多媒体设备管理器有哪些职责,以及其提供的API是如何工作的。下篇文章,我们将从作为Guest的角度触发,讨论如何使用多媒体连接器。谢谢。
阅读 更多OMCS开发手册系列文章。
-----------------------------------------------------------------------------------------------------------------------------------------------
关于OMCS的任何问题,欢迎联系我们:
电话:027-87638960
Q Q:168757008