zhuweisky

电脑杂谈  发布时间:2020-05-16 15:10:07  来源:网络整理

讨论组语音怎么开_讨论组语音怎么开_开黑语音麦克风

文章“ C#实现语音聊天”发表后,许多朋友建议我也建立一个视频作为参考. 实际上,视频和语音的原理是相似的,因为添加了. 视频处理的逻辑将更加复杂. 本文实现了一个简单的视频聊天系统,该系统允许多个人进入同一房间进行语音和视频通信. 首先看一下由3个人执行的视频聊天的运行效果的屏幕截图:

以上两个屏幕截图分别是: 登录界面,标有各种控件的视频主界面.

很明显,我的语音使用C / S结构,整个项目结构相对简单,如下所示:

像语音一样,该项目的底层也基于OMCS语音和视频框架. 这样,服务器不编写任何代码,而直接使用OMCS服务器. 客户比较麻烦. 下面,我将重点介绍客户端的开发.

客户端开发了多个自定义控件,然后将它们组装在一起以完成视频的功能. 为了便于说明,我的主界面上的图片被标记为指示每个自定义控件.

讨论组语音怎么开_开黑语音麦克风_讨论组语音怎么开

现在,我们分别介绍每个控件:

分贝显示器用于显示声音的大小,例如麦克风收集的声音或扬声器播放的声音. 如上面的图2所示.

(1)傅立叶变换

傅里叶变换用于将声音数据转换为强度. 它对应于客户端项目中的FourierTransformer静态类. 源代码相对简单,因此将不会发布. 让我们自己看看吧.

(2)声音强度显示控件DecibelDisplayer

DecibelDisplayer使用PrograssBar显示声音强度.

只要有声音数据移交给DecibelDisplayer进行显示,首先,DecibelDisplayer就会调用上面的傅里叶变换将其转换为分贝,然后将其映射到相应的PrograssBar值.

VideoPanel用于表示中的成员,如上面的1所示. 它显示成员的ID,成员的声音强度(使用DecibelDisplayer控件),麦克风的状态(启用,禁用),的状态(不可用讨论组语音怎么开,正常,禁用),成员的视频,等

讨论组语音怎么开_讨论组语音怎么开_开黑语音麦克风

此控件非常重要,我发布了其源代码:

复制代码

    public partial class VideoPanel : UserControl
    {
        private IChatUnit chatUnit;
        private bool isMySelf = false;
        public VideoPanel()
        {
            InitializeComponent();
        }       /// <summary>
        /// 初始化成员视频显示控件。
        /// </summary>       
        public void Initialize(IChatUnit unit ,bool myself)
        {          this.chatUnit = unit;
            this.isMySelf = myself;
            this.toolStripLabel_displayName.Text = unit.MemberID;
            this.decibelDisplayer1.Visible = !myself;            
            //初始化麦克风连接器
            this.chatUnit.MicrophoneConnector.Mute = myself;
            this.chatUnit.MicrophoneConnector.SpringReceivedEventWhenMute = myself;
            this.chatUnit.MicrophoneConnector.ConnectEnded += new CbGeneric<ConnectResult>(MicrophoneConnector_ConnectEnded);
            this.chatUnit.MicrophoneConnector.OwnerOutputChanged += new CbGeneric(MicrophoneConnector_OwnerOutputChanged);
            this.chatUnit.MicrophoneConnector.AudioDataReceived += new CbGeneric<byte[]>(MicrophoneConnector_AudioDataReceived);
            this.chatUnit.MicrophoneConnector.BeginConnect(unit.MemberID);
            //初始化连接器
            this.chatUnit.DynamicCameraConnector.SetViewer(this.skinPanel1);
            this.chatUnit.DynamicCameraConnector.ConnectEnded += new CbGeneric<ConnectResult>(DynamicCameraConnector_ConnectEnded);
            this.chatUnit.DynamicCameraConnector.OwnerOutputChanged += new CbGeneric(DynamicCameraConnector_OwnerOutputChanged);
            this.chatUnit.DynamicCameraConnector.BeginConnect(unit.MemberID);
        }
        //好友启用或禁用
        void DynamicCameraConnector_OwnerOutputChanged()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric(this.DynamicCameraConnector_OwnerOutputChanged));
            }
            else
            {
                this.ShowCameraState();
            }
        }
        private ConnectResult connectCameraResult;
        //连接器尝试连接的结果
        void DynamicCameraConnector_ConnectEnded(ConnectResult res)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric<ConnectResult>(this.DynamicCameraConnector_ConnectEnded), res);
            }
            else
            {
                this.label_tip.Visible = false;
                this.connectCameraResult = res;
                this.ShowCameraState();
            }           
        }
        /// <summary>
        /// 综合显示的状态。
        /// </summary>
        private void ShowCameraState()
        {            
            if (this.connectCameraResult != OMCS.Passive.ConnectResult.Succeed)
            {
                this.pictureBox_Camera.BackgroundImage = null;
                this.pictureBox_Camera.BackgroundImage = this.imageList2.Images[2];
                this.pictureBox_Camera.Visible = true;
                this.toolTip1.SetToolTip(this.pictureBox_Camera, this.connectCameraResult.ToString());
            }
            else
            {
                this.pictureBox_Camera.Visible = !this.chatUnit.DynamicCameraConnector.OwnerOutput;                
                if (!this.chatUnit.DynamicCameraConnector.OwnerOutput)
                {
                    this.pictureBox_Camera.BackgroundImage = this.imageList2.Images[1];
                    this.toolTip1.SetToolTip(this.pictureBox_Camera, "被主人禁用!");
                    return;
                }     
            }
        }
        //将接收到的声音数据交给分贝显示器显示
        void MicrophoneConnector_AudioDataReceived(byte[] data)
        {
            this.decibelDisplayer1.DisplayAudioData(data);
        }
        //好友启用或禁用麦克风
        void MicrophoneConnector_OwnerOutputChanged()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric(this.MicrophoneConnector_OwnerOutputChanged));
            }
            else
            {
                this.ShowMicState();
            }
        }
        private ConnectResult connectMicResult;
        //麦克风连接器尝试连接的结果
        void MicrophoneConnector_ConnectEnded(ConnectResult res)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric<ConnectResult>(this.MicrophoneConnector_ConnectEnded), res);
            }
            else
            {
                this.connectMicResult = res;
                this.ShowMicState();
            }
        }
        /// <summary>
        /// 综合显示麦克风的状态。
        /// </summary>
        private void ShowMicState()
        {            
            if (this.connectMicResult != OMCS.Passive.ConnectResult.Succeed)
            {
                this.pictureBox_Mic.Visible = true;
                this.toolTip1.SetToolTip(this.pictureBox_Mic, this.connectMicResult.ToString());
            }
            else
            {                
                this.decibelDisplayer1.Working = false;
                this.pictureBox_Mic.Visible = !this.chatUnit.MicrophoneConnector.OwnerOutput;
                this.decibelDisplayer1.Visible = this.chatUnit.MicrophoneConnector.OwnerOutput && !this.isMySelf;
                if (!this.chatUnit.MicrophoneConnector.OwnerOutput)
                {                    
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[1];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "麦克风被主人禁用!");
                    return;
                }
                this.pictureBox_Mic.Visible = !isMySelf;
                if (this.chatUnit.MicrophoneConnector.Mute)
                {
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[1];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "静音");
                }
                else
                {
                    this.pictureBox_Mic.Visible = false;
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[0];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "正常");
                    this.decibelDisplayer1.Working = true;
                }
            }
        }
       
        /// <summary>
        /// 展开或收起视频面板。
        /// </summary>       
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.Height > this.toolStrip1.Height)
                {
                    this.toolStripButton1.Text = "展开";
                    this.toolStripButton1.Image = Resources.Hor;
                    this.chatUnit.DynamicCameraConnector.SetViewer(null);
                    this.Height = this.toolStrip1.Height;
                }
                else
                {
                    this.toolStripButton1.Text = "收起";
                    this.toolStripButton1.Image = Resources.Ver;                  
            this.chatUnit.DynamicCameraConnector.SetViewer(this.skinPanel1);
                }
            }
            catch (Exception ee)
            {               
                MessageBox.Show(ee.Message);
            }
        }            
    }

