视频会议是如何实现屏幕标注功能的?

现在主流的视频会议软件都有屏幕标注功能,屏幕标注功能给屏幕分享者讲解分享内容时提供了极大的方便。那我们以傲瑞视频会议(OrayMeeting)为例,来讲解屏幕标注是如何实现的。

傲瑞会议的PC端(Windows、信创Linux、银河麒麟、统信UOS)在分享自己的屏幕时,可在屏幕上进行标注、绘制功能。如下图,是傲瑞会议在银河麒麟V10SP1上演示的屏幕标注功能:

屏幕标注的工具有:自由曲线(涂鸦)、箭头、矩形、圆和椭圆、文本。并且可设置它们的颜色、线条粗细、字体大小。

那么,这样的屏幕标注功能是怎么实现的了?

细想一下,这个屏幕标注实际上就像是一个可以在上面绘制涂鸦的电子白板,只要将电子白板的背景设置为透明,然后,重新定义其工具栏就可以了。而我们的OMCS实时音视频框架内置了电子白板的功能,所以,可以直接使用OMCS来实现标注功能。

为了方便讲解其代码层面是如何实现的,我们在OMCS入门demo的白板功能(使用WhiteBoardConnector
)演示的窗口上,增加一个动态桌面连接器(DynamicDesktopConnector),并预定动态桌面连接器相关事件。

           public WhiteBoardForm(string _ownerID){InitializeComponent();this.whiteBoardConnector1.WatchingOnly = false;this.ownerID = _ownerID;this.Text = string.Format("正在访问{0}的电子白板", this.ownerID);// 需要在设计界面将电子白板连接器的背景改为透明(属性已修改)this.whiteBoardConnector1.ConnectEnded += new CbGeneric<ConnectResult>(whiteBoardConnector1_ConnectEnded);this.whiteBoardConnector1.BeginConnect(this.ownerID);        this.dynamicDesktopConnector1.ConnectEnded += new CbGeneric<ConnectResult>(DynamicDesktopConnector1_ConnectEnded);        // 将动态桌面连接器控件设置在当前窗口this.dynamicDesktopConnector1.SetViewer(this);this.dynamicDesktopConnector1.BeginConnect(this.ownerID);        }private void DynamicDesktopConnector1_ConnectEnded(ConnectResult obj){if (this.InvokeRequired){this.BeginInvoke(new CbGeneric<ConnectResult>(this.DynamicDesktopConnector1_ConnectEnded), obj);}else{if (obj != ConnectResult.Succeed){MessageBox.Show("连接失败!" + obj.ToString());}          }}

在Demo的UI上点击开始“远程桌面(标绘)”按钮时,我们开始初始化电子白板连接器及动态桌面连接器,连接到目标会议室的房间ID。

这里有几点要注意一下:

(1)电子白板连接器控件的背景色 BackgroundColor 要设置成透明。

(2)必须要使用DynamicDesktopConnector组件,而不能使用DesktopConnector控件。

(3)DynamicDesktopConnector组件所使用的显示屏幕图像的Viewer必须是Form,而不能是Control,否则,电子白板连接器控件的背景透明就无法实现(可能是WinForm的限制)。

(4)所以,UI的整体结构层次是:底层是Form(DynamicDesktopConnector使用该Form的表面来绘制屏幕图像),上层是WhiteBoardConnector控件,背景透明,用于实现标注。

上面的这个Demo已经比较具体的说明了屏幕标注功能的代码实现,傲瑞视频会议的屏幕标绘功能也正是基于同样的思路实现的,只不过其不仅仅支持Windows,同时也适配了信创操作系统,包括银河麒麟、统信UOS等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Framework开发入门(一)之源码下载

一、使用Linux操作系统的小伙伴可以跳转到官网链接按提示操作 官网源码地址&#xff1a;下载源代码 | Android Open Source Project 1.创建一个空目录来存放您的工作文件。为其指定一个您喜欢的任意名称&#xff1a; mkdir WORKING_DIRECTORYcdWORKING_DIRECTORY …

改进爬山算法之四:概率爬山法(Probabilistic Hill Climbing,PHC)

概率爬山法(Probabilistic Hill Climbing,PHC)是一种局部搜索算法,它结合了随机性和贪婪搜索的特点,是对爬山算法(Hill Climbing Algorithm)的一种变体或扩展。与传统的爬山法不同,PHC不是总是选择最优的邻居作为下一步的移动,而是以一定的概率选择最优邻居,同时以一…

Unity中实现人物残影效果

今天火柴人联盟3公测了&#xff0c;看到一个残影的效果&#xff0c;很有意思&#xff0c;上网查询了一下实现方式&#xff0c; 实现思路&#xff1a; 将角色的网格复制出来&#xff0c;然后放置到新建的物体的MeshFilter组件上&#xff0c;每隔几十毫秒在玩家的位置生成一个&a…

C#实现调用DLL 套壳读卡程序(桌面程序开发)

背景 正常业务已经支持 读三代卡了&#xff0c;前端调用医保封装好的服务就可以了&#xff0c;但是长护要读卡&#xff0c;就需要去访问万达&#xff0c;他们又搞了一套读卡的动态库&#xff0c;为了能够掉万达的接口&#xff0c;就需要去想办法调用它们提供的动态库方法&…

自动挡有什么优势

自动挡汽车相比手动挡汽车具有多方面的优势&#xff0c;以下是对这些优势的详细阐述&#xff1a; 一、操作简便性 无需手动换挡&#xff1a;自动挡汽车不需要驾驶员手动操作离合器和换挡杆&#xff0c;只需通过油门和刹车踏板来控制车速&#xff0c;大大降低了驾驶难度。这使…

菜鸟带新鸟——基于EPlan2022的部件库制作(3D)

设备逻辑的概念&#xff1a; 可在布局空间 中和其它对象上放置对象。可将其它对象放置在 3D 对象上。已放置的对象分到组件的逻辑结构中。 将此属性的整体标识为设备逻辑。可使用不同的功能创建和编辑设备逻辑。 设备的逻辑定义 定义 / 旋转 / 移动 / 翻转&#xff1a;组…

小程序基础 —— 07 创建小程序项目

创建小程序项目 打开微信开发者工具&#xff0c;左侧选择小程序&#xff0c;点击 号即可新建项目&#xff1a; 在弹出的新页面&#xff0c;填写项目信息&#xff08;后端服务选择不使用云服务&#xff0c;开发模式为小程序&#xff0c;模板选择为不使用模板&#xff09;&…

Android Java 版本的 MSAA OpenGL ES 多重采样

最近多次被小伙伴问到 OpenGL 多重采样&#xff0c;其实前面文章里多次讲过了&#xff0c;就是构建2个缓冲区&#xff0c;多重采样缓冲区和目标解析缓冲区。 代码流程 // Framebuffer IDs private int msaaFBO; private int msaaColorBuffer; private int msaaDepthBuffer;pr…

Markdown语法字体字号讲解

学习目录 语法详解改变字体样式[电脑要自带该样式字体]改变局部字号全局字体字号的设置使用场景及应用实例 > 快来试试吧&#x1f603; &#x1f447; &#x1f447; &#x1f448;点击该图片即可跳转至Markdown学习网站进行 Markdown语法字体字号讲解&#x1f448;点击这里…

Spring boot处理跨域问题

Spring boot处理跨域问题 方案一方案二推荐解决方案注意 方案一 实现WebMvcConfigurer的addCorsMappings方法 Configuration public class InterceptorConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMappin…

TOTP双因素认证(2FA)php简单实现

TOTP身份验证的工作原理基于时间戳和密钥。用户需要在设置阶段将密钥与相应的身份验证器进行绑定。通常&#xff0c;用户会在需要使用TOTP动态验证码的APP或网站上获得一个密钥&#xff0c;然后将该密钥添加到TOTP验证器工具上。验证器会根据当前的时间戳和密钥生成一个一次性密…

day21——web自动化测试(3)Unittest+Selenium实战小案例

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 今日目标&#xff1a; 1、UnitTest框架 2、UnitTest 核心用例 2.1 TestCase 2.2 TestSuite 2.3 TestRunner 2.4 TestLoader 2.5 TestLoader 与 TestSuite的区别 2.6 Fixture 3、断言 3.1 1230…

【Flink运行时架构】系统构架

SMP架构 数据处理系统的架构最简单的实现方式就是单节点&#xff0c;但是随着数据量的增大&#xff0c;为了使单节点的机器性能更加强大&#xff0c;需要增加CPU数量和加大内存来提高吞吐量。这就是所谓的SMP(Symmetrical Multi Processing,对称多处理)架构。 但是这种架构带来…

CountDownLatch应用举例

定义 CountDownLatch是juc下的一个多线程锁&#xff0c;下面是jdk对它的定义 A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 翻译如下 一种同步辅助工具&#xff0c;允许一个或多个…

ADC(二):外部触发

有关ADC的基础知识请参考标准库入门教程 ADC&#xff08;二&#xff09;&#xff1a;外部触发 1、TIM1的CC1事件触发ADC1DMA重装载2、TIM3的TRGO事件(的更新事件)触发ADC1DMA重装载3、TIM3的TRGO事件(的捕获事件)触发ADC1DMA重装载4、优化TIM3的TRGO事件(的捕获事件)触发ADC1D…

磁盘分区格式

MBR和GPT ‌磁盘分区形式主要有两种&#xff1a;MBR和GPT。‌‌ MBR&#xff08;Master Boot Record&#xff09; MBR是一种较旧的分区形式&#xff0c;首次引入于1983年的IBM PC DOS 2.0。它位于驱动器的第一个扇区&#xff0c;包含460字节的引导代码、64字节的磁盘分区表和…

几个支持用户名密码的代理链工具: glider, gost, proxychains+microsocks

几个支持用户名密码的代理链工具: glider, gost, proxychainsmicrosocks gost -L:7777 -Fsocks5://192.168.2.20:7575 -Fsocks5://user:passwd1.1.1.1:10086 -Dgost&#xff1a;(https://github.com/ginuerzh/gost) 参考 https://www.quakemachinex.com/blog/279.html

量子退火与机器学习(1):少量数据求解未知QUBO矩阵,以少见多

文章目录 前言ー、复习QUBO&#xff1a;中药配伍的复杂性1.QUBO 的介入&#xff1a;寻找最佳药材组合 二、难题&#xff1a;QUBO矩阵未知的问题1.为什么这么难&#xff1f; 三、稀疏建模(Sparse Modeling)1. 欠定系统中的稀疏解2. L1和L2的选择&#xff1a; 三、压缩感知算法(C…

【连续学习之SSL算法】2018年论文Selfless sequential learning

1 介绍 年份&#xff1a;2018 期刊&#xff1a; arXiv preprint Aljundi R, Rohrbach M, Tuytelaars T. Selfless sequential learning[J]. arXiv preprint arXiv:1806.05421, 2018. 本文提出了一种名为SLNID&#xff08;Sparse coding through Local Neural Inhibition and…

关于SNAT、DNAT及浮动地址

SNAT、DNAT SNAT、DNAT就是实现代理的功能。 SNAT 类似于客户端代理&#xff1a;内网主机通过共享公网 IP 地址访问外部服务。DNAT 类似于服务端代理&#xff1a;外部请求通过公网 IP 转发到内网主机上的服务。 没有大网地址的内部主机想要作为客户端访问外部网络&#xff08;主…