阿拉丁丁 發表於 2023-6-26 10:16:00

C# 实现 Linux 视频聊天、远程桌面(源码,支持信创国产化环境,银河麒麟,统信UOS)

<p><span style="font-size: 14px"><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp;园子里的有朋友在下载并了解了《</span><span style="font-family: &quot;Microsoft YaHei&quot;">C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)</span><span style="font-family: &quot;Microsoft YaHei&quot;">》中提供的源码后,留言给我说,这个视频会议有点复杂了,代码比较多,看得有些费劲。问我能不能整个简单点的Demo,只要有视频聊天和远程桌面的功能就可以。于是,我就又写了一个Demo来供大家参考,它可以在Windows和Linux(包括国产OS,如银河麒麟、统信UOS、深度Deepin等)上运行。</span></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp;下图是在银河麒麟V10上运行的截图:</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp;<img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526121341564-1659132827.png"></span></p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18pt">一.<strong>功能介绍</strong></span></h2>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;">1. 视频聊天</span></h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)每个登录的用户都可向其他任意在线用户发送视频聊天请求。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(2)当收到来自其他在线用户的视频聊天邀请时,可接受或拒绝对方的请求。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(3)当接受其他在线用户的视频聊天邀请时,即可开启视频聊天。&nbsp;</span></p>
<h3 class="p"><span style="font-family: &quot;Microsoft YaHei&quot;">2. 远程桌面</span></h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)每个登录的用户都可向其他任意在线用户发送远程桌面请求;当对方未响应时,可主动取消远程桌面请求。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(2)当收到来自其他在线用户请求控制桌面时,可接受或拒绝对方的请求。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(3)当发送方收到其他在线用户同意控制其电脑时,即可开启远程桌面连接。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(4)被控端和主控端都可主动断开远程桌面连接。</span><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp;</span></p>
<p class="p">&nbsp;</p>
<span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18pt">二.<strong>开发环境</strong></span><br>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">1.开发工具:</span></h3>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">Visual Studio 2022&nbsp;</span></p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">2. 开发框架:&nbsp;</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">.NET Core 3.1,.NET 6,.NET 7&nbsp;</span></p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">3.开发语言:</span></h3>
<p><span style="font-size: 14px; font-family: &quot;Microsoft YaHei&quot;">C#</span></p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;">4.其它框架:</span></h3>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">CPF.net UI 框架、OMCS 语音视频框架&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;</span></p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18pt">三.<strong>具体实现</strong></span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp; 下面我们讲一下Demo中核心的代码实现,大家从文末下载源码并对照着源码看,会更清楚些。</span></p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px"><strong>1.自定义消息类型 InformationTypes</strong></span></h3>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;">      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"> InformationTypes</span>
    {
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 视频请求 0
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> VideoRequest = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 回复视频请求的结果 1
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> VideoResult = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 通知对方 挂断 视频连接 2
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> CloseVideo = <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 通知好友 网络原因,导致 视频中断 3
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> NetReasonCloseVideo = <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 通知对方(忙线中) 挂断 视频连接 4
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> BusyLine = <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 远程桌面请求 5
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DesktopRequest = <span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 回复远程桌面请求的结果 6
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DesktopResult = <span style="color: rgba(128, 0, 128, 1)">6</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">主动取消远程桌面请求 7
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> CancelDesktop = <span style="color: rgba(128, 0, 128, 1)">7</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">对方(主人端)主动断开远程桌面 8
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> OwnerCloseDesktop = <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">;

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
                <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 客人端断开远程桌面连接 9
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> GuestCloseDesktop = <span style="color: rgba(128, 0, 128, 1)">9</span><span style="color: rgba(0, 0, 0, 1)">;
    }</span></span>&nbsp;</pre>
</div>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">2. 发送视频请求</span></h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)当发起视频聊天时,将显示视频聊天窗口</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">  </span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 显示视频聊天窗口
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="wait"&gt;</span><span style="color: rgba(0, 128, 0, 1)">true表示自己为发送端</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> RequestVideo(<span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> wait)
{
  </span><span style="color: rgba(0, 0, 255, 1)">if</span> (videoChat == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
  {
    videoChat </span>=<span style="color: rgba(0, 0, 0, 1)"> DoCreateVideoChatForm(wait);
  }
  videoChat.Show();
  <span style="color: rgba(0, 128, 128, 1)">IMultimediaManager </span>mgr </span>=<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"> MultimediaManagerFactory</span>.GetSingleton();
  </span><span style="color: rgba(0, 0, 255, 1)">if</span> (mgr == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
  {
    <span style="color: rgba(0, 128, 128, 1)">CommonHelper</span>.ShowToolTip(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">无法启动多媒体设备!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
    ClearVideoChat();
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
  }
  </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.videoChat.Initialize(mgr);
  </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.videoChat.SendVideoRequest(wait);
}</span></span></pre>
</div>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;(2)连接自己的摄像头并发送视频通话请求</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 发送视频通话请求
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="isSend"&gt;</span><span style="color: rgba(0, 128, 0, 1)">是否为发送者</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SendVideoRequest(<span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> isSend)
{
  </span><span style="color: rgba(0, 0, 255, 1)">this</span>.StackPanel_Camera_myself.Visibility =<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"> Visibility</span>.Visible;
  </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector_myself.ConnectEnded +=<span style="color: rgba(0, 0, 0, 1)"> DynamicCameraConnector_myself_ConnectEnded;
  </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector_myself.SetViewer(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.image_camera_myself);
  </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector_myself.BeginConnect(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.currentUserID);
  </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isSend)
  {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.time_tip.Content = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">正在等待对方回复</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
    <span style="color: rgba(0, 128, 128, 1)">App</span>.multimediaManager.SendCustomizedMessage(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.friendID, <span style="color: rgba(0, 128, 128, 1)">InformationTypes</span>.VideoRequest,<span style="color: rgba(0, 0, 255, 1)">null</span>, <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
  }
}   </span></span></pre>
</div>
<h3><span style="font-size: 18px; font-family: &quot;Microsoft YaHei&quot;">3. 回复对方视频请求</span></h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)当收到对方的视频聊天邀请时,将显示视频邀请窗口&nbsp;&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526142615970-374040813.png"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;(2)发送回复视频聊天请求消息</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 是否同意视频聊天请求
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="isReceive"&gt;</span><span style="color: rgba(0, 128, 0, 1)">true表示同意,false表示拒绝</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ReplyVideoRequest(<span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> isReceive)
{
  </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
  {<br></span><span style="color: rgba(0, 0, 255, 1)">    byte</span>[] vs =<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"> BitConverter</span>.GetBytes(isReceive);
    <span style="color: rgba(0, 128, 128, 1)">App</span>.multimediaManager.SendCustomizedMessage(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.friendId, <span style="color: rgba(0, 128, 128, 1)">InformationTypes</span>.VideoResult, vs,<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isReceive)
    {
      <span style="color: rgba(0, 128, 128, 1)">App</span>.mainWindow.RequestVideo(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      <span style="color: rgba(0, 128, 128, 1)">App</span>.mainWindow.SetCurrentVideo(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendId);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    {
      <span style="color: rgba(0, 128, 128, 1)">CommonHelper</span>.ShowToolTip(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">已拒绝对方视频通话邀请</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
    }
    Close4BtnClick </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
    <span style="color: rgba(0, 128, 128, 1)">App</span>.mainWindow.ClearVideoRequest();
  }
  </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)">(<span style="color: rgba(0, 128, 128, 1)">Exception</span> e)<br>  {
    <span style="color: rgba(0, 128, 128, 1)">LoginWindow</span>.FileAgileLogger.Log(e, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">VideoRequestWindow.ReplyVideoRequest</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, ESBasic.Loggers.ErrorLevel.Standard);
  }
} </span></span></pre>
</div>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">4. 收到对方视频请求的回复</span></h3>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 视频请求,收到对方回复
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="OtherIsAgree"&gt;</span><span style="color: rgba(0, 128, 0, 1)">true表示同意,false表示拒绝</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SendVideoRequestResult(<span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> OtherIsAgree)
{
  </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (OtherIsAgree)
  {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.OnAgree(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendID);
    <span style="color: rgba(0, 128, 128, 1)">App</span>.mainWindow.SetCurrentVideo(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendID);
  }
  </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
  {
    <span style="color: rgba(0, 128, 128, 1)">CommonHelper</span>.ShowToolTip(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">对方拒绝与您进行视频通话</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
    <span style="color: rgba(0, 128, 128, 1)">App</span>.mainWindow.ClearVideoChat();
  }
}</span></span></pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">当对方回复同意时,将连接到对方的麦克风和摄像头,开始视频聊天会话:</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 对方同意视频会话
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> OnAgree(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> destLoginID)
{
  </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
  {
    startTime </span>=<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 128, 1)"> DateTime</span>.Now;
    timer.Start();
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.friendLoginID = destLoginID != <span style="color: rgba(0, 0, 255, 1)">null</span>? destLoginID: <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendName;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.lab_title.Content = <span style="color: rgba(0, 0, 255, 1)">string</span>.Format(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">正在和{0}视频会话</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendName);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector1.BeginConnect(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendLoginID);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.microphoneConnector1.BeginConnect(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.friendLoginID);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.microphoneConnector1.ConnectEnded +=<span style="color: rgba(0, 0, 0, 1)"> MicrophoneConnector1_ConnectEnded;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector1.ConnectEnded +=<span style="color: rgba(0, 0, 0, 1)"> DynamicCameraConnector1_ConnectEnded;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector1.Disconnected +=<span style="color: rgba(0, 0, 0, 1)"> DynamicCameraConnector1_Disconnected;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.dynamicCameraConnector1.SetViewer(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.image_camera_other);
  }
  </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (<span style="color: rgba(0, 128, 128, 1)">Exception</span> ee){}
}</span></span></pre>
</div>
<h3>&nbsp;</h3>
<h3>5. 实现远程桌面</h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp; 远程桌面的请求/应答逻辑几乎与视频聊天请求/应答逻辑是一模一样的。这里就不再罗列响应的代码了。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)当收到对方的远程桌面控制请求时,将显示请求窗口。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp;  <img src="https://img2023.cnblogs.com/blog/513369/202306/513369-20230616102326358-1238613389.png"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(2)当同意对方的控制请求时,对方就可以控制请求方的电脑了。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img src="https://img2023.cnblogs.com/blog/513369/202306/513369-20230616115143608-1507699440.png">&nbsp;</span></p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18pt">四.<strong>源码下载</strong></span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp; &nbsp; &nbsp;源码下载:(若点击没有自动下载,可右键另存为)</span>&nbsp;</p>
<p><span style="font-size: 16px">&nbsp; &nbsp; &nbsp;服务端+PC端:<strong>VideoChatMini.rar</strong>&nbsp;</span>&nbsp;</p>
<p><span style="font-size: 16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Android 端:<strong>VideoChatMini.Android.rar</strong></span></p>
<p><span style="font-size: 16px"><strong>&nbsp; &nbsp; </strong>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Web&nbsp;端:<strong>VideoChatMini.Web.rar</strong>&nbsp;(需要安装&nbsp;OMCS Web 插件&nbsp;)</span></p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">1. 源码项目说明</span></h3>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp;下载【服务端+PC端】源码压缩包,解压后,可以用 VS2022 打开解决方案,其中主要包括了如下几个项目:<br></span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(1)&nbsp;Oraycn.Demos.VideoChatMini.ClientWPF:视频聊天Windows 客户端(WPF版本)</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(2)&nbsp;Oraycn.Demos.VideoChatMini.Server:视频聊天 Windows 服务端</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(3)&nbsp;Oraycn.Demos.VideoChatMini.LinuxClient:视频聊天 Linux 客户端</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">(4) Oraycn.Demos.VideoChatMini.LinuxServer:视频聊天 Linux 服务端</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp;注:&nbsp;Linux客户端内置的是x86/x64非托管so库,若需要其它架构的so,请联系QQ:2027224508 获取。&nbsp;&nbsp;</span></p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">2. 在Linux上部署运行说明</span></h3>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp; &nbsp;在部署之前,需要在linux服务端和客户端上分别安装 .Net core 3.1版本,命令行安装命令如下:</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;">yum install dotnet-sdk-3.1</span></pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp; &nbsp; &nbsp; 检查版本安装情况</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;"> dotnet --version</span></pre>
</div>
<p class="p"><span style="font-size: 14px; font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp;运行:</span></p>
<p class="p"><span style="font-size: 14px; font-family: &quot;Microsoft YaHei&quot;">(1)在CentOS上启动Oraycn.Demos.VideoChatMini.LinuxServer服务端:</span></p>
<p class="p"><span style="font-size: 14px; font-family: &quot;Microsoft YaHei&quot;">  拷贝Oraycn.Demos.VideoChatMini.LinuxServer项目下的Debug文件夹,到CentOS操作系统上,打开Debug -&gt; netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动服务端</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp;</span><span style="font-size: 16px; font-family: &quot;Microsoft YaHei&quot;">  <img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526121807112-741474842.png"></span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;">dotnet Oraycn.Demos.VideoChatMini.LinuxServer.dll</span></pre>
</div>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;(2)在麒麟或统信UOS、Ubuntu上运行Oraycn.Demos.VideoChatMini.LinuxClient客户端:</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">  拷贝Oraycn.Demos.VideoChatMini.LinuxClient项目下的Debug文件夹,到麒麟或统信UOS、Ubuntu操作系统上,打开Debug -&gt; netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动客户端</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: &quot;Microsoft YaHei&quot;">dotnet Oraycn.Demos.VideoChatMini.LinuxClient.dll</span></pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp; &nbsp; &nbsp; &nbsp;命令执行成功后,就会出现之前截图的客户端主界面。</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;安卓端的运行界面也差不多,这里就不截图了,大家可以下载源码自行运行测试。</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; 谢谢!</p><br><br>
来源:https://www.cnblogs.com/shawshank/p/17420469.html
頁: [1]
查看完整版本: C# 实现 Linux 视频聊天、远程桌面(源码,支持信创国产化环境,银河麒麟,统信UOS)