• 循序渐进做项目系列(4)迷你QQ篇(2)——视频聊天!(附源码)


    一·效果展示

           

          源码派送MiniQQ1.1

          文字聊天的实现参见:循序渐进做项目系列(3):迷你QQ篇(1)——实现客户端互相聊天

    二·服务端设计

          对于实现视频聊天而言,服务端最核心的工作就是要构造多媒体服务器MultimediaServer 。

    namespace Server
    {
        static class Program
        {       
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //创建服务端通信引擎
                IRapidServerEngine ServerEngine = RapidEngineFactory.CreateServerEngine();
                ServerHandler serverHandler = new ServerHandler();//创建服务端消息处理器
                //初始化服务端引擎,设置好用于监听的端口号,并注入消息处理器
                ServerEngine.Initialize(2000/*端口号*/, serverHandler);
                
                DefaultUserVerifier userVerifier = new DefaultUserVerifier();//默认任何用户都验证通过
                //OMCS配置信息
                OMCSConfiguration config = new OMCSConfiguration(15/*摄像头采集的帧频*/,
                                                                 15/*远程桌面的帧频*/,
                                                                 EncodingQuality.Middle/*语音编码的质量*/);
                //创建多媒体服务器
                IMultimediaServer MultimediaServer = MultimediaServerFactory.CreateMultimediaServer(2400/*监听的端口*/,
                                                                                                    userVerifier/*用户帐密验证器*/,
                                                                                                    config/*OMCS配置信息*/,
                                                                                                    false/*是否记录详细的安全日志*/);                       
                Application.Run(new Form_Server());
              
            }
        }
    }

    三·客户端设计

          对于实现视频聊天而言,客户端设计的核心在于需要构造并初始化多媒体设备管理器 multimediaManager

        1.登陆窗设计

          对于实现视频聊天而言,登陆窗的主要任务就是与多媒体服务器MultimediaServer 建立连接,并初始化本地多媒体管理器multimediaManager。      

    namespace Client
    {
        public partial class Form_Login : Form
        {
            private IRapidPassiveEngine clientEngine;//客户端通信引擎 
           
            private  ClientHandler clientHandler;//客户端消息处理器
    
            public string SelfUserID//本人用户ID,该属性主要是为了暴露给主窗体用来标识用户
            {            
                get { return this.textBox_UserID.Text; }
            }
    
            public Form_Login(IRapidPassiveEngine _clientEngine, ClientHandler _clientHandler)
            {
                InitializeComponent();
                //传入通信引擎和消息处理器主要是为了登陆的时候进行通信引擎初始化操作
                this.clientEngine = _clientEngine;
                this.clientHandler = _clientHandler;           
            }
    
            private void button_login_Click(object sender, EventArgs e)
            {
                //通信引擎初始化,与目标服务器建立TCP连接             
                LogonResponse logonResponse = this.clientEngine.Initialize(this.textBox_UserID.Text, this.textBox_Password.Text, "127.0.0.1", 2000, clientHandler);
                //创建多媒体设备管理器
                IMultimediaManager multimediaManager = MultimediaManagerFactory.GetSingleton();
                multimediaManager.CameraDeviceIndex = 1;//要使用的摄像头的索引
                multimediaManager.AutoAdjustCameraEncodeQuality = false;//是否根据音频反馈以及视频丢帧情况自动调整视频编码质量
                //与多媒体服务器建立连接,并初始化本地多媒体管理器。
                multimediaManager.Initialize(this.textBox_UserID.Text,/*当前登录的用户ID*/
                                             null,/*当前登录的用户的密码*/
                                            "127.0.0.1",/*OMCS服务器IP*/
                                             2400);/*OMCS服务器端口*/
                if (logonResponse.LogonResult == LogonResult.Succeed)
                {
                    this.DialogResult = DialogResult.OK;
                }
                else
                {
                    MessageBox.Show("登陆失败!" + logonResponse.LogonResult.ToString() + logonResponse.FailureCause);
                }
            }         
        }
    }

        2.主窗体设计

          对于实现视频聊天而言,主窗体最主要的工作就是开启视频窗。

    namespace Client
    {
        public partial class Form_Client : Form
        {
            private IRapidPassiveEngine clientEngine;
    
            private string selfUserID;
            private string targetUserID;
    
            public Form_Client(IRapidPassiveEngine _clientEngine,string _selfUserID)
            {
                this.clientEngine = _clientEngine;
                this.selfUserID = _selfUserID;
                this.Text = _selfUserID;//在窗体上显示本用户ID             
                InitializeComponent();
            }
    
            private void button_Send_Click(object sender, EventArgs e)
            {
                string msg = this.textBox_Input.Text;//聊天消息
                Byte[] msgCode = Encoding.UTF8.GetBytes(msg);//转码以备发送
               //从输入框读取待发送用户ID
                //利用通信引擎发送消息
                this.clientEngine.CustomizeOutter.Send(this.targetUserID, InformationType.Chat, msgCode);
                this.ShowChatMsg(this.selfUserID, msg);         
            }
            //将聊天消息按一定格式显示在界面上
            public void ShowChatMsg(string UserID, string msg)
            {
                this.richTextBox_Output.AppendText(UserID + "  " + DateTime.Now.ToString() + "
    ");
                this.richTextBox_Output.AppendText(msg + "
    ");
                this.richTextBox_Output.ScrollToCaret();
                this.textBox_Input.Text = "";
            }
            //开启视频
            private void button_Video_Click(object sender, EventArgs e)
            {
                this.targetUserID = this.textBox_TargetUserID.Text;
                Form_Video form_Video = new Form_Video(this.targetUserID/*待连接用户ID*/);//创建视频窗
                form_Video.Show();//显示视频窗
            }
        }
    }

        3.视频窗设计

           对于实现视频聊天而言,视频窗最主要的任务就是将视频连接器cameraConnector连接到目标用户的摄像头

    namespace Client
    {
        public partial class Form_Video : Form
        {
            public Form_Video(string targetUserID)
            {
                InitializeComponent();
                //预定摄像头连接器的连接结束和连接断开事件             
                this.cameraConnector.ConnectEnded += new ESBasic.CbGeneric<OMCS.Passive.ConnectResult>(cameraConnector_ConnectEnded);
                this.cameraConnector.Disconnected += new ESBasic.CbGeneric<OMCS.Passive.ConnectorDisconnectedType>(cameraConnector_Disconnected);
                this.cameraConnector.BeginConnect(targetUserID/*待连接用户ID*/);//尝试连接目标多媒体设备           
            }
    
            void cameraConnector_Disconnected(OMCS.Passive.ConnectorDisconnectedType connectorDisconnectedType)
            {
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new CbGeneric<ConnectorDisconnectedType>(this.cameraConnector_Disconnected), connectorDisconnectedType);
                }
                else
                {
                    this.Text = string.Format("视频:断开,{0}", connectorDisconnectedType);
                    if (connectorDisconnectedType == ConnectorDisconnectedType.TrialTimeout)
                    {
                        MessageBox.Show("Trial Timeout");
                    }
                }
            }
    
            void cameraConnector_ConnectEnded(ConnectResult result)
            {
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new CbGeneric<ConnectResult>(this.cameraConnector_ConnectEnded), result);
                }
                else
                {
                    //显示视频连接结果
                    this.Text = string.Format("视频:{0}", result == ConnectResult.Succeed ? "正常" : result.ToString());
                }
            }
    
            //关闭窗口时,主动断开连接,并释放连接器
            private void Form_Video_FormClosed(object sender, FormClosedEventArgs e)
            {
                this.cameraConnector.Disconnect();//与目标用户的多媒体设备断开连接
                this.cameraConnector.Dispose(); //释放资源        
            }     
        }
    }

    四·源码下载

          MiniQQ1.1

        本Demo仅仅实现了客户端互相打视频,更多更丰富的功能将在高版本中逐步为大家展示,欢迎大家持续关注哦!

        如果您觉得对您有点帮助的话请点个赞吧!

  • 相关阅读:
    边缘节点为什么不能直接通过 kubernetes service 直接访问云端 master 节点中的 API Server
    Leaflet中原生方式实现测距
    http网页是否能引用https资源/调用https接口?https网页是否能引用http资源/调用http接口?
    Vite2 Vue3 SSR
    SQL模糊查询的四种匹配模式
    vue3中ref、reactive、toRef、toRefs区别
    iis在访问vue服务时报错
    vue3中使用elform
    koa2cors实现过程以及应用
    chrome v8的垃圾回收机制和内存泄漏分析
  • 原文地址:https://www.cnblogs.com/aoyeyuyan/p/4466597.html
Copyright © 2020-2023  润新知