站内搜索

搜索

手游源码-游戏源码-棋牌源码资源网-亲测源码-游戏搭建-破解游戏-网站源码-qq技术

100金币/天 购买
100金币/天 购买
100金币/天 购买

QQ的语音聊天室,或多人语音聊天(组图)

18

主题

73

帖子

109

金币

绿钻会员

Rank: 3Rank: 3

积分
269
发表于 2022-1-11 15:01:28 | 显示全部楼层 |阅读模式
语音聊天室,或多人语音聊天,是即时通讯应用中的常用功能之一。比如QQ的语音讨论群,我们用的比较多。 本文将实现一个简单的语音聊天室,允许多人进入同一个房间进行语音交流。先看一下运行效果的截图:
三张图从左到右分别是:登录界面、语音聊天室主界面、标有各个控件的主界面。 (如果觉得界面太丑也没关系,后面下载源码后,自己美化一下吧~~) 一. C/S 结构 很明显,我的语音聊天室采用的是C/S结构,整个项目结构比较简单,如下图:
该项目的底层是建立在 OMCS 之上的。这样,服务端基本不用写代码,直接使用OMCS服务端;客户端比较麻烦,所以我将重点放在客户端的开发上。 二. 客户端控制开发 客户端开发了几个自定义控件,然后将它们组装在一起以完成语音聊天室功能。为方便说明,我的主界面的示意图标明了各个自定义控件。 现在我们分别介绍各个控件: 1. 分贝监视器 分贝显示用于显示声音的音量,例如麦克风拾取的声音的音量聊天室代码,或扬声器播放的声音的音量。如上图3所示。 (1)傅里叶变换 傅里叶变换用于将声音数据转换为分贝强度。它对应于客户端项目中的静态类。源码比较简单,这里就不贴了,大家自己看吧。 (2)声强显示控件 用于显示声音强度的大小。 每当有声音数据需要显示时,首先会调用上面的傅里叶变换将其转换为分贝,然后再映射到对应的Value。 2.扬声器控制 用于表示聊天室中的成员天外神坛,如上图 1 所示。它显示成员的 ID、成员的声音强度(使用控件)以及他们的麦克风状态(启用、引用)。 这个控件很重要,我贴一下它的源码:

        public partial class SpeakerPanel : UserControl ,IDisposable
    {
        private ChatUnit chatUnit;     
        public SpeakerPanel()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.ResizeRedraw, true);//调整大小时重绘
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);// 双缓冲
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);// 禁止擦除背景.
            this.SetStyle(ControlStyles.UserPaint, true);//自行绘制            
            this.UpdateStyles();
        }
        public string MemberID
        {
            get
            {
                if (this.chatUnit == null)
                {
                    return null;
                }
                return this.chatUnit.MemberID;
            }
        }
        public void Initialize(ChatUnit unit)
        {
            this.chatUnit = unit;
            this.skinLabel_name.Text = unit.MemberID;
                   
            this.chatUnit.MicrophoneConnector.ConnectEnded += new CbGenericConnectResult>(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);
        }
        public void Initialize(string curUserID)
        {
            this.skinLabel_name.Text = curUserID;
            this.skinLabel_name.ForeColor = Color.Red;
            this.pictureBox_Mic.Visible = false;
            this.decibelDisplayer1.Visible = false;
        }
        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 connectResult;
        void MicrophoneConnector_ConnectEnded(ConnectResult res)
        {            
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric<ConnectResult>(this.MicrophoneConnector_ConnectEnded), res);
            }
            else
            {
                this.connectResult = res;
                this.ShowMicState();
            }
        }
        public void Dispose()
        {
            this.chatUnit.Close();
        }
        private void ShowMicState()
        {
            if (this.connectResult != OMCS.Passive.ConnectResult.Succeed)
            {
                this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[2];
                this.toolTip1.SetToolTip(this.pictureBox_Mic, this.connectResult.ToString());
            }
            else
            {
                this.decibelDisplayer1.Working = false;
                if (!this.chatUnit.MicrophoneConnector.OwnerOutput)
                {
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[1];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "好友禁用了麦克风");
                    return;
                }
                if (this.chatUnit.MicrophoneConnector.Mute)
                {
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[1];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "静音");
                }
                else
                {
                    this.pictureBox_Mic.BackgroundImage = this.imageList1.Images[0];
                    this.toolTip1.SetToolTip(this.pictureBox_Mic, "正常");
                    this.decibelDisplayer1.Working = true;
                }
            }
        }
        private void pictureBox_Mic_Click(object sender, EventArgs e)
        {
            if (!this.chatUnit.MicrophoneConnector.OwnerOutput)
            {
                return;
            }
            this.chatUnit.MicrophoneConnector.Mute = !this.chatUnit.MicrophoneConnector.Mute;
            this.ShowMicState();
        }
    }

(1)在代码中,它代表了这个聊天室的当前成员。我们用它来连接目标成员的麦克风。 (2)预定事件,当接收到语音数据时,移交给显示声音的音量。 (3)预定sum事件聊天室代码,根据其结果在空间上显示麦克风图标的状态(对应方法)。 3.ner 控制 ner对应上图中标为2的控件,主要做了以下几件事: (1)初始化时加入聊天室:通过调用属性的Join方法。 (2)用于对应列出聊天室中的每个成员。 (3)当成员加入或离开聊天室(对应和事件)时,动态添加或移除对应的实例。 (4)通过公开对我们自己的设备(麦克风和扬声器)的控制。我们可以启用或禁用我们自己的麦克风或扬声器。 (5)注意它提供了一个Close方法,也就是说当包含该控件的宿主窗体关闭时,应该调用它的Close方法来释放内部持有的麦克风连接器等资源。 完成ner之后,我们聊天室的核心就差不多了。下一步是获取一个主窗体,然后将 ner 向上拖动,对其进行初始化,并将其传递给 ner,您就完成了。 三. 源码下载 以上只谈了多人语音聊天室实现中的几个关键点,并不全面。您可以下载下面的源代码进行更深入的研究。 .rar 最后说一下部署步骤: (1)在一台机器上部署服务器并启动服务器。 (2)在客户端配置文件中修改刚才服务器的IP。 (3)在多台机器上运行客户端,用不同的账号登录同一个房间(就像默认的R1000). (4)这样,多个用户在同一个聊天室进行语音聊天。 请理解: 通信框架OMCS网络语音和视频框架MFile语音和视频录制组件语音和视频捕获组件轻量级通信引擎
【天外神坛】免责声明及帮助
1.重要:如果遇到隐藏内容回复后显示为代码状态,直接刷新一下页面即可解决此问题。
2.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
3.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
5.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
6.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

老群被封加此新群不迷路。
上个主题 下个主题 快速回复 返回列表 客服中心 搜索 QQ加群
上个主题 下个主题 快速回复 返回列表 客服中心 搜索 QQ加群

QQ|Archiver|小黑屋|天外神坛

湘ICP备2021015333号

Powered by 天外神坛 X3.4 © 2020-2022 天外神坛