我们在前面一篇文章中提到:任何一个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服务器之间的TCP连接的状态。

(3)创建P2P通道。在多媒体连接器发起到目标设备的连接请求时,同时异步创建到目标Owner的双向P2P通道。

(4)访问控制。允许或拒绝某个guest到本地某个设备的连接请求。

上述这些职责,可以通过多媒体设备管理器的接口OMCS.Passive.IMultimediaManager的定义体现出来。

1.属性

IMultimediaManager接口中所有的属性定义如下:

        /// <summary>
        /// 已连接的多媒体服务器的地址。
         /// </summary>
        AgileIPE ServerIPE {get; }

        /// <summary>
        /// 系统标志。
         /// </summary>
        string SystemToken { get; set; }

        /// <summary>
        /// 当前登录用户的ID。
         /// </summary>
        string CurrentUserID { get; }

        /// <summary>
        /// 当前多媒体管理器是否可用?
         /// </summary>
        bool Available { get; }

        #region Audio
        /// <summary>
        /// 要使用的麦克风的索引。必须在初始化前设置才有效。
         /// </summary>
        int MicrophoneDeviceIndex { get; set; }

        /// <summary>
        /// 要使用的扬声器的索引。必须在初始化前设置才有效。
         /// </summary>
        int SpeakerIndex { get; set; }

        /// <summary>
        /// 是否将话筒采集到的音频输出给Guest。(必须在初始化完成之后设置才有效,可动态修改。)
         /// 如果为true,表示输出;否则,表示将采集到的音频数据丢弃,不发送给guest。默认值为true。
         /// </summary>
        bool OutputAudio { get; set; }
        #endregion

        #region Camera
        /// <summary>
        /// 要使用的摄像头的索引。默认值0。可以在运行时动态修改。
         /// </summary>
        int CameraDeviceIndex { get; set; }

        /// <summary>
        /// 摄像头采集视频的大小。默认为320*240。可以在运行时动态修改。
         /// </summary>
        Size CameraVideoSize { get; set; }

        /// <summary>
        /// 摄像头采集的视频的编码质量。取值0~31,默认值6。取值越小,质量越高。可以在运行时动态修改。
         /// </summary>
        int CameraEncodeQuality { get; set; }

        /// <summary>
        /// [从Owner的角度]是否根据音频反馈以及视频丢帧情况自动调整视频编码质量。默认值为true。可以在运行时动态修改。
         /// </summary>
        bool AutoAdjustCameraEncodeQuality { get; set; }

        /// <summary>
        /// 是否将摄像头集到的视频输出给Guest。(必须在初始化完成之后设置才有效,可动态修改。)
         /// 如果为true,表示输出;否则,表示将采集到的视频数据丢弃,不发送给guest。默认值为true。
         /// </summary>
        bool OutputVideo { get; set; }
        #endregion       

        /// <summary>
        /// 本地桌面的编码质量。取值0~31,默认值6。取值越小,越清晰。可以在运行时动态修改。
         /// </summary>
        int DesktopEncodeQuality { get; set; }

        /// <summary>
        /// [从Owner的角度]Owner发送帧数据给Guest时,通道的选择模型。默认值为AutoChooseFaster4Audio。必须在初始化前设置才有效。
         /// </summary>
        ChannelMode ChannelMode { get; set; }

        /// <summary>
        /// 在广播帧的时候,是否允许丢弃帧。必须在初始化前设置才有效。
         /// </summary>
        bool AllowDiscardFrameWhenBroadcast { get; set; }

        /// <summary>
        /// 多媒体访问控制器。
         /// </summary>
        IMultimidiaGateway MultimidiaGateway { set; }

        /// <summary>
        /// 记录OMCS日志的文件路径,默认值为在运行目录下的OmcsLog.txt文件。(运行目录下可能没有写权限)。设为null,表示不记录任何日志。
         /// </summary>
        string OmcsLogPath { get; set; }

        /// <summary>
        /// 是否记录安全日志。默认值为false。
         /// </summary>
        bool SecurityLogEnabled { get; set; }

ServerIPE 只读属性显示了当前多媒体管理器连接的OMCS服务器的地址。

SystemToken 用于区分不同的基于OMCS开发的系统,并隔离它们。OMCS的服务端也会配置SystemToken,如果客户端与服务端的SystemToken的值不一致,则客户端就无法成功登录到OMCS服务端。

CurrentUserID 只读属性可以获取当前登录的用户的UserID。只有在多媒体管理器初始化(Initialize方法)成功之后,该属性才有效。

Available 属性显示了当前多媒体管理器是否与OMCS服务器成功建立了连接并完成了初始化,而处于可用状态。只有该属性为true时,多媒体管理器才可以正常使用。