复制代码

(1)在代码中,IChatUnit表示此中的当前成员. 我们使用其MicrophoneConnector连接到目标成员的麦克风,并使用DynamicCameraConnector连接到目标成员的摄像机.

(2)安排MicrophoneConnector的AudioDataReceived事件,并在其接收语音数据时,将其提供给DecibelDisplayer以显示声音的大小.

(3)调度MicrophoneConnector的ConnectEnded和OwnerOutputChanged事件,并根据结果(对应于ShowMicState方法)在VideoPanel控件上显示麦克风图标的状态.

(4)安排DynamicCameraConnector的ConnectEnded和OwnerOutputChanged事件,并根据结果(与ShowCameraState方法相对应)在VideoPanel控件上显示摄像机图标的状态.

讨论组语音怎么开_讨论组语音怎么开_开黑语音麦克风

MultiAudioChatContainer对应于上图中标记为3的控件,它主要做以下事情:

(1)在初始化期间加入: 通过调用IMultimediaManager的ChatGroupEntrance属性的Join方法.

(2)使用FlowLayoutPanel列出与中每个成员相对应的VideoPanel.

(3)当成员加入或离开时(对应于ChatGroup的SomeGroupJoin和SomeoneExit事件),将动态添加或删除相应的VideoPanel实例.

(4)通过CheckBox公开对自己的设备(相机,麦克风,扬声器)的控制. 我们可以启用或禁用我们自己的麦克风或扬声器.

(5)请注意,它提供了Close方法,这意味着当您关闭包含该控件的宿主窗体时,需要调用其Close方法以释放其中包含的麦克风连接器,相机连接器等.

完成MultiAudioChatContainer后,我们的核心几乎相同. 下一步是获取主窗体,然后向上拖动MultiVideoChatContainer,初始化IMultimediaManager,然后将其传递给MultiVideoChatContainer讨论组语音怎么开,您就完成了.

以上内容仅讨论了实现视频的几个关键点. 它不全面. 您可以下载以下源代码以进行更深入的研究.

讨论组语音怎么开_开黑语音麦克风_讨论组语音怎么开

VideoChatRoom.rar

最后,向所有人介绍部署步骤:

(1)在服务器上部署服务器并启动服务器.

(2)将客户端配置文件中的ServerIP修改为刚才的服务器IP.

(3)在多台计算机上运行客户端,并使用不同的帐户(例如默认的R1000)登录到同一房间.

(4)这样,多个用户可以在同一个中进行视频聊天.

zhuweisky

原始文章390赞扬398次访问106万+

关注他的留言板


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-212011-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...