OMCS Demo -- 远程录制或在服务器端录制语音、视频、屏幕
远程录制的意思是,客户端A希望录制客户端B的语音视频屏幕等数据;而在服务器端录制,实际上原理是一样的,我们只要在服务端集成一个虚拟的客户端用户就OK了。
本文我们以在服务器端录制为例,至于远程录制,大家只需要将本文的demo稍作修改就行。比如这样的需求:有个系统是一个在线培训系统,需要在服务端将指定老师的讲课(包括语音和视频)录制下来,并保存为.mp4文件,以便随时可以查阅这些文件。
本文我们就做一个demo实现类似的功能,演示如何在服务端录制某个指定在线用户的语音视频,并提供三种录制模式:录制语音视频、仅录制语音、仅录制视频。
一.实现原理
我们基于OMCS和MFile来实现上述场景描述的功能,下面是对应的原理。
(1)在OMCS的结构中,客户端之间可以相互获取到对方的摄像头和麦克风的数据,所以,服务端可以作为一个虚拟的客户端用户(比如ID为“_Server”),连接到同一个进程中的OMCS多媒体服务器。
(2)在服务端动态创建DynamicCameraConnector组件,连接到指定用户的摄像头。
(3)在服务端动态创建MicrophoneConnector组件,接到指定用户的麦克风。
(4)调用DynamicCameraConnector的GetCurrentImage方法,即可获得所连接的摄像头采集的视频帧。
(5)预定MicrophoneConnector的AudioDataReceived事件,即可获得所连接的麦克风采集的音频数据。
(6)使用MFile将上述结果进行编码并写入mp4文件。
注:如果需要录制用户的屏幕,则需要使用DynamicDesktopConnector组件,其也有GetCurrentImage方法,与DynamicCameraConnector使用方法几乎一样。
二.实现说明
下载Demo源码:RecordOnServerDemo.rar (原始版本)
RecordOnServerDemo_RecordProcess.rar (将录制从OMCS服务端中独立出来,每次录制二人视频会话时,就启动一个独立的录制进程)
(1)源码说明
如果熟悉OMCS和MFile的使用,理解上面的代码是非常容易的,而且本文这个Demo就是在语音视频入门Demo的基础上改写而成的,只是有几点是需要注意:
(1)由于在服务端录制时,不需要显示被录制用户的视频,所以不用设置DynamicCameraConnector的Viewer(即不用调用其SetViewer方法来设置绘制视频的面板)。
(2)同样,在服务端录制时,不需要播放被录制用户的语音,所以,将MicrophoneConnector的Mute属性设置为true即可。
(3)如果需要录制视频,则通过一个定时器(videoTimer)每隔100毫秒(即10fps)从DynamicCameraConnector采集一帧图片,并写入录制文件。
(4)如果是录制桌面,想同时录制鼠标位置,只要将DynamicDesktopConnector的WatchingOnly及ShowMouseCursor属性均设置为true即可。
(5)如果录制的仅仅是图像视频(不包括音频),采用的视频编码仍然为H264,但生成的录制文件也是.mp4文件,而非.h264文件,否则,生成的视频文件将无法正常播放。
(6)在服务端,最好将IMultimediaManager 的 Advanced 的DontUseAudioDevice属性设置为true,这样就可以不播放声音数据而只录制了。
(2)运行说明
服务端运行起来的截图如下所示:
测试时,可按如下步骤:
(1)启动demo的服务端。
(2)修改客户端配置文件中的服务器IP,然后,用不同的帐号在不同的机器上登录多个demo的客户端。
(3)在服务端界面上,点击“录制单人视频”,选择一个在线用户,点击“开始录制”按钮,录制结束后,将在服务端的运行目录下,生成以用户ID为名称的mp4文件。
(4)在服务端界面上,点击“录制两人视频”,选择两个在线用户,即可将两人的视频聊天过程录制成mp4文件。
更多参考:如何使用OMCS语音视频入门Demo在两个客户端之间相互视频对话。
三.扩展1:在客户端录制聊天双方的对话过程
我们切换到在二人对话的视频聊天系统中,聊天的一方希望将自己和对方对话的整个过程录制下来,包括语音和视频。 这就涉及到将自己的视频图像与对方的视频图像合成一个整体图像,自己的声音和对方的声音合成一路声音。
(1)图像合成
通过两个DynamicCameraConnector可以分别获得自己和对方的图像,然后通过GDI+技术即可将两张图片拼接成一张。
(2)声音合成
声音合成使用的是混音技术。OMCS已经在内部完成了这一功能,我们可以直接拿来使用。
OMCS提供的OMCS.Passive.Audio.AudioInOutMixer,AudioInOutMixer 混音器用于将本地话筒设备的输入数据以及本地声音播放的输出数据进行混音。所以,只需要调用AudioInOutMixer的Initialize方法,并预定其AudioMixed事件即可。AudioMixed事件提供的就是我们需要的最终的混音结果。请记住,当不再使用AudioInOutMixer时,请调用其Dispose方法释放混音器。
当然,如果希望自己实现混音,也是可以的。我们可以预定IMultimediaManager的AudioCaptured事件和AudioPlayed事件。AudioCaptured事件提供的数据就是自己麦克风采集到的数据,而AudioPlayed事件提供的数据就是播放的声音,即对方说话的声音。
这里有一个Demo供大家参考:如何实现:录制视频聊天的全过程?
四.扩展2:在服务端录制聊天双方的对话过程
(2019.07.04 该示例已经在 RecordOnServerDemo.rar 实现,大家可以下载源码参考了)
与上述的《扩展1:在客户端录制聊天双方的对话过程》基本类似。
(1)使用两个DynamicCameraConnector分别连接到两个对话者的摄像头获得他们的图像,然后通过GDI+技术即可将两张图片拼接成一张。
(2)使用两个MicrophoneConnector分别连接到两个对话者的麦克风,并使用MCapture组件的混音器进行混音,然后录制混音后的数据。
(3)使用MCapture组件进行混音时,需要先将MicrophoneConnector封装转换为IWaveCapturer接口。
public class WaveCapturer4MicrophoneConnector : IWaveCapturer { public event ESBasic.CbGeneric<byte[]> AudioCaptured; public WaveCapturer4MicrophoneConnector(OMCS.Passive.Audio.MicrophoneConnector connector) { connector.AudioDataReceived += new ESBasic.CbGeneric<byte[]>(connector_AudioDataReceived); } void connector_AudioDataReceived(byte[] data) { if (this.AudioCaptured != null) { this.AudioCaptured(data); } } }
(4)然后调用MCapture组件的CapturerFactory的CreateAudioMixter方法创建混音器IAudioMixter。
/// <summary> /// 创建混音器。 /// </summary> /// <param name="capturer1">采集器1。采样率16000,位数:16。</param> /// <param name="capturer2">采集器2。采样率16000,位数:16。</param> /// <param name="output2Channel">混音结果是否采用双声道?如果为true,则表示capturer1和capturer2的数据在混音结果中各占一个声道。</param> /// <returns>混音器</returns> public static IAudioMixter CreateAudioMixter(IWaveCapturer capturer1, IWaveCapturer capturer2, bool output2Channel);
(5)预定IAudioMixter的AudioMixed事件,即可得到混音后的数据。
五.扩展3:在服务端录制群组的语音聊天(群聊)
如果需要在服务端将群聊的过程录制下来,其原理与上述是一样的。在服务端使用一个虚拟的客户端用户登录OMCS,然后
(1)使用多个DynamicCameraConnector分别连接到每个成员的摄像头获得他们的图像,然后通过GDI+技术即可将这些图片拼接成一张。
(2)使用多个MicrophoneConnector连接到每个成员,再用 MicrophoneConnectorMixer 将这些MicrophoneConnector的声音数据进行混音。
一般而言,如果同时讲话的人数大于3个时,混音后的结果基本就很嘈杂了,所以,建议在设计群聊时,通过逻辑控制一下发言的权限,最多允许有三个人在同时说话, 关于类似的权限设计,可以参考 OMCS FAQ -- OMCS 常见问题解答 一文中的“麦克风相关”章节对“4.在同一个房间中,多个人语音/视频聊天时,OMCS如何对发言控制权进行支持?”的解答。
阅读 更多OMCS开发手册系列文章。
Q Q:168757008