OMCS 开发手册(07) -- 扩展音视频输入(附Demo:接入海康威视网络摄像头、接入RTMP流)

  有些OMCS用户需要在他的系统中,使用网络摄像头(IP Camera,如海康威视的摄像头)或者特殊的视频采集卡(如AV-878采集卡)作为视频源,或者其它的声音采集设备作为音频源。在这种情况下,OMCS是不直接支持这些视频采集设备和声音采集设备的。但是,OMCS提供了扩展接口,让使用者可以向OMCS框架中注入其自己的声音/视频采集程序。

        下面以扩展视频输入为例进行讲解,对于扩展声音输入,原理是一模一样的。要实现视频输入的扩展相当简单,只需实现两个接口即可。

一. IVideoCapturer接口  (音频对应 IAudioCapturer)

  OMCS.Engine.Video.IVideoCapturer定义了视频采集器的基本功能,其用于采集RGB24原始格式或H264编码格式的图像,其定义如下:

    public interface IVideoCapturer :IDisposable
    {       
        /// <summary>
        /// 采集的数据是编码后的数据?(true表示H264,false表示RGB24)
        /// 比如:
        /// (1)从网络摄像头拿到的已编码的视频流。
        /// (2)从DynamicCameraConnector 的 FrameEncodedReceived 事件拿到的数据。
        /// (3)在部署相互关联的多套OMCS服务器时,可在桥接器上使用。
        /// 注意,若启用该属性,则在连接自己测试时,要将IMultimediaManager.Advanced.UseOriginImage4Myself设置为false。
        /// </summary>
        bool IsEncodedVideoData { get; }                

        /// <summary>
        /// 要采集的视频大小(分辨率),宽和高都修正为8的整数倍。
        /// </summary>
        Size VideoSizeRevised { get; }       

        /// <summary>
        /// 是否正在采集?
        /// </summary>
        bool IsVideoCapturing { get; }

        /// <summary>
        /// 开始采集
        /// </summary>
        void StartVideo();

        /// <summary>
        /// 停止采集
        /// </summary>
        void StopVideo();

        /// <summary>
        /// 修改采集的分辨率。
        /// IVideoCapturer内部应按顺序执行如下动作:
        /// 停止采集 =》 更改分辨率 =》 触发VideoSizeChanged事件 =》 启动采集 
        /// </summary>        
        void ChangeVideoSize(Size newSize);

        /// <summary>
        /// 当采集完一帧时,触发此事件。事件参数: (byte[])图像数据 - (bool)如果是编码后的数据,则表示是否为关键帧。
        /// </summary>
        event CbGeneric<byte[],bool> VideoCaptured;

        /// <summary>
        /// 当采集发生错误时,触发此事件。
        /// </summary>
        event CbGeneric<Exception> VideoError;

        /// <summary>
        /// 当采集的分辨率发生变化时,触发此事件。
        /// </summary>
        event CbGeneric<Size> VideoSizeChanged;
    }

(1)在定义实现该接口的类时,可以通过类的构造函数传入三个参数:设备的Index、采集的分辨率、采集的帧频。

(2)OMCS会在合适的时候调用Start方法启动注入的采集器,采集器启动后,当每采集到一帧视频时,就触发VideoCaptured事件。OMCS内部预定了该事件,以获取采集到的图像数据。

(3)注意,采集得到的图像分辨率的宽或高若不是8的整数倍,则需要将其裁剪成8的整数倍后,再触发VideoCaptured事件。裁剪为8的整数倍的代码如下所示:

        public Bitmap RoundSizeBy8(Bitmap origin)
        {
            if (origin.Width % 8 == 0 && origin.Height % 8 == 0)
            {
                return origin;
            }

            int newWidth = origin.Width / 8 *  8;
            int newHeight = origin.Height / 8 * 8;

            Bitmap newImg = new Bitmap(newWidth, newHeight);
            Graphics g = Graphics.FromImage(newImg);
            g.DrawImage(origin, new Rectangle(0, 0, newWidth, newHeight));
            g.Dispose();

            return newImg;
        }

(4)如果在采集的过程中,采集器发生了任何异常,请通过触发VideoError事件来通知OMCS框架。

(5)如果在采集的过程中,更改了采集器采集的分辨率,请通过触发VideoSizeChanged事件来通知OMCS。

   请特别注意VideoCaptured事件参数的含义:当IsEncodedData为false时,表示是RGB24数据,那么VideoCaptured输出的并不是一个Bitmap的完整数据,而是不包含位图header的核心数据(OMCS通过设定的采集的分辨率来推断位图header的信息)。从Bitmap转为不包含头的核心数据的代码如下所示:

    public byte[] GetBitmapCoreData(Bitmap bm)
    {
        int buffSize =bm.Width * bm.Height * 24 / 8;
        byte[] destBuff = new byte[buffSize];
        Rectangle bmRect = new Rectangle(new Point(0, 0), new Size(bm.Width, bm.Height));
        BitmapData data = bm.LockBits(bmRect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
        Marshal.Copy(data.Scan0, destBuff, 0, destBuff.Length);
        bm.UnlockBits(data);
        return destBuff;
    }

  如果视频采集器采集到的本来就是位图核心数据(通常情况下都是如此),就不需要这层转换了。

       当然,如果 IsEncodedData为 true,表示VideoCaptured输出的就是H264编码帧(I帧或P帧)。

(6)对于声音扩展,OMCS支持接入的音频格式包括:PCM、AAC、Speex。

二. IVideoCapturerFactory接口 (音频对应 IAudioCapturerFactory)

  在实现完IVideoCapturer接口后,我们还需要实现简单的OMCS.Passive.IVideoCapturerFactory接口。   

    public interface IVideoCapturerFactory
    {
        /// <summary>
        /// 创建一个新的视频采集器实例。
        /// 如果返回null,则表示使用框架内置的视频采集器。
        /// </summary>
        /// <param name="deviceIndex">摄像头索引</param>       
        IVideoCapturer CreateVideoCapturer(int deviceIndex);        
    }

          可以按如下逻辑来实现IVideoCapturerFactory的方法:

           实现CreateVideoCapturer方法:判断deviceIndex所对应的视频设备是否是特殊的类型,如果是,则new一个我们刚实现的视频采集类的实例返回;

         如果不是,则返回null,表示使用框架内置的视频采集程序。

三.注入到OMCS

   在调用IMultimediaManager的Initialize方法之前,先new一个上面实现的Factory类,然后将其赋值给IMultimediaManager的VideoCapturerFactory属性(音频对应 AudioCapturerFactory属性)。这样,就完成对OMCS视频设备的扩展。  

四.OMCS 扩展语音视频 Demo

(1)简单的视频扩展

       下载:OMCS.SimpleExtendVideoDemo 源码。 

       首先,我们给出一个简单的Demo的源码来示范如何扩展OMCS的视频设备。

       本demo中的示例是模拟了一个视频采集器,这个采集器会使用几张图片来模拟采集到的视频帧。其过程大致如下:当客户端启动时,从运行目录下的TestImages文件夹中加载所有的示例图片文件,等采集开始时(Start方法被调用),就启动一个采集线程,轮流使用这些图片来触发VideoCaptured事件,每隔1秒就换一张图片。

        Demo运行示意图如下所示:

       

(2)接入海康网络摄像头 IP Camera 或 RTMP流

      下载:OMCS.ExtendVideoDemo 源码。

      很多客户希望能将网络摄像头或RTMP流接入OMCS,这样就可以在PC或手机上查看网络摄像头的监控视频或RTMP流视频,甚至还可以将网络摄像头视频或RTMP流接入到基于OMCS开发的视频会议系统中。

      这里,我们就以海康的网络摄像头(型号:DS-IPC-T12H-IA)为例,将其采集的视频数据(H264)和音频数据(AAC)接入到OMCS中。具体细节请参阅源码。

      如此,我们就可以像使用本地PC的USB摄像头与麦克风一样来使用海康网络摄像头和RTMP流了。 

Demo中采用的技术:

海康摄像头:使用SDK接入(海康提供的HCNetSDK.dll)。

RTMP    流:使用NPuller拉流组件接入。

         

下一篇:OMCS 开发手册(08) -- 多人语音/视频

上一篇:OMCS 开发手册(06) -- 分离信道

--------------------------------------------------------------------------------------------------------------------  

下载免费版本的OMCS以及 demo源码

阅读 更多OMCS开发手册系列文章

Q Q:168757008

官网: www.oraycn.com

导航

首页

官方网站

联系我们

站内搜索

OrayTalk 企业即时通讯系统

傲瑞通官网

详细说明

客户端下载

OrayMeeting 视频会议系统

详细说明

客户端下载

ESFramework 通信框架

详细说明

SDK与Demo下载

ESFramework FAQ

版本变更记录

OMCS 语音视频框架

详细说明

SDK与Demo下载

OMCS FAQ

版本变更记录

OVCS 视频会议Demo

详细说明

源码下载

傲瑞实用组件

SDK下载

H5Media 纯网页音视频交互

NPusher 推流组件

MCapture 语音视频采集组件

MFile 语音视频录制组件

MPlayer 语音视频播放组件

OAUS 自动升级系统

StriveEngine 轻量级的通信引擎

傲瑞组件 FAQ

授权

授权流程

产品选购指南

授权方案说明

授权SDK使用说明

其它

支持信创国产化

SDK使用技巧

联系我们