CameraDeviceIndex、MicrophoneDeviceIndex、SpeakerIndex 属性用于分别设置要使用的本地摄像头、麦克风、以及扬声器的索引。

如果当前机器接有多个摄像头或者话筒设备,则可以通过这几个属性来明确指定要使用哪个设备。在大多数情况下,这两个属性设为0即可,其默认值也是0。

OutputAudio和OutputVideo 属性用于控制是否输出采集到的音频/视频数据给guest。

比如在视频会议中,我们可以只将当前发言人的OutputAudio设为true,而将其它成员的OutputAudio设为false,以减少带宽和避免杂音。

CameraVideoSize 用于设定摄像头采集视频的大小,现在的摄像头通常都支持很多种视频采集尺寸,后面的文章会详细介绍如何获取摄像头所支持的视频尺寸列表。

CameraEncodeQuality和DesktopEncodeQuality 属性用于设定摄像头视频和远程桌面视频的编码质量。我们可以根据网络状态动态调节它们的值,以控制带宽的使用。

AutoAdjustCameraEncodeQuality属性用于控制是否开启视频质量自动调节功能。

OMCS内部内置了一套音频/视频优化策略,其可以根据音频反馈以及视频丢帧的情况自动调整视频编码质量,以优先保证音频的清晰与流畅。如果该属性设为true,将开启这套内置策略。如果该属性开启,则CameraEncodeQuality属性的设置,将不再有效;但是我们仍然可以通过CameraEncodeQuality属性读取到当前视频的编码质量。

ChannelMode 属性用于控制通道选择模型。即当存在P2P通道时,那么多媒体数据传送的路径就有两种:经服务器中转、或直接经P2P通道传送。ChannelMode用于控制使用哪条通道传送多媒体数据。

AllowDiscardFrameWhenBroadcast 属性用于设置在广播帧的时候,是否允许丢弃帧。

比如,多个guest连到了同一个Owner的Camera设备,当Owner发送视频帧给各个guest时,如果到某个Guest的通道繁忙,则:如果AllowDiscardFrameWhenBroadcast为true,则不发送本帧给这个Guest;否则,仍然发送本帧给这个Guest。

OmcsLogPath 多媒体管理器会捕获内部产生的所有异常,并将其记录到OmcsLogPath指定的日志文件。其默认是运行目录下的OmcsLog.txt文件,但是,如果我们将基于OMCS的客户端程序安装在C盘,那么在win7下以普通身份运行起来后,是没有权限写运行目录的,这时,我们通常将日志路径设在“我的文档”的目录下面。

IMultimidiaGateway用于控制来访者Guest对本地多媒体设备的连接请求。IMultimidiaGateway接口定义如下:

    public interface IMultimidiaGateway
    {
        /// <summary>
        /// 是否允许来访者连接本地多媒体设备。该方法应尽快返回。
         /// </summary>
        /// <param name="guestID">来访者的UserID</param>
        /// <param name="deviceType">多媒体设备的类型</param>
        bool AllowConnect(string guestID, MultimediaDeviceType deviceType);
    }

    /// <summary>
    /// 默认的多媒体访问控制器。放行所有的连接请求。
    /// </summary>
    public class DefaultMultimidiaGateway : IMultimidiaGateway
    {
        public bool AllowConnect(string guestID, MultimediaDeviceType deviceType)
        {
            return true;
        }
    }

比如,当来访者要连接本地的多媒体设备时,OMCS首先会调用IMultimidiaGateway的AllowConnect方法,如果该方法返回true,则允许对方的此次连接;如果返回false,则拒绝对方的此次连接,对方将会得到连接失败的回复。
      OMCS提供了默认的IMultimidiaGateway实现 -- DefaultMultimidiaGateway,其对于AllowConnect方法的实现总是返回true。我们可以根据应用要求的设备访问控制策略,自己实现IMultimidiaGateway,并将其注入到MultimidiaManager的MultimidiaGateway属性。 在实现IMultimidiaGateway接口时,要注意所有方法都应该尽快返回,否则,可能导致来访者请求超时(默认为30秒)。

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方法将其进行初始化,初始化将做如下几件事情:

