实现Linux 视频聊天、远程桌面(源码,支持信创环境,可与Windows版、安卓版互通)

news2024/11/26 12:34:36

有朋友在下载并了解了《C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)》中提供的源码后,留言给我说,这个视频会议有点复杂了,代码比较多,看得有些费劲。问我能不能整个简单点的Demo,只要有视频聊天和远程桌面的功能就可以。于是,我就又写了一个Demo来供大家参考,客户端包括了Windows版本、Linux版本(包括国产OS,如银河麒麟、统信UOS、深度Deepin等)以及Android版本。

       下图是在银河麒麟V10上运行的截图:

视频聊天、远程桌面Demo在银河麒麟V10上运行 

一.功能介绍

1. 视频聊天

(1)每个登录的用户都可向其他任意在线用户发送视频聊天请求。

(2)当收到来自其他在线用户的视频聊天邀请时,可接受或拒绝对方的请求。

(3)当接受其他在线用户的视频聊天邀请时,即可开启视频聊天。 

2. 远程桌面

(1)每个登录的用户都可向其他任意在线用户发送远程桌面请求;当对方未响应时,可主动取消远程桌面请求。

(2)当收到来自其他在线用户请求控制桌面时,可接受或拒绝对方的请求。

(3)当发送方收到其他在线用户同意控制其电脑时,即可开启远程桌面连接。

(4)被控端和主控端都可主动断开远程桌面连接。 

二.开发环境

1.开发工具:

Visual Studio 2022 

2. 开发框架: 

.NET Core 3.1,.NET 6,.NET 7 

3.开发语言:

C#

4.其它框架:

CPF.net UI 框架、OMCS 语音视频框架 

三.具体实现

      下面我们讲一下Demo中核心的代码实现,大家从文末下载源码并对照着源码看,会更清楚些。

1.自定义消息类型 InformationTypes

    public static class InformationTypes
    {
        /// <summary>
                /// 视频请求 0
        /// </summary>
        public const int VideoRequest = 0;

        /// <summary>
                /// 回复视频请求的结果 1
        /// </summary>
        public const int VideoResult = 1;

        /// <summary>
                /// 通知对方 挂断 视频连接 2
        /// </summary>
        public const int CloseVideo = 2;

        /// <summary>
        /// 通知好友 网络原因,导致 视频中断 3
        /// </summary>
        public const int NetReasonCloseVideo = 3;

        /// <summary>
        /// 通知对方(忙线中) 挂断 视频连接 4
        /// </summary>
        public const int BusyLine = 4;

        /// <summary>
                /// 远程桌面请求 5
        /// </summary>
        public const int DesktopRequest = 5;

        /// <summary>
                /// 回复远程桌面请求的结果 6
        /// </summary>
        public const int DesktopResult = 6;

        /// <summary>
                ///  主动取消远程桌面请求 7
        /// </summary>
        public const int CancelDesktop = 7;

        /// <summary>
                ///  对方(主人端)主动断开远程桌面 8
        /// </summary>
        public const int OwnerCloseDesktop = 8;

        /// <summary>
                /// 客人端断开远程桌面连接 9
        /// </summary>
        public const int GuestCloseDesktop = 9;
    }

2. 发送视频请求

(1)当发起视频聊天时,将显示视频聊天窗口 

/// <summary>
/// 显示视频聊天窗口
/// </summary>
/// <param name="wait">true表示自己为发送端</param>
public void RequestVideo(bool wait)
{
  if (videoChat == null)
  {
    videoChat = DoCreateVideoChatForm(wait);
  }
  videoChat.Show();
  IMultimediaManager mgr = MultimediaManagerFactory.GetSingleton();
  if (mgr == null)
  {
    CommonHelper.ShowToolTip("无法启动多媒体设备!");
    ClearVideoChat();
    return;
  }
  this.videoChat.Initialize(mgr);
  this.videoChat.SendVideoRequest(wait);
}

(2)连接自己的摄像头并发送视频通话请求

/// <summary>
/// 发送视频通话请求
/// </summary>
/// <param name="isSend">是否为发送者</param>
internal void SendVideoRequest(bool isSend)
{
  this.StackPanel_Camera_myself.Visibility = Visibility.Visible;
  this.dynamicCameraConnector_myself.ConnectEnded += DynamicCameraConnector_myself_ConnectEnded;
  this.dynamicCameraConnector_myself.SetViewer(this.image_camera_myself);
  this.dynamicCameraConnector_myself.BeginConnect(this.currentUserID);
  if (isSend)
  {
    this.time_tip.Content = "正在等待对方回复";
    App.multimediaManager.SendCustomizedMessage(this.friendID, InformationTypes.VideoRequest,null, null);
  }
}

3. 回复对方视频请求

(1)当收到对方的视频聊天邀请时,将显示视频邀请窗口  

(2)发送回复视频聊天请求消息

/// <summary>
/// 是否同意视频聊天请求
/// </summary>
/// <param name="isReceive">true表示同意,false表示拒绝</param>
private void ReplyVideoRequest(bool isReceive)
{
  try
  {    byte[] vs = BitConverter.GetBytes(isReceive);
    App.multimediaManager.SendCustomizedMessage(this.friendId, InformationTypes.VideoResult, vs,null);
    if (isReceive)
    {
      App.mainWindow.RequestVideo(false);
      App.mainWindow.SetCurrentVideo(this.friendId);
    }
    else
    {
      CommonHelper.ShowToolTip("已拒绝对方视频通话邀请");
    }
    Close4BtnClick = true;
    App.mainWindow.ClearVideoRequest();
  }
  catch(Exception e)  {
    LoginWindow.FileAgileLogger.Log(e, "VideoRequestWindow.ReplyVideoRequest", ESBasic.Loggers.ErrorLevel.Standard);
  }
}

4. 收到对方视频请求的回复

/// <summary>
/// 视频请求,收到对方回复
/// </summary>
/// <param name="OtherIsAgree">true表示同意,false表示拒绝</param>
internal void SendVideoRequestResult(bool OtherIsAgree)
{
  if (OtherIsAgree)
  {
    this.OnAgree(this.friendID);
    App.mainWindow.SetCurrentVideo(this.friendID);
  }
  else
  {
    CommonHelper.ShowToolTip("对方拒绝与您进行视频通话");
    App.mainWindow.ClearVideoChat();
  }
}

当对方回复同意时,将连接到对方的麦克风和摄像头,开始视频聊天会话:

/// <summary>
/// 对方同意视频会话
/// </summary>
public void OnAgree(string destLoginID)
{
  try
  { 
    startTime = DateTime.Now;
    timer.Start();
    this.friendLoginID = destLoginID != null? destLoginID: this.friendName;
    this.lab_title.Content = string.Format("正在和{0}视频会话", this.friendName);
    this.dynamicCameraConnector1.BeginConnect(this.friendLoginID);
    this.microphoneConnector1.BeginConnect(this.friendLoginID);
    this.microphoneConnector1.ConnectEnded += MicrophoneConnector1_ConnectEnded;
    this.dynamicCameraConnector1.ConnectEnded += DynamicCameraConnector1_ConnectEnded;
    this.dynamicCameraConnector1.Disconnected += DynamicCameraConnector1_Disconnected;
    this.dynamicCameraConnector1.SetViewer(this.image_camera_other);
  }
  catch (Exception ee){}
}

5. 实现远程桌面

      远程桌面的请求/应答逻辑几乎与视频聊天请求/应答逻辑是一模一样的。这里就不再罗列响应的代码了。

(1)当收到对方的远程桌面控制请求时,将显示请求窗口。

 (2)当同意对方的控制请求时,对方就可以控制请求方的电脑了。

四.源码下载     

     服务端+PC端:VideoChatMini.rar 

     Android  端   :VideoChatMini.Android.rar

1. 源码项目说明

     下载【服务端+PC端】源码压缩包,解压后,可以用 VS2022 打开解决方案,其中主要包括了如下几个项目:

(1) Oraycn.Demos.VideoChatMini.ClientWPF:视频聊天Windows 客户端(WPF版本)

(2) Oraycn.Demos.VideoChatMini.Server:视频聊天 Windows 服务端

(3) Oraycn.Demos.VideoChatMini.LinuxClient:视频聊天 Linux 客户端

(4) Oraycn.Demos.VideoChatMini.LinuxServer:视频聊天 Linux 服务端

     注: Linux客户端内置的是x86/x64非托管so库,若需要其它架构的so,请留言获取。  

2. 在Linux上部署运行说明

       在部署之前,需要在linux服务端和客户端上分别安装 .Net core 3.1版本,命令行安装命令如下:

yum install dotnet-sdk-3.1

 检查版本安装情况:

dotnet --version

   运行:

(1)在CentOS上启动Oraycn.Demos.VideoChatMini.LinuxServer服务端:

  拷贝Oraycn.Demos.VideoChatMini.LinuxServer项目下的Debug文件夹,到CentOS操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动服务端

dotnet Oraycn.Demos.VideoChatMini.LinuxServer.dll

(2)在麒麟或统信UOS、Ubuntu上运行Oraycn.Demos.VideoChatMini.LinuxClient客户端:

  拷贝Oraycn.Demos.VideoChatMini.LinuxClient项目下的Debug文件夹,到麒麟或统信UOS、Ubuntu操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动客户端

dotnet Oraycn.Demos.VideoChatMini.LinuxClient.dll

命令执行成功后,就会出现之前截图的客户端主界面。

安卓端的运行界面也差不多,这里就不截图了,大家可以下载源码自行运行测试。

谢谢!

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

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

相关文章

嵌入式系统标志的策略和技巧

当在嵌入式系统中使用标志时&#xff0c;可以考虑以下优化措施&#xff1a; 图像压缩&#xff1a;由于嵌入式系统通常具有有限的存储空间&#xff0c;可以使用图像压缩算法来减小标志的文件大小。常见的压缩算法包括JPEG、PNG等&#xff0c;可以根据系统的要求选择合适的压缩算…

Gradle多模块项目搭建完整教程,模块互相依赖,基于springboot开发

1.父项目创建&#xff0c;【com.fdw.hibernate】 2.子项目创建&#xff0c;【com.fdw.study】【com.fdw.parent】 3.最终结构目录 4. 父工程build.gradle plugins {id java }allprojects {// 指定需要的插件// 指定语言apply plugin: java//指定编辑器apply plugin: idea// 配…

漏洞复现Tomcat系列弱口令、CVE-2017-12615、CVE-2020-1938

文章目录 提提神tomcat8 弱口令介绍&#xff1a;复现&#xff1a; Tomcat PUT方法任意写文件漏洞&#xff08;CVE-2017-12615&#xff09;介绍&#xff1a;复现&#xff1a; Tomcat AJP 文件包含漏洞&#xff08;CVE-2020-1938&#xff09;介绍&#xff1a;复现&#xff1a; 提…

c#/c++ 通过系统api监视文件变化的问题

再分享个比较经典的案例&#xff0c;在很多场景下&#xff0c;我们都要去监视某个文件夹下的文件变化&#xff0c;在创建、修改或删除的时候触发一些行为。众所周知&#xff0c;c#有个实现类叫FileSystemWatcher&#xff0c;可以用来监视目录包括子目录下文件的变化&#xff0c…

亚马逊云科技,定义了生成式AI的生产力

众所周知&#xff0c;要把大模型转化为生产力&#xff0c;AI模型、算力和数据会是难以逾越的门槛。新的目标已经出现&#xff0c;我们是否有了足够强大的AI基础设施&#xff1f;在6月28日上海举行的峰会上&#xff0c;亚马逊云科技展示了这样的能力。 从掀起AI画图热潮的Stabil…

【深度学习笔记】深层神经网络

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

select 框添加树结构(todu)

1. 案例: 2. 代码 下班了&#xff0c;明天写

蓝桥杯专题-真题版含答案-【马虎的算式】【振兴中华】【黄金连分数】【打印十字图】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

day27-MySQL拓展

0目录 第六章 MySQL拓展 1.MySQL拓展 1.1 事务定义&#xff1a;事务就是将一组SQL语句放在同一批次内去执行&#xff0c;如果一个SQL语句出错&#xff0c;则该批次内的所有sql都将被取消执行。 1.2 事务ACID原则 (1)原子性 一个事务要么全部提交成功&#xff0c;要么全部…

「深度学习之优化算法」(九)群搜索算法

1. 群搜索算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读)   群搜索算法(Group Search Optimizer)是一种基于发现者,跟随者,游荡者模型而产生的算法。算法模型较为复杂,提出时间也不长,对于其的深度研究相对较少,但也有一定的应用研究。   在群搜索算法…

【雕爷学编程】Arduino动手做(150)---旋转角度传感器模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【IDE 小程序】小程序控制台 不打印 console.log问题

小程序控制台 不打印 console.log问题 全局搜索compress.drop_console&#xff08;一般在config文件中&#xff09;&#xff0c;设置为false&#xff0c;再重新打开小程序即可

4、架构:Canvas VS DOM

在可视化搭建的低代码平台中&#xff0c;设计器是一个非常关键的模块&#xff0c;可以帮助用户通过拖拽、配置等方式快速搭建应用界面。 在技术选型方面&#xff0c;目前市面上主流的设计器技术包括基于 HTML/CSS/JavaScript 的 Web 设计器。 在渲染方案方面&#xff0c;主流…

TiDB(6):数据迁移-TiDB Lightning

1 TiDB Lightning介绍 TiDB Lightning 是一个将全量数据高速导入到 TiDB 集群的工具&#xff0c;目前支持 Mydumper 或 CSV 输出格式的数据源。你可以在以下两种场景下使用 Lightning&#xff1a; 迅速导入大量新数据。 备份恢复所有数据。 TiDB Lightning 主要包含两个部分…

NSS [SWPUCTF 2021 新生赛]jicao

NSS [SWPUCTF 2021 新生赛]jicao 先看题目&#xff0c;要求我们post传参一个id。然后get一个变量叫json&#xff0c;并且通过json_decode()对一串JSON进行解码 payload&#xff1a; GET&#xff1a; ?json{"x":"wllm"} POST&#xff1a;idwllmNB

java中处理异常规范

java处理异常规范 文章目录 java处理异常规范一、尽量不要使用e.printStackTrace(),而是使用log打印,并记录exception二、不要用一个Exception捕捉所有可能的异常三、使用finally关闭流资源或者直接使用try-with-resource四、捕获异常与抛出异常必须是完全匹配&#xff0c;或者…

Spring Boot 中的 Redis 分布式锁

Spring Boot 中的 Redis 分布式锁 在分布式系统中&#xff0c;多个进程同时访问共享资源时&#xff0c;很容易出现并发问题。为了避免这些问题&#xff0c;我们可以使用分布式锁来保证共享资源的独占性。Redis 是一款非常流行的分布式缓存&#xff0c;它也提供了分布式锁的功能…

react - TS

TypeScript TypeScript 简称『TS』&#xff0c;是微软开发的一个开源的编程语言。 一、TS 特点 TS 主要有如下几个特点: 完全兼容 JavaScript&#xff0c;是 JavaScript 的超集 引入类型系统&#xff0c;可以尽早的定位错误位置, 帮助提升开发效率 let obj {a:1,b:2....}o…

四氯化硅铝的活性离子蚀刻

引言 铝膜广泛用于集成电路中的互连线。随着电路的集成规模和密度变得越来越大&#xff0c;有必要将互连线和间隔的宽度减小到几乎薄膜厚度。为了实现这一点&#xff0c;已经开发了具有定向蚀刻能力的平行平面电极型等离子体蚀刻。这被称为反应离子蚀刻&#xff0c;因为它采用…

基于免疫优化算法的物流配送中心选址规划研究(Matlab实现)

目录 1 概述 2 物流配送中心选址规划研究 3 Matlab代码 4 结果 1 概述 影响物流配送中心选址的因素有很多,精确选址优化问题亟待解决。通过充分考虑货物的配送时间,将免疫算法加入其中,介绍了物流配送选址模型的构建以及免疫算法实现的相关步骤,最后利用matlab软件进行分析,提出…