java短语音聊天室_实现一个简单的语音聊天室(源码)
语音聊天室,或多人语音聊天,是即时通信应用中常见的功能之一,比如,QQ的语音讨论组就是我们用得比较多的。
这篇文章将实现一个简单的语音聊天室,让多个人可以进入同一个房间进行语音沟通。先看运行效果截图:
从左到右的三张图分别是:登录界面、语音聊天室的主界面、标注了各个控件的主界面。
(如果觉得界面太丑,没关系,后面下载源码后,你可以自己美化~~)
一. C/S结构
很明显,我这个语音聊天室采用的是C/S结构,整个项目结构相对比较简单,如下所示:
该项目的底层是基于
二. 客户端控件式开发
客户端开发了多个自定义控件,然后将它们组装到一起,以完成语音聊天室的功能。为了便于讲解,我主界面的图做了标注,以指示出各个自定义控件。
现在我们分别介绍各个控件:
1. 分贝显示器
分贝显示器用于显示声音的大小,比如麦克风采集到的声音的大小,或扬声器播放的声音的大小。如上图中3标注的。
(1)傅立叶变换
将声音数据转换成分贝强度使用的是傅立叶变换。其对应的是客户端项目中的FourierTransformer静态类。源码比较简单,就不贴出来了,大家自己去看。
(2)声音强度显示控件 DecibelDisplayer
DecibelDisplayer 使用的是PrograssBar来显示声音强度的大小。
每当有声音数据交给DecibelDisplayer显示时,首先,DecibelDisplayer会调用上面的傅立叶变换将其转换为分贝,然后,将其映射为PrograssBar的对应的Value。
2.发言者控件 SpeakerPanel
SpeakerPanel 用于表示聊天室中的一个成员,如上图中1所示。它显示了成员的ID,成员的声音的强度(使用DecibelDisplayer控件),以及其麦克风的状态(启用、引用)。
这个控件很重要,我将其源码贴出来:
public partial classSpeakerPanel : UserControl ,IDisposable
{privateChatUnit chatUnit;publicSpeakerPanel()
{
InitializeComponent();this.SetStyle(ControlStyles.ResizeRedraw, true);//调整大小时重绘
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//双缓冲
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);//禁止擦除背景.
this.SetStyle(ControlStyles.UserPaint, true);//自行绘制
this.UpdateStyles();
}public stringMemberID
{get{if (this.chatUnit == null)
{return null;
}return this.chatUnit.MemberID;
}
}public voidInitialize(ChatUnit unit)
{this.chatUnit =unit;this.skinLabel_name.Text =unit.MemberID;this.chatUnit.MicrophoneConnector.ConnectEnded += new CbGeneric(MicrophoneConnector_ConnectEnded);this.chatUnit.MicrophoneConnector.OwnerOutputChanged += newCbGeneric(MicrophoneConnector_OwnerOutputChanged);this.chatUnit.MicrophoneConnector.AudioDataReceived += new CbGeneric(MicrophoneConnector_AudioDataReceived);this.chatUnit.MicrophoneConnector.BeginConnect(unit.MemberID);
}public void Initialize(stringcurUserID)
{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);
}voidMicrophoneConnector_OwnerOutputChanged()
{if (this.InvokeRequired)
{this.BeginInvoke(new CbGeneric(this.MicrophoneConnector_OwnerOutputChanged));
}else{this.ShowMicState();
}
}privateConnectResult connectResult;voidMicrophoneConnector_ConnectEnded(ConnectResult res)
{if (this.InvokeRequired)
{this.BeginInvoke(new CbGeneric(this.MicrophoneConnector_ConnectEnded), res);
}else{this.connectResult =res;this.ShowMicState();
}
}public voidDispose()
{this.chatUnit.Close();
}private voidShowMicState()
{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(objectsender, EventArgs e)
{if (!this.chatUnit.MicrophoneConnector.OwnerOutput)
{return;
}this.chatUnit.MicrophoneConnector.Mute = !this.chatUnit.MicrophoneConnector.Mute;this.ShowMicState();
}
}
(1)在代码中,ChatUnit就代表当前这个聊天室中的成员。我们使用其MicrophoneConnector连接到目标成员的麦克风。
(2)预定MicrophoneConnector的AudioDataReceived事件,当收到语音数据时,将其交给DecibelDisplayer去显示声音的大小。
(3)预定MicrophoneConnector的ConnectEnded和OwnerOutputChanged事件,根据其结果来显示SpeakerPanel空间上麦克风图标的状态(对应ShowMicState方法)。
3. MultiAudioChatContainer 控件
MultiAudioChatContainer对应上图中2标注的控件,它主要做了以下几件事情:
(1)在初始化时,加入聊天室:通过调用IMultimediaManager的ChatGroupEntrance属性的Join方法。
(2)使用FlowLayoutPanel将聊天室中每个成员对应的SpeakerPanel罗列出来。
(3)当有成员加入或退出聊天室时(对应ChatGroup的SomeoneJoin和SomeoneExit事件),动态添加或移除对应的SpeakerPanel实例。
(4)通过CheckBox将自己设备(麦克风和扬声器)的控制权暴露出来。我们可以启用或禁用我们自己的麦克风或扬声器。
(5)注意,其提供了Close方法,这意味着,在关闭包含了该控件的宿主窗体时,要调用其Close方法以释放其内部持有的麦克风连接器等资源。
在完成MultiAudioChatContainer后,我们这个聊天室的核心就差不多了。接下来就是弄个主窗体,然后把MultiAudioChatContainer拖上去,初始化IMultimediaManager,并传递给MultiAudioChatContainer就大功告成了。
三. 源码下载
上面只是讲了实现多人语音聊天室中的几个重点,并不全面,大家下载下面的源码可以更深入的研究。
最后,跟大家说说部署的步骤:
(1)将服务端部署在一台机器上,启动服务端。
(2)修改客户端配置文件中的ServerIP为刚才服务器的IP。
(3)在多台机器上运行客户端,以不同的帐号登录到同一个房间(如默认的R1000)。
(4)如此,多个用户就处于同一个聊天室进行语音聊天了。
敬请了解:
java短语音聊天室_实现一个简单的语音聊天室(源码)相关推荐
- JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库
JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目 ...
- 城乡投票源码php_一个简单的PHP投票程序源码
一个简单的PHP投票程序源码 2021-01-23 10:04:50721 分析: 我们利用一个文件(data.dat)来存储投票栏目.每个栏目占据一行. 这样一来,便可随意加入和减去想要投票的栏目. ...
- 如何实现一个简单的课程网(源码+论文)
1.功能设计 可以分为三个角色管理员.教师.学生,各自的功能如下 2.功能分析 用户注册模块:普通游客只能浏览首页或进入课程中心观看视,但可通过此功能注册成为本站的学生用户,获得更多使用权限. 用户登 ...
- linux下udp实现聊天软件,socket实现一个简单的对话聊天软件
socket可以在网络间进行通信, 基本上有两种通信协议, 一种是TCP, 一种是UDP. UDP是一种面向无链接的通信协议, 通信前无需与对端建立连接. 只要有目的ip地址和port端口, 就可以将 ...
- python写一个聊天程序_python实现一个简单的网络聊天程序
一.Linux Socket 1.Linux Socke基本上就是BSD Socket(伯克利套接字) 伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信.B ...
- java 在线聊天室_一万人一起在线聊天的聊天室,怎样用Java实现?
原标题:一万人一起在线聊天的聊天室,怎样用Java实现? 今天逛论坛的时候发现一个Java Socket实现多人聊天室的源码,感觉写得还不错,至少算个有模有样的聊天工具.虽然有点简单,但是也算是一个项 ...
- 实现一个简单的语音聊天室(源码)
语音聊天室,或多人语音聊天,是即时通信应用中常见的功能之一,比如,QQ的语音讨论组就是我们用得比较多的. 这篇文章将实现一个简单的语音聊天室,让多个人可以进入同一个房间进行语音沟通.先看运行效果截图: ...
- 实现一个简单的语音聊天室(多人语音聊天系统)
多人语音聊天,或语音聊天室,是即时通信应用中常见的功能之一,比如,QQ的语音讨论组就是我们用得比较多的. 本文将基于最新版本的OMCS(V3.5)实现一个简单的语音聊天室,让多个人可以进入同一个房间进 ...
- php 开发一个聊天系统,ajax+php 实现一个简单的在线聊天室功能(附带源码)
通过ajax和setInterval()函数,配合php+mysql实现一个简单的在线聊天室的功能.附带详细源码案例.这个聊天室是一个简单的聊天室,通过javascript setInterval() ...
- 实现一个简单的视频聊天室(源码)
在 <实现一个简单的语音聊天室>一文发布后,很多朋友建议我也实现一个视频聊天室给他们参考一下,其实,视频聊天室与语音聊天室的原理是差不多的,由于加入了摄像头.视频的处理,逻辑会繁杂一些,本 ...
最新文章
- python有序字典_python 学习 有序字典
- Leetcode::Balanced Binary Tree
- 【java作业】2、 编写两个函数,分别使用字节流、字符流实现文件的拷贝;点击按钮,将第三个文本框的字符串的值设置为第一个文本框的字符串+第二个文本框的字符串。
- Excel中根据单元格背景色求和
- CentOS系统下docker的基本命令
- 1.12 Linux查看用户信息
- STM32 f103 实现命令终端
- 装修软件平台开发的优势
- 挖掘Dark Sky Maps(热的要死后,疯传的一个气温地图网站)
- 金业能源科技的汽车消耗能源解决对策
- 分部积分法的快速运算 表格法
- 关于华为设备ospf进程中RID重叠的问题
- 如何在地图上批量标注经纬坐标
- 信用卡客户风险分析与评价
- 医学界的动作捕捉系统(二)
- python 模拟考试系统_Project-OTS: Online Exam System written on Python 3. 基于Python 3的在线考试系统。...
- 无线网卡Intel Corporation Wireless 8265 / 8275在ubuntu系统不能工作
- 测序故事:从框架图到染色体水平组装(一)
- 六一儿童节:虽然小时候吹过的牛没实现,幸亏喜欢的零食玩具还买得起
- Java加密解密算法-SHA加密