(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事件。特别要注意:当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开发手册(01) -- 多媒体设备管理器的更多相关文章

  1. OMCS开发手册(02) -- 多媒体连接器

    OMCS开发手册(01) -- 多媒体设备管理器 一文,我们从Owner的角度详细描述了多媒体设备管理器的使用,本文我们将站在Guest的角度,描述OMCS中另一类组件/控件:多媒体连接器.多媒体连接 ...

  2. OMCS开发手册(03) -- 多媒体服务器

    前面我们已经详细介绍了基于OMCS开发网络多媒体应用的客户端程序所必需掌握的内容,现在我们来看一下OMCS服务端的开发.对于使用者而言,OMCS的服务端就非常简单了,只要实现一个用户验证的接口,挂接到 ...

  3. OMCS开发手册(04) -- 二次开发流程

    在掌握了前面几篇关于OMCS的详细介绍后,我们就可以正式基于OMCS进行二次开发了.下面我们就从服务端和客户端的角度分别介绍开发的步骤. 一.服务端开发 抛开具体的业务逻辑而言,就OMCS的服务端的开 ...

  4. Android开发 多媒体提取器MediaExtractor详解_入门篇

    前言 MediaExtractor字面意思是多媒体提取器,它在Android的音视频开发里主要负责提取视频或者音频中的信息和数据流(例如将视频文件,剥离出音频与视频).本章博客将讲解一些入门简单的东西 ...

  5. 指导手册01:安装Hadoop

    指导手册01:安装Hadoop  Part 1:安装及配置虚拟机 1.安装Linux. (1)打开VMvirtualBox (2) 控制->新建虚拟机,输入虚拟机名称“marst+学号” 类型: ...

  6. 在线教学、视频会议 Webus Fox(2) 服务端开发手册

    上次在<在线教学.视频会议软件 Webus Fox(1)文本.语音.视频聊天及电子白板基本用法>里介绍了软件的基本用法.本文主要介绍服务器端如何配置.开发. 1. 配置 1.1 IIS配置 ...

  7. Navi.Soft30.开放平台.聚合.开发手册

    1系统简介 1.1功能简述 现在是一个信息时代,并且正在高速发展.以前获取信息的途径非常少,可能只有电视台,收音机等有限的来源,而现在的途径数不胜数,如:QQ,微信,官方网站,个人网站等等 本开发手册 ...

  8. Navi.Soft30.开放平台.腾讯.开发手册

    1系统简介 1.1功能简述 现在是一个信息时代,并且正在高速发展.以前获取信息的途径非常少,可能只有电视台,收音机等有限的来源,而现在的途径数不胜数,如:QQ,微信,官方网站,个人网站等等 本开发手册 ...

  9. Navi.Soft30.开放平台.百度.开发手册

    1系统简介 1.1功能简述 现在是一个信息时代,并且正在高速发展.以前获取信息的途径非常少,可能只有电视台,收音机等有限的来源,而现在的途径数不胜数,如:QQ,微信,官方网站,个人网站等等 本开发手册 ...

随机推荐

  1. git submodule相关操作

    $ cd 项目目录 // 初始化 $ git init $ git submodule add https://github.com/XXXX // 普通更新 $ git submodule upda ...

  2. Kmplayer播放器 绿色免安装版 2016 中文版

    软件名称: Kmplayer播放器 绿色免安装版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 42.8MB 图片预览: 软件简介: Kmplayer播放 ...

  3. PHP检测文件能否下载

    用php代码检测一个文件是否可以下载,网上没有找到合适的代码,自己实现了一个还挺好用的,分享给有需要的朋友. 基本原理:使用http的HEAD方法,检测报文的头里httpcode是否为200. pub ...

  4. Java学习日志(20170111)

    今日新知识点: 1.关键字volatile sychronized是同步锁,这个之前接触过,在类/方法或代码块前加该修饰词,即可实现线程同步: volatile也是一个修饰符,被volatile修饰的 ...

  5. 超实用 JS 代码段笔记(一)

    序1:30段简单代码段(有删减) 1 . 区分 IE 和 非 IE 浏览器 if(!+[1,]){ console.log('ie浏览器'); }else{ console.log('非ie浏览器') ...

  6. MPMoviePlayerController

    属性 说明 @property (nonatomic, copy) NSURL *contentURL 播放媒体URL,这个URL可以是本地路径,也可以是网络路径 @property (nonatom ...

  7. sqlite导入后无法使用

    问题:sqlite导入后无法使用 解决方式:引入sqlite3 的libraries ,然后再在 projectName-Bridging-Header.h 中添加 #import "sql ...

  8. WSAEventSelect IO复用模型

    1 今天帮一学习WSAEventSelect的网友排查一个测试用服务器端recv返回0的问题,出现这个问题直观判断一般是客户端socket关闭了,可是他的代码很简单并且是本机测试,通过wireshar ...

  9. 一.HttpClient、JsonPath、JsonObject运用

    HttpClient详细应用请参考官方api文档:http://hc.apache.org/httpcomponents-client-4.5.x/httpclient/apidocs/index.h ...

  10. NSLineBreakMode

    typedef enum {    UILineBreakModeWordWrap = 0,    UILineBreakModeCharacterWrap,    UILineBreakModeCl ...