OMCS FAQ -- OMCS 常见问题解答
关于在使用语音视频框架OMCS过程中遇到的常见问题,我们做了一个整理总结,并给出了解决问题的步骤或方案,大家可以按照指定的步骤发现和解决问题。
首先,我们先明确一下OMCS框架中的Owner与Guest的含义。假设A使用一个CameraConnector连接到B的摄像头,那么,B就是作为Owner方,A作为Guest方。B是摄像头的Owner,A是连接到摄像头的Guest。当然,在视频聊天系统中,双方通常是互为Owner和Guest的。
一. 常见错误信息解决
错误1: 试图加载格式不正确的程序。
解 答: VS开发环境->项目->属性->生成->目标平台,设置为x86。
如果只是某台Win7报此错误,则需要在这台电脑上安装补丁:Universal C Runtime (CRT)
错误2: Unable to load DLL 'OraycnCodecs.dll' ,或者:无法加载DLL“OraycnCodecs.dll”,找不到指定的模块。
解 答: 缺少非托管库(C++的dll),可以从Demo的debug目录下,或者OMCS SDK压缩包中,将这些dll拷贝到运行目录下。
这些非托管库dll有:OraycnCodecs.dll、avcodec.dll、avutil.dll、dxbase.dll、swresample.dll、msvcp140.dll、vcruntime140.dll、vcomp140.dll。
上述操作完成后,如果还报同样的错误,则参考如下方案:
(1)如果是Win7,则需要安装补丁:Universal C Runtime (CRT)
(2)如果是Windows Server 2008 / 2012,则需要安装两个补丁:Universal C Runtime (CRT) 01 、 CRT02
错误3: Error on connecting OMCS server. cause : VersionMismatched.
解 答: 客户端和服务端的OMCS的版本不一致,必须保证客户端和服务端的OMCS.dll这个文件是同一个文件。
错误4: 客户端IMultimediaManager的Initialize方法抛出异常:Timeout waiting for reply ! 或者 Timeout to connect server !
解 答:(1)客户端和服务端的UserID的最大长度是否一致。可查找 GlobalUtil 的 SetMaxLengthOfUserID 静态方法。
(2)ping一下服务器,看到服务器的网络情况如何。
(3)如果使用的是OMCS的试用版本,则检查SDK是否已经过期。
错误5: Error on connecting OMCS server . error code is 1678.
解 答: OMCS服务端和客户端的 SystemToken 设置的不一致。
客户端对应 IMultimediaManager 的 SystemToken 属性,服务端对应的是 OMCSConfiguration 的 SystemToken 属性。它们默认值都是空字符串(String.Empty)。
错误6: OMCS Expired! Please contact to www.oraycn.com。
解 答: 试用版的OMCS已经过期,请从官网下载最新的OMCS开发包。
错误7: 失败索引和计数必须引用该缓冲区内的位置。(Index and count must refer to a location within the buffer .)
解 答: (1)客户端和服务端的OMCS的版本不一致,必须保证客户端和服务端的OMCS.dll这个文件是同一个文件。
(2)服务端与客户端UserID的最大长度的设置必须一致。
错误8: OMCS客户端运行目录下没有生成OmcsLog.txt文件?
解 答: (1)查看客户端文件夹目录有没有写的权限。
(2)客户端exe必须要先解压后,再双击exe运行,而不是双加压缩包中的exe运行。
错误9: OMCS Linux 版本报错:Unable to load shared library 'libOraycnMedia.so' or one of its dependencies .
解 答: (1)确认 libOraycnMedia.so 的架构与当前CPU的架构是否一致?如果不一致,请更换对应架构的 libOraycnMedia.so 及其依赖文件。
(2)查看 libOraycnMedia.so 的所有依赖库是否都存在,在终端执行命令:ldd -d libOraycnMedia.so 。根据结果,看具体缺少的是哪个库。
(3)如果是GLIBC的版本不对,可以查看当前系统GLIBC的版本,在终端执行命令:getconf GNU_LIBC_VERSION 。
二. 综合问题
问题1: 如何修改UserID的最大长度?
解 答: OMCS.GlobalUtil.SetMaxLengthOfUserID()静态方法。客户端和服务端都需要设置(在调用OMCS的其它代码之前设置),且要设置成一致的。
问题2: 如何修改语音视频数据的传输通道(P2P传送、或经过服务器中转)?
解 答: IMultimediaManager的ChannelMode属性。
问题3:OMCS与业务要求的权限如何结合?
解 答:OMCS本身并没有任何访问权限的控制,即,只要A用户在线,其它任何在线用户都可以连接到A的摄像头、麦克风、桌面。如果要加入访问权限的控制,则需要在OMCS之外来做这件事情。比如,可通过ESFramework实现类似的需求:B向A发起视频聊天请求,只有收到A回复的同意消息之后,B方的CameraConnector才去连接A的摄像头。
问题4:(语音、视频、桌面)连接器 如何实现断线重连?
解 答:OMCS客户端与OMCS服务器之间的TCP连接断开(掉线)时,会导致所有的连接器(如CameraConnector)都与目标设备断开。此时,OMCS客户端会启动自动重连,重连服务器成功后, IMultimediaManager将触发ConnectionRebuildSucceed事件。但是,请注意,这个TCP重连成功并不会导致已经断开的连接器去自动重连目标设备。若要实现连接器的重连,我们可以预定ConnectionRebuildSucceed事件,在其事件处理函数中,调用连接器的BeginConnect方法即可。
问题5:多媒体连接器在BeginConnect的时候连不上目标设备?
解 答:我们可以预定连接器的ConnectEnded事件,然后,查看事件参数ConnectResult的值。
(1)Timeout : Owner和Guest都要ping一下服务器,看延迟和丢包,如果一方丢包严重,则是网络问题导致。
(2)DeviceInvalid : Owner用设备测试程序测试设备,若设备不可用则更改MultimediaManager的对应设置,改为可用的设备索引。
(3)ExceptionOccured: 查看运行目录下的日志文件OmcsLog.txt。
(4)SelfOffline: 待重连成功后再看。
(5)ChannelUnavailable: 待重连成功后再看。
问题6:在Win7上视频通话/远程桌面时,CPU占用过高,需要怎么优化了?
解 答:在Win7电脑上可以安装微软常用运行库:MSVBCRT AIO 2018.01.15 。
三. 摄像头相关:
1.两个人视频聊天的时候,声音卡、视频卡,是怎么回事?
声音卡、视频卡 90%以上都是网络的原因,可按如下步骤排查:
(1)视频对话的双方都持续的ping 服务器,观察延迟、抖动、丢包等情况。
(2)视频对话的双方都需要测试与服务器之间的上行、下行速度。
(3)OMCS 带宽占用及网络品质测试 一文中有对上述测试方法的详细描述。双方在测试过程中,请多截几张图。
如果按上述排查后,仍然有疑惑,则可将双方测试结果的截图发给我们客服,同时将类似下面更具体的情况告诉我们,我们会协助您分析。
(4)摄像头分辨率为多大?视频图像的清晰度如何?(对应IMultimediaManager的CameraVideoSize和CameraEncodeQuality属性)
(5)是一方卡,还是双方都卡?
(6)仅仅进行语音对话,是否也卡?
(7)电脑上是否有同时运行其它占用网络的软件(如下载软件、在线看电影等)?观察任务管理器,看看是否有其它软件消耗了大量的CPU?
(8)如果装有杀毒软件、防火墙,则关掉它们试试。
(9)双方都下载我们的OrayTalk客户端,使用OrayTalk进行语音视频聊天,对比一下效果。
2.看不到对方的视频图像?
如果CameraConnector(或DynamicCameraConnector)连接到对方的摄像头,但是却看不到视频图像,则可按照以下步骤排查:
(01)预定CameraConnector的ConnectEnded事件,看看该事件参数ConnectResult的值,该枚举值说明了连接摄像头失败的各种原因。
(02)如果上述ConnectResult的值为Succeed,则在对方(即摄像头的Owner),使用设备测试程序,测试一下目标摄像头是否正常?
CameraDeviceIndex 被设置错误是最常见的,比如电脑上只有一个摄像头(index为0),而CameraDeviceIndex却被设置为1。
或者,存在多个摄像头(比如虚拟摄像头等),但是 CameraDeviceIndex指向的那个摄像头是无效的。
日志中可能有类似这样的日志:Current camera [ index : 1 ] is invalid !
(03)查看CameraConnector的OwnerOutput属性,看Owner是否禁止了视频输出。(或查看Owner方的IMultimediaManager的OutputVideo属性)。
(04)如果使用的是 OMCS.Windows.WpfCameraPanel ,则其所在的Window 的 AllowsTransparency 属性需要设置为 false 。
(05)查看自己和Owner方的日志文件。(OMCS框架会将错误和异常自动记录到默认的日志文件,即运行目录下的 omcsLog.txt 文件)
(06)如果上述都正常,则分别查看Owner方和自己到服务器的上下行网络是否通畅?参考:OMCS 带宽占用及网络品质测试
3.视频图像闪烁
如果使用的是DynamicCameraConnector,在控件或窗体的表面上绘制,则该控件或窗体必须开启双缓冲机制。
或者,直接使用OMCS提供的开启了双缓冲的Panel控件:OMCS.Passive.Video.VideoPanel。
4.如何设置摄像头的采集分辨率?帧频?视频编码清晰度?
(1)客户端IMultimediaManager的CameraVideoSize属性,用于设置和修改摄像头采集的分辨率。
(2)客户端IMultimediaManager的CameraEncodeQuality属性,用于设置视频的编码清晰度,取值0~31,取值越小,清晰度越高。
注意:如果IMultimediaManager的Advanced的VideoQualityProtectEnabled属性为true,则OMCS内部会自动将设置的值修正到 2~15。
(3)客户端IMultimediaManager的MaxCameraFrameRate属性,用于设定摄像头采集的帧频。
-- 注意,如果网络拥塞,OMCS内部会自动丢弃某些视频帧,所以MaxCameraFrameRate参数设定的是可能的最大帧频。
如果AutoAdjustCameraEncodeQuality属性设置为true,OMCS框架会根据网络情况自动调整视频编码的清晰度。
5.导致视频不清晰(有锯齿、毛边、小方块)的原因?
(1)摄像头采集的分辨率小于显示窗口的尺寸。比如,采集的分辨率为320x240,而显示窗口大小是640X480,那就相当于把图片放大了4倍,就不可能清晰了。
(2)视频编码质量的参数(CameraEncodeQuality)设置得低。如3所述,视频质量默认是自动调节的。我们可以将AutoAdjustCameraEncodeQuality设置为false以关闭自动调节,并将CameraEncodeQuality设置为2(高清晰)。这样做的前提是,通信双方之间的网络质量良好。
6.Camera's origin output format [47504a4d-0000-0010-8000-XXXXXXXXXXX] is not supported !
这个日志属于正常现象。一个摄像头可以输出很多个格式,其中某个格式不被支持,就会写这个日志,但是只要有一个格式能被支持,就能正常使用了。
四. 麦克风相关:
1.听不到对方的声音?
如果MicrophoneConnector 连接到对方的麦克风,但是却听不到对方的声音,则可按照以下步骤排查:
(01)预定MicrophoneConnector 的ConnectEnded事件,看看该事件参数ConnectResult的值,该枚举值说明了连接麦克风失败的各种原因。
(02)如果上述ConnectResult的值为Succeed,则在对方(即麦克风的Owner),使用设备测试程序,测试一下目标麦克风是否正常?
(03)查看MicrophoneConnector 的OwnerOutput属性,看Owner是否禁止了声音输出。(或查看Owner方的IMultimediaManager的OutputAudio属性)。
(04)查看MicrophoneConnector 的Mute属性,看当前的麦克风连接器是否被静音了?
(05)查看自己和Owner方的日志文件。(OMCS框架会将错误和异常自动记录到默认的日志文件,即运行目录下的 omcsLog.txt 文件)
(06)如果上述都正常,则分别查看Owner方和自己到服务器的上下行网络是否通畅?
2.声音不连贯?
当网络不够顺畅或者繁忙时,语音对话的同时还在进行视频聊天或远程桌面,声音就可能会断断续续,除了信道分离这一方案外,还可以通过设置一些属性,来达到优先保证语音连贯的目的:
(a)IMultimediaManager的VideoFrameDisardedMode 设置为 FrameDisardedMode.DiscardWhenNeed。
(b)IMultimediaManager的AutoAdjustCameraEncodeQuality 设置为ture。
(c)降低摄像头的采集分辨率,其是由IMultimediaManager的CameraVideoSize属性控制的。
(d)如果存在桌面共享,则降低桌面的分辨率或清晰度。桌面的清晰度由IMultimediaManager的DesktopEncodeQuality属性控制。
对于多人语音视频(视频会议)系统,还可考虑以下相关因素:
(a)IMultimediaManager的AllowDiscardFrameWhenBroadcast 属性设置为 true。
(b)考虑关闭视频和远程桌面,只进行语音通话。
如果上述方案施行后,效果还不够理想,那就要从服务器部署、网络拓扑、服务器带宽方面进行网络调优,这是一个复杂的系统工程:目标用户主要分布在哪些城市?在哪个地方或哪些地方(分布式方案)部署服务器对整体目标用户而言综合效果最为理想?如何部署?是否需要支持双线或多线(电信、联通、移动、铁通等)?等等。
3.声音延迟大?
听到对方的声音延迟很大,这种情况除了网络延迟这一原因外,还有两个额外的延迟:
(1)Owner 方会攒够多个音频帧之后,再将它们打包发送。
在OMCS中,一个音频帧的长度为20ms,默认会攒够6个音频帧一起发送,这样导致的额外延迟就是 6 x 20 = 120 ms 。
通过设置 IMultimediaManager 的 Advanced 的 EncodedAudioFrameCountInPackage 属性可以修改每次发送的音频帧的个数。
(2)OMCS 使用的JitterBuffer(抖动缓冲区)机制会导致额外的延迟。
可以通过设定IMultimediaManager 的 Advanced 的 MinJitterBufferSize(默认值20) 和 MaxJitterBufferSize (默认值200)属性来限制JitterBuffer导致的最大延迟。在默认情况下,由JitterBuffer导致的额外的最大可能延迟为 200 x20 = 4000 ms ,即4秒钟。
4.在同一个房间中,多个人语音/视频聊天时,OMCS如何对发言控制权进行支持?
在类似于视频会议系统或在线培训系统中,通常涉及到多人同时语音的场景。首先,OMCS是支持多路混音的,也就是说在一个房间内,多个人可以同时发言,房间中的其它的人可以听到这几个人的声音。为了达到最好的效果,我们的经验是这样做:
(1)区分发言人和听众。
(2)同一时刻的发言人不超过2~3个,最好是1个。如果同一时刻很多人在说话,那听众根本就听不清楚说话的内容了。
(3)通常,发言人和听众的角色是动态变换的。
(4)通过动态设定IMultimediaManager的OutputAudio属性,来协同(3)的角色变换。若是发言者,其OutputAudio就设为true;如果是听众,其OutputAudio就设置为false。
(5)如果某人没有说话,但是其OutputAudio设置为true,那么其麦克风采集到的背景噪音对其它听众也是一种干扰。所以要谨慎,只有必要时,才将OutputAudio设置为true。
5.如何让背景声音的效果更好?
一般情况下,OMCS将优先保证对话过程中人说话的声音。如果我们的应用场景主要是为了听到远程采集到的环境声音(比如播放的音乐),那么,可以做如下设置:
将IMultimediaManager.Advanced 的 UseAEQ4Audio、UseAGC4Audio、UseNS4Audio 这三个属性都设置为 false 。
6.如何将自定义音源与麦克风的声音混音作为OMCS的音频输入?
在语音直播系统中,主播在说话的时候,可能需要播放背景音乐,希望能将背景音乐与自己说话的声音都传递给听众,类似这样的需求可以这样实现:
(1)将播放的音乐作为OMCS扩展音频输入(具体参见这里),比如播放wav音乐文件,则需要从文件中读取PCM数据,然后实现IAudioCapturer接口。
(2)注意,OMCS要求扩展的音频数据必须满足的条件是,位数:16bit,采样率:16000,1声道。如果原始数据的特征不是如此,需要对数据做转换处理。
(3)实现 IAudioCapturerFactory 接口,并将其注入到 IMultimediaManager 的 AudioCapturerFactory属性。
(4)实现 IAudioCapturerFactory 接口时,只要实现其CreateAudioCapturer4MixInput()方法,方法中返回(1)的IAudioCapturer实现的类的实例。
(5)设定IMultimediaManager 的 AudioInputMode 属性为 BothExtendAndMicrophone(将自定义扩展音源与麦克风混音作为输入)。
说明:这个方案会遇到的可能比较麻烦的地方在于:
(1)音乐文件不是wav格式,而可能是mp3,这样就需要自行完成mp3的解码,并得到解码后的PCM数据。
(2)实现IAudioCapturer接口在触发IAudioCapturer的AudioCaptured事件时,要注意控制每隔10ms触发一次,并且每次暴露的是10ms的音频数据。
五.远程桌面相关:
1.看不到对方的屏幕图像?
如果DesktopConnector(或DynamicDesktopConnector)连接到对方的桌面,但是却看不到视频图像,则可按照以下步骤排查:
(01)桌面的Owner方:使用的是vps虚拟机或是没显示器?或者,系统启动了屏幕保护?或者,屏幕被锁定(Ctrl+Alt+Delete)?
(02)桌面的Owner方的应用程序是windows服务?或是没有UI的应用程序?这样的程序是没有权限获取屏幕图像的。(日志中会有类似“句柄无效”的记录)
(03)预定DesktopConnector的ConnectEnded事件,看看该事件参数ConnectResult的值,该枚举值说明了连接桌面失败的各种原因。
(04)查看DesktopConnector的OwnerOutput属性,看Owner是否禁止了桌面图像的输出。(或查看Owner方的IMultimediaManager的OutputDesktop属性)。
(05)如果使用的是 OMCS.Windows.WpfDesktopPanel ,则其所在的Window 的 AllowsTransparency 属性需要设置为 false 。
(06)分别查看Owner方和自己到服务器的上下行网络是否通畅?参考:OMCS 带宽占用及网络品质测试
(07)由于屏幕视频图像的数据量较大,所以当网络缓慢时,可能要等一段时间,才会出现屏幕图像。
此时,可考虑降低屏幕图像的清晰度:设定Owner方的IMultimediaManager的DesktopEncodeQuality属性。
(08)查看自己和Owner方的日志文件。(OMCS框架会将错误和异常自动记录到默认的日志文件,即运行目录下的 omcsLog.txt 文件)
2.远程桌面延迟是怎么回事?
(1)首先,我们要检查一下OMCS客户端设置的桌面采集帧频(即IMultimediaManager 的 MaxDesktopFrameRate属性)。这个值意味着在网络通畅的情况下,实际能达到的最大帧频。推荐MaxDesktopFrameRate的配置值:广域网设为3~5,局网设为6~10。
(2)接下来我们分析经常碰到的一个场景:A用户操作B的电脑桌面,有时反应很慢 -- 就是A做一个操作,要过几秒才能看到操作后的效果。这是什么原因导致的了?
在这个场景中,有两个方向的数据:(1)A方发操作命令经过Server到达B方;(2)B方将自己的屏幕图像经过Server发送给A方。
一般而言,操作命令的数据量非常小,只要网络通畅,延时会很小。而桌面图像数据虽然经过了编码压缩,但仍然还是很大,这就就对带宽有较高的要求。
### B会上传自己的桌面图像数据到Server。(上行)
### 同时,Server会将图像数据转发给A。(下行)
上行和下行是同时进行的,无论是哪个慢,都会导致延迟增大。
(3)另外,即使对同一个用户而言,其上行和下行的速度差别可能是非常大的。我们有过很多这样的经验:A操作B的桌面很流畅,延迟1~2秒;但是反过来,B操作A的桌面就很慢,延迟达到10秒甚至以上。这就说明:(1)A的下行很好,B的上行也很好;(2)A的上行很慢,或者B的下行很慢,或者A的上行和B的下行都很慢。
很慢的意思是:发送较大的数据量时,能达到的最高速度不高(因为路由上最窄的那个节点被塞满了)。但是,这种情况下,发送小块数据, 也许很快。
如何测试网络品质和监控网络品质,可以参考 OMCS 带宽占用及网络品质测试 。如果网络确实很慢,有什么办法可以减少延迟了?那只有降低桌面图像的流量,有两个方案:
### 将桌面的分辨率调低,或者只共享部分桌面区域(对应IMultimediaManager的 DesktopRegion 属性)。
### 降低桌面图像的编码清晰度(对应IMultimediaManager的 DesktopEncodeQuality 属性,可以动态调节)。
3.屏幕图像闪烁
如果使用的是DynamicDesktopConnector,在控件或窗体的表面上绘制,则该控件或窗体必须开启双缓冲机制。
或者,直接使用OMCS提供的开启了双缓冲的Panel控件:OMCS.Passive.RemoteDesktop.DesktopPanel。
4.远程桌面控制失效
(1)如果被控方是win10系统,当其打开任务管理器时,远程操作暂时失效,关闭任务管理器后,远程操作恢复正常。
这是因为被控端程序的执行权限不够导致的。解决方法:在win10机器上,以管理员身份运行(选中客户端程序->右键->以管理员身份运行)被控端即可。
(2)如果不是(1)描述的情况, 则查看被控端的电脑是否启动了360安全卫士等杀毒软件,可以退出它们后再次尝试。
这些杀毒软件会将远程控制当作是木马命令,进行拦截。要避免被杀毒软件拦截,可将开发的应用程序提交给杀毒软件官方进行认证。比如360的认证在这里。
(3)若上述操作仍不奏效,Win10可按如下操作:
打开控制面板,依次点击:用户账户>用户账户>更改用户账户控制设置,设置为“从不通知”;
打开编辑组策略,依次点击:计算机配置>Windows设置>安全设置>本地策略>安全选项;
找到并禁用下面两项:“用户账户控制:以管理员批准模式运行所有管理员”、“用户账户控制:用于内置管理员账户的管理员批准模式”;
最后,重启电脑即可。
5.如何实现 屏幕图像缩放?
如果要让屏幕图像的绘制始终填满整个控件的表面(自动拉伸图像),那可以将DesktopConnector的AdaptiveToViewerSize属性设置为true。
如果要让屏幕图像的绘制依据控件尺寸的大小进行等比缩放,并居中显示,则可借由OMCS.Boost(OMCS的增强库,可下载源码)提供的AutoScaleContainer快速实现:
(1)在Form窗口上拖放一个AutoScaleContainer控件。
(2)在刚才的AutoScaleContainer控件上拖放一个DesktopConnector控件。
(3)将DesktopConnector的AdaptiveToViewerSize属性设置为true。
(4)在DesktopConnector的ConnectEnded事件处理函数中,判断连接是否成功。如果成功,则调用AutoScaleContainer控件的Initialize方法进行初始化:
void desktopConnector1_ConnectEnded(ConnectResult result) { if (this.InvokeRequired) { this.BeginInvoke(new CbGeneric<ConnectResult>(this.desktopConnector1_ConnectEnded), result); } else { if (result != ConnectResult.Succeed) { MessageBox.Show("连接失败!" + result.ToString()); return; } this.autoScaleContainer1.Initialize(this.desktopConnector1, this.desktopConnector1.DesktopSize); } }
6.远程桌面的协助模式如何开启?
(1)被控方MultimediaManager的AllowControlDesktop属性要设置为true。
(2)主控方的将DesktopConnector的WatchingOnly属性设置为false。
7.远程桌面如何支持多显示器?
(1)将 IMultimediaManager 的 Advanced 的 DesktopJustInPrimaryScreen 属性设置为 false。(DesktopJustInPrimaryScreen :在远程桌面功能中,是否将共享的屏幕限制在主屏幕?)
(2)设置 IMultimediaManager 的 DesktopRegion 属性设置为要使用的那个显示器的 Rectangle。
注意:这两个属性都需要在 IMultimediaManager 的 Initialize 方法之前进行设置才有效。
六.电子白板相关:
1. 如何使用白板的课件功能?
3. 如何自定义工具栏?
--------------------------------------------------------------------------------------------------------------------
阅读 更多OMCS开发手册系列文章 。
Q Q:168757008
官网: www.oraycn.com