C# 实现 Linux 视频聊天、远程桌面(源码,支持信创国产化环境,银河麒麟,统信UOS)
<p><span style="font-size: 14px"><span style="font-family: "Microsoft YaHei""> 园子里的有朋友在下载并了解了《</span><span style="font-family: "Microsoft YaHei"">C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)</span><span style="font-family: "Microsoft YaHei"">》中提供的源码后,留言给我说,这个视频会议有点复杂了,代码比较多,看得有些费劲。问我能不能整个简单点的Demo,只要有视频聊天和远程桌面的功能就可以。于是,我就又写了一个Demo来供大家参考,它可以在Windows和Linux(包括国产OS,如银河麒麟、统信UOS、深度Deepin等)上运行。</span></span></p><p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 下图是在银河麒麟V10上运行的截图:</span></p>
<p><span style="font-family: "Microsoft YaHei""> <img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526121341564-1659132827.png"></span></p>
<h2><span style="font-family: "Microsoft YaHei"; font-size: 18pt">一.<strong>功能介绍</strong></span></h2>
<h3><span style="font-family: "Microsoft YaHei"">1. 视频聊天</span></h3>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1)每个登录的用户都可向其他任意在线用户发送视频聊天请求。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(2)当收到来自其他在线用户的视频聊天邀请时,可接受或拒绝对方的请求。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(3)当接受其他在线用户的视频聊天邀请时,即可开启视频聊天。 </span></p>
<h3 class="p"><span style="font-family: "Microsoft YaHei"">2. 远程桌面</span></h3>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1)每个登录的用户都可向其他任意在线用户发送远程桌面请求;当对方未响应时,可主动取消远程桌面请求。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(2)当收到来自其他在线用户请求控制桌面时,可接受或拒绝对方的请求。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(3)当发送方收到其他在线用户同意控制其电脑时,即可开启远程桌面连接。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(4)被控端和主控端都可主动断开远程桌面连接。</span><span style="font-family: "Microsoft YaHei""> </span></p>
<p class="p"> </p>
<span style="font-family: "Microsoft YaHei"; font-size: 18pt">二.<strong>开发环境</strong></span><br>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px">1.开发工具:</span></h3>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px">Visual Studio 2022 </span></p>
<h2><span style="font-family: "Microsoft YaHei"; font-size: 18px">2. 开发框架: </span></h2>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px">.NET Core 3.1,.NET 6,.NET 7 </span></p>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px">3.开发语言:</span></h3>
<p><span style="font-size: 14px; font-family: "Microsoft YaHei"">C#</span></p>
<h3><span style="font-family: "Microsoft YaHei"">4.其它框架:</span></h3>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px">CPF.net UI 框架、OMCS 语音视频框架 </span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> </span></p>
<h2><span style="font-family: "Microsoft YaHei"; font-size: 18pt">三.<strong>具体实现</strong></span></h2>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 下面我们讲一下Demo中核心的代码实现,大家从文末下载源码并对照着源码看,会更清楚些。</span></p>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px"><strong>1.自定义消息类型 InformationTypes</strong></span></h3>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""> <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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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)"><summary></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)"></summary></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> </pre>
</div>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px">2. 发送视频请求</span></h3>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1)当发起视频聊天时,将显示视频聊天窗口</span><span style="font-family: "Microsoft YaHei"; font-size: 16px"> </span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="wait"></span><span style="color: rgba(0, 128, 0, 1)">true表示自己为发送端</span><span style="color: rgba(128, 128, 128, 1)"></param></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: "Microsoft YaHei"; font-size: 14px"> (2)连接自己的摄像头并发送视频通话请求</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isSend"></span><span style="color: rgba(0, 128, 0, 1)">是否为发送者</span><span style="color: rgba(128, 128, 128, 1)"></param></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: "Microsoft YaHei"">3. 回复对方视频请求</span></h3>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1)当收到对方的视频聊天邀请时,将显示视频邀请窗口 </span></p>
<p><span style="font-family: "Microsoft YaHei""> <img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526142615970-374040813.png"></span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> (2)发送回复视频聊天请求消息</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isReceive"></span><span style="color: rgba(0, 128, 0, 1)">true表示同意,false表示拒绝</span><span style="color: rgba(128, 128, 128, 1)"></param></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: "Microsoft YaHei"; font-size: 18px">4. 收到对方视频请求的回复</span></h3>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="OtherIsAgree"></span><span style="color: rgba(0, 128, 0, 1)">true表示同意,false表示拒绝</span><span style="color: rgba(128, 128, 128, 1)"></param></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: "Microsoft YaHei"; font-size: 14px">当对方回复同意时,将连接到对方的麦克风和摄像头,开始视频聊天会话:</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></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> </h3>
<h3>5. 实现远程桌面</h3>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 远程桌面的请求/应答逻辑几乎与视频聊天请求/应答逻辑是一模一样的。这里就不再罗列响应的代码了。</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1)当收到对方的远程桌面控制请求时,将显示请求窗口。</span></p>
<p><span style="font-family: "Microsoft YaHei""> <img src="https://img2023.cnblogs.com/blog/513369/202306/513369-20230616102326358-1238613389.png"></span></p>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px">(2)当同意对方的控制请求时,对方就可以控制请求方的电脑了。</span></p>
<p><span style="font-family: "Microsoft YaHei""> <img src="https://img2023.cnblogs.com/blog/513369/202306/513369-20230616115143608-1507699440.png"> </span></p>
<h2><span style="font-family: "Microsoft YaHei"; font-size: 18pt">四.<strong>源码下载</strong></span></h2>
<p><span style="font-family: "Microsoft YaHei"; font-size: 16px"> 源码下载:(若点击没有自动下载,可右键另存为)</span> </p>
<p><span style="font-size: 16px"> 服务端+PC端:<strong>VideoChatMini.rar</strong> </span> </p>
<p><span style="font-size: 16px"> Android 端:<strong>VideoChatMini.Android.rar</strong></span></p>
<p><span style="font-size: 16px"><strong> </strong> Web 端:<strong>VideoChatMini.Web.rar</strong> (需要安装 OMCS Web 插件 )</span></p>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px">1. 源码项目说明</span></h3>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 下载【服务端+PC端】源码压缩包,解压后,可以用 VS2022 打开解决方案,其中主要包括了如下几个项目:<br></span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(1) Oraycn.Demos.VideoChatMini.ClientWPF:视频聊天Windows 客户端(WPF版本)</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(2) Oraycn.Demos.VideoChatMini.Server:视频聊天 Windows 服务端</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(3) Oraycn.Demos.VideoChatMini.LinuxClient:视频聊天 Linux 客户端</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px">(4) Oraycn.Demos.VideoChatMini.LinuxServer:视频聊天 Linux 服务端</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 注: Linux客户端内置的是x86/x64非托管so库,若需要其它架构的so,请联系QQ:2027224508 获取。 </span></p>
<h3><span style="font-family: "Microsoft YaHei"; font-size: 18px">2. 在Linux上部署运行说明</span></h3>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 在部署之前,需要在linux服务端和客户端上分别安装 .Net core 3.1版本,命令行安装命令如下:</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei"">yum install dotnet-sdk-3.1</span></pre>
</div>
<p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 检查版本安装情况</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei""> dotnet --version</span></pre>
</div>
<p class="p"><span style="font-size: 14px; font-family: "Microsoft YaHei""> 运行:</span></p>
<p class="p"><span style="font-size: 14px; font-family: "Microsoft YaHei"">(1)在CentOS上启动Oraycn.Demos.VideoChatMini.LinuxServer服务端:</span></p>
<p class="p"><span style="font-size: 14px; font-family: "Microsoft YaHei""> 拷贝Oraycn.Demos.VideoChatMini.LinuxServer项目下的Debug文件夹,到CentOS操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动服务端</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei""> </span><span style="font-size: 16px; font-family: "Microsoft YaHei""> <img src="https://img2023.cnblogs.com/blog/513369/202305/513369-20230526121807112-741474842.png"></span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei"">dotnet Oraycn.Demos.VideoChatMini.LinuxServer.dll</span></pre>
</div>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px"> (2)在麒麟或统信UOS、Ubuntu上运行Oraycn.Demos.VideoChatMini.LinuxClient客户端:</span></p>
<p class="p"><span style="font-family: "Microsoft YaHei"; font-size: 14px"> 拷贝Oraycn.Demos.VideoChatMini.LinuxClient项目下的Debug文件夹,到麒麟或统信UOS、Ubuntu操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动客户端</span></p>
<div class="cnblogs_code">
<pre><span style="font-family: "Microsoft YaHei"">dotnet Oraycn.Demos.VideoChatMini.LinuxClient.dll</span></pre>
</div>
<p><span style="font-family: "Microsoft YaHei""> 命令执行成功后,就会出现之前截图的客户端主界面。</span></p>
<p> 安卓端的运行界面也差不多,这里就不截图了,大家可以下载源码自行运行测试。</p>
<p> 谢谢!</p><br><br>
来源:https://www.cnblogs.com/shawshank/p/17420469.html
頁:
[1]