• Avalonia 实现跨平台的视频聊天、屏幕分享(源码,支持Win、银河麒麟、统信UOS)


           现在最火的.NET跨平台UI框架莫过于Avalonia了。Avalonia 基于.NET Core,因此它可以运行在任何支持.NET Core的平台上。之前基于CPF跨平台UI框架写过一个视频聊天的demo,而现在看来Avalonia是大势所趋,于是,我再写一个Avalonia版本的Demo来供大家参考,它可以在Windows和Linux(包括国产OS,如银河麒麟、统信UOS)上运行。

           下图是视频聊天Demo的Avalonia客户端在国产统信UOS上的运行的截图:

     一.功能介绍 

          客户端登录成功后,运行的主界面如下图所示:  

    1. 视频聊天

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

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

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

    2. 远程桌面

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

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

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

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

    二.开发环境

    1.开发工具:

    Visual Studio 2022 

    2. 开发框架: 

    .NET Core 3.1

    3.开发语言:

    C#

    4.其它框架:

    Avalonia UI 框架(版本:0.10.22)、OMCS 语音视频框架 (版本:8.0)

    注:建议 Avalonia 使用0.10.*的版本,精简而且很稳定,而最新的11.0的版本太庞大了。

    三.具体实现

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

    1.自定义消息类型 InformationTypes

    1. public static class InformationTypes
    2. {
    3. ///
    4. /// 视频请求 0
    5. ///
    6. public const int VideoRequest = 0;
    7. ///
    8. /// 回复视频请求的结果 1
    9. ///
    10. public const int VideoResult = 1;
    11. ///
    12. /// 通知对方 挂断 视频连接 2
    13. ///
    14. public const int CloseVideo = 2;
    15. ///
    16. /// 通知好友 网络原因,导致 视频中断 3
    17. ///
    18. public const int NetReasonCloseVideo = 3;
    19. ///
    20. /// 通知对方(忙线中) 挂断 视频连接 4
    21. ///
    22. public const int BusyLine = 4;
    23. ///
    24. /// 远程桌面请求 5
    25. ///
    26. public const int DesktopRequest = 5;
    27. ///
    28. /// 回复远程桌面请求的结果 6
    29. ///
    30. public const int DesktopResult = 6;
    31. ///
    32. /// 主动取消远程桌面请求 7
    33. ///
    34. public const int CancelDesktop = 7;
    35. ///
    36. /// 对方(主人端)主动断开远程桌面 8
    37. ///
    38. public const int OwnerCloseDesktop = 8;
    39. ///
    40. /// 客人端断开远程桌面连接 9
    41. ///
    42. public const int GuestCloseDesktop = 9;
    43. }

    2. 发送视频请求

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

    1. ///
    2. /// 打开视频通话窗口
    3. ///
    4. /// 对方ID
    5. /// false表示主动发起视频通话邀请
    6. internal void OpenVideoChat(string destID,bool isWorking)
    7. {
    8. if (!this.VideoInvokeVerdict(destID))
    9. {
    10. return;
    11. }
    12. App.Multimedia.OutputAudio = true;
    13. VideoChatWindow videoChatWindow = new VideoChatWindow(destID, isWorking);
    14. videoChatWindow.EndTheCalled += VideoChatWindow_EndTheCalled;
    15. objectManager.Add(destID, videoChatWindow);
    16. videoChatWindow.Show();
    17. }

    (2)连接自己的摄像头 

    1. public VideoChatWindow(string destID,bool isWorking)
    2. {
    3. this.DestID = destID;
    4. this.IsWorking = isWorking;
    5. InitializeComponent();
    6. //连接自己的摄像头
    7. this.selfCamera.Core.DisplayVideoParameters = true;
    8. this.selfCamera.Core.VideoDrawMode = VideoDrawMode.ScaleToFill;
    9. this.selfCamera.BeginConnect(MainWindow.CurrentID);
    10. this.Title = this.title.Text = this.RepeatedCallTip(false);
    11. this.timer = new System.Timers.Timer();
    12. this.timer.Interval = 1000;
    13. this.timer.Elapsed += Timer_Elapsed;
    14. if (IsWorking)
    15. {
    16. this.BeginConnect();
    17. }
    18. }

    (3)发送视频通话请求

    1. protected override void OnInitialized()
    2. {
    3. base.OnInitialized();
    4. this.SetWindowStats();
    5. if (!this.IsWorking)
    6. {
    7. //向对方发起视频通话邀请
    8. VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoRequest, null);
    9. }
    10. }

    3. 回复对方视频请求

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

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

    1. protected override void OnClosed(EventArgs e)
    2. {
    3. base.OnClosed(e);
    4. if (this.EndTheCalled != null)
    5. {
    6. this.EndTheCalled(this.DestID);
    7. }
    8. if (this.NotifyOther)
    9. {
    10. //回复对方的视频通话请求
    11. byte[] bytes = BitConverter.GetBytes(replyResult);
    12. VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoResult, bytes);
    13. }
    14. if (this.replyResult)
    15. {
    16. VideoController.Singleton.OpenVideoChat(DestID,true);
    17. }
    18. }

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

    1. ///
    2. /// 视频通话,收到对方回复
    3. ///
    4. internal void TargerReply(string destID, CommunicationStateType type)
    5. {
    6. ICommunicationAid aid = this.objectManager.Get(destID);
    7. if(aid == null)
    8. {
    9. return;
    10. }
    11. switch (type)
    12. {
    13. case CommunicationStateType.Agree:
    14. VideoChatWindow videoChatWindow = (VideoChatWindow)aid;
    15. videoChatWindow.BeginConnect();
    16. break;
    17. case CommunicationStateType.Reject:
    18. aid.CloseWindow(false);
    19. break;
    20. case CommunicationStateType.HangUp:
    21. aid.CloseWindow(false);
    22. break;
    23. default:
    24. break;
    25. }
    26. }

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

    1. ///
    2. /// 连接对方设备
    3. ///
    4. internal void BeginConnect()
    5. {
    6. UiSafeInvoker.ActionOnUI(() =>
    7. {
    8. this.IsWorking = true;
    9. this.Title = this.title.Text = this.RepeatedCallTip(false);
    10. this.startTime = DateTime.Now;
    11. this.timer.Start();
    12. this.otherCamera.Core.DisplayVideoParameters = true;
    13. this.otherCamera.Core.VideoDrawMode = VideoDrawMode.ScaleToFill;
    14. this.otherCamera.Core.ConnectEnded += DynamicCameraConnector_ConnectEnded;
    15. this.otherCamera.Core.Disconnected += DynamicCameraConnector_Disconnected;
    16. this.microphoneConnector.ConnectEnded += MicrophoneConnector_ConnectEnded;
    17. this.microphoneConnector.Disconnected += MicrophoneConnector_Disconnected;
    18. this.otherCamera.BeginConnect(this.DestID);
    19. this.microphoneConnector.BeginConnect(this.DestID);
    20. this.NotifyOther = true;
    21. });
    22. }

    5. 实现远程桌面

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

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

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

    四.源码下载     

         .NetCore服务端 + Avalonia客户端:VideoChatMini.Avalonia.rar  

          在Windows上部署运行服务端和客户端很容易,大家也都很熟悉了。下面讲一下如何在Linux上部署运行这个视频聊天程序的服务端和客户端。

         在Linux上部署运行说明

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

     yum install dotnet-sdk-3.1

      检查版本安装情况

     dotnet --version

       运行:

    (1)在CentOS上启动VideoChatMini.ServerNetcore服务端:

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

    dotnet Oraycn.VideoChatMini.ServerNetcore.dll

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

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

    dotnet Oraycn.VideoChatMini.ClientAvalonia.dll

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

            Avalonia 支持在X64和ARM64架构的Linux上运行,Demo的运行目录下放的是X64架构的so,如果需要ARM64架构的so,可留下邮箱获取。

  • 相关阅读:
    kali工具熟悉——网络扫描
    YARN的产生背景和架构剖析
    2022-08-19 Mysql--preparedStatement(预编译)
    WHATS WRONG WITH MY LAMBDA TO DYNAMODB CONNECTIVITY?
    你真的懂Java怎么输出Hello World吗?
    校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
    Django模型的字段选项
    京东大佬问我:下单后30分钟未支付,自动取消有什么设计方案么?
    web网页设计期末课程大作业:环境保护主题网站设计——农业三级带表单带js(14页)HTML+CSS+JavaScript
    R语言绘制时间序列的偏自相关函数图:使用pacf函数可视化时间序列数据的偏自相关系数图
  • 原文地址:https://blog.csdn.net/zhuweisky/article/details/133857450