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开发手册系列文章 。
Q Q:168757008
官网: www.oraycn.com