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

有朋友在下载并了解了《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.hqwc.cn/news/8187.html

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

相关文章

Spring Batch 批处理框架

一、SpringBatch 介绍 Spring Batch 是一个轻量级、全面的批处理框架&#xff0c;旨在支持开发对企业系统的日常操作至关重要的健壮的批处理应用程序。Spring Batch 建立在人们期望的 Spring Framework 特性&#xff08;生产力、基于 POJO 的开发方法和一般易用性&#xff09;…

通信相关知识(三) 接入网

接入网的定界 接入网的功能 用户口功能、业务口功能、核心功能、传送功能、接入网系统管理功能。 ADSL 非对称数字用户线路&#xff08;ADSL&#xff0c;Asymmetric Digital Subscriber Line&#xff09;是数字用户线路&#xff08;xDSL&#xff0c;Digital Subscriber Lin…

结构光三维测量几种比较成熟的方法

1.飞行时间发 原理:通过直接测量光传播的时间,确定物体的面型。发射脉冲信号,接受发射回的光,计算距离。 精度:毫米级 优点:原理简单,可避免阴影和遮挡等问题,且仪器便携化。 缺点:精度相对较低 2.莫尔条纹法 原理:采用两组光栅,一个主光栅,一个基准光栅,通过…

yolov7

一、 ELAN [-1, 1, Conv, [64, 1, 1]],[-2, 1, Conv, [64, 1, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [64, 3, 1]],[[-1, -3, -5, -6], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1]], # 11二、E-ELAN 三、模型缩放…

Docker是什么以及docker的常用命令

Docker简介 Docker是一种开源的容器化平台&#xff0c;用于构建、部署和运行应用程序。它允许开发人员将应用程序及其所有依赖项打包到一个称为"容器"的独立单元中。这个容器可以在任何支持Docker的环境中运行&#xff0c;无论是开发人员的本地机器、虚拟机还是云服务…

配置Jenkins的slave agent并使用它完成构建任务

上一章&#xff0c;使用单机配置并运行了一个简单的maven项目&#xff0c;并发布到了一个服务器上启动。这一章将要配置一个slave agent&#xff0c;并将上一章的job放到agent上执行。我们agent使用的是ssh的方式 前置步骤 准备两台虚拟机&#xff1a; 192.168.233.32&#…

欧科云链2023年报:毛利达1.55亿港元,数字资产业务成最大增长点

据香港商报报道&#xff0c;2023年6月28日&#xff0c;欧科云链控股有限公司&#xff08;以下简称“欧科云链”&#xff09;及其附属公司&#xff08;股份代号&#xff1a;1499.HK&#xff0c;以下简称“集团”&#xff09;发布了截至2023年3月31日的年度报告。报告期内&#x…

Redis【实战篇】---- Redis消息队列

Redis【实战篇】---- Redis消息队列 1. Redis消息队列 - 认识消息队列2. Redis消息队列 - 基于List实现消息队列3. Redis消息队列 - 基于PubSub的消息队列4. Redis消息队列 - 基于Stream的消息队列5. Redis消息队列 - 基于Stream的消息队列-消费组6. 基于Redis的Stream结构作为…

MAC OS X 这个“安装 macOS Xxx Xxx”应用程序副本已损坏,不能用来安装 macOS,超级终端修改日期date 已解决

原因&#xff1a;旧版 macOS 证书已经过期 解决方法&#xff1a;断开互联网&#xff0c;修改系统时间 date 102013142018.20 说明&#xff1a;10是月&#xff0c;20是日&#xff0c;13是时&#xff0c;14是分&#xff0c;2018是年&#xff0c;20是秒 输入上面的代码按回车后…

SpringBoot操作Excel实现导入和导出功能(详细讲解+Gitee源码)

前言&#xff1a;在日常的开发中&#xff0c;避免不了操作Excel&#xff0c;比如从系统当中导出一个报表&#xff0c;或者通过解析客户上传的Excel文件进行批量解析数据入库等等&#xff0c;本篇博客主要汇总日常开发中如何使用开源的Apache提供的POI流操作Excel进行导入导出功…

【035】C++泛型编程(模板)实践:设计数组类模板模仿vector容器

C泛型编程&#xff08;模板&#xff09;实践 引言一、类模板的概述二、实现数组类模板三、类模板的继承3.1、类模板派生出普通类3.2、类模板派生出类模板 总结 引言 &#x1f4a1; 作者简介&#xff1a;专注于C/C高性能程序设计和开发&#xff0c;理论与代码实践结合&#xff0…

常州工学院单片机及应用系统设计2021-2022 学年第 二 学期 考试类型 开卷 课程编码 0302005

第一题 #include "SC95F861x_C.H" #include <INTRINS.H> unsigned char keydata0; void delay(unsigned int timer) //延时函数 { while(timer>0) timer--; } void IOinit() { P5CON0x00; P5PH0x03; P3CON0xFF; P3PH0xFF; } void readke…