循序渐进做项目系列(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(/*端口号*/, serverHandler); DefaultUserVerifier userVerifier = new DefaultUserVerifier();//默认任何用户都验证通过
//OMCS配置信息
OMCSConfiguration config = new OMCSConfiguration(/*摄像头采集的帧频*/,
/*远程桌面的帧频*/,
EncodingQuality.Middle/*语音编码的质量*/);
//创建多媒体服务器
IMultimediaServer MultimediaServer = MultimediaServerFactory.CreateMultimediaServer(/*监听的端口*/,
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", , clientHandler);
//创建多媒体设备管理器
IMultimediaManager multimediaManager = MultimediaManagerFactory.GetSingleton();
multimediaManager.CameraDeviceIndex = ;//要使用的摄像头的索引
multimediaManager.AutoAdjustCameraEncodeQuality = false;//是否根据音频反馈以及视频丢帧情况自动调整视频编码质量
//与多媒体服务器建立连接,并初始化本地多媒体管理器。
multimediaManager.Initialize(this.textBox_UserID.Text,/*当前登录的用户ID*/
null,/*当前登录的用户的密码*/
"127.0.0.1",/*OMCS服务器IP*/
);/*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() + "\n");
this.richTextBox_Output.AppendText(msg + "\n");
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(); //释放资源
}
}
}
四·源码下载
本Demo仅仅实现了客户端互相打视频,更多更丰富的功能将在高版本中逐步为大家展示,欢迎大家持续关注哦!
如果您觉得对您有点帮助的话请点个赞吧!
循序渐进做项目系列(4)迷你QQ篇(2)——视频聊天!(附源码)的更多相关文章
- 循序渐进做项目系列(3):迷你QQ篇(1)——实现客户端互相聊天
<循序渐进做项目系列迷你QQ篇>将陆续介绍客户端聊天,文件传输,加好友,群聊,包括语音聊天,视频聊天,远程桌面等等需求如何实现,感兴趣的朋友可以持续关注.考虑到某些需求较为复杂,本系列采用 ...
- 循序渐进做项目系列(2):最简单的C/S程序——消息异步调用与消息同步调用
上篇博客 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法 实现了一个最简单的C/S程序,即让服务器来做加法.当时为了通俗易懂采用了消息异步调用的方式.今天我们要采用消息同步调用的方式 ...
- 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法
(本文是专门针对未接触过C/S开发的初学者而写的,C/S开发高手请自动忽略啊~~) 还在写“Hello world!”式的单机程序吗?还在各种拖控件吗?是否自己都觉得有点low呢?来个质的飞跃吧!看看 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(24)-权限组的设计和实现(附源码)(终结)
ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2):数据库访问层的设计Demo (3):面向接口编程 (4 ):业务逻辑层的封装 ...
- C# 30分钟完成百度人脸识别——进阶篇(文末附源码)
距离上次入门篇时隔两个月才出这进阶篇,小编惭愧,对不住关注我的卡哇伊的小伙伴们,为此小编用这篇博来谢罪. 前面的准备工作我就不说了,注册百度账号api,创建web网站项目,引入动态链接库引入. 不了解 ...
- C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...
- 我们一起学习WCF 第一篇初识WCF(附源码供对照学习)
前言:去年由于工作需要我学习了wcf的相关知识,初期对wcf的作用以及为何用怎么样都是一知半解,也许现在也不是非常的清晰.但是通过项目对wcf的运用在脑海里面也算有了初步的模型.今天我就把我从开始wc ...
- 循序渐进做项目系列(5):制作安装包,谁人都可以!——VS制作安装包简明教程
一开始让我做安装包的时候,其实我是拒绝的.因为我根本就不会做安装包.查了资料之后,我很懵,很晕,很乱,因为不清晰,不简明,不直白.然而经过一番彷徨的挣扎,我终于发现:制作安装包,谁人都可以!故挥狼毫, ...
- arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...
随机推荐
- Datazen配置
Datazen是被微软收购的移动端全平台的数据展现解决方案.此篇主要介绍其服务器端的配置过程. 在上一篇的基础安装完成之后,在浏览器敲入如下地址进入系统的控制面板(留意安装的时候配置的是80 web端 ...
- Windows平台手动卸载Oracle Server【完整+干净】
使用Oracle自带的Universal Installer卸载存在问题: 不干净,不完全,还有一些注册表残留,会影响到后来的安装. 所以,推荐使用手工卸载Oracle. 1.[win+R]-> ...
- 安装opensuse时遇到的一些问题
1.硬盘安装suse的时候提示找不到源,因为是2块硬盘所以需要mount一下硬盘. 2.安装N卡驱动的时候,推荐一键安装,不然需要把所有GCC和make安装好,并且禁用系统的nouneau.
- AOJ 0558 Cheese【BFS】
在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次), ...
- Python-基础数据类型
数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定 ...
- Andriod学习笔记4:mac下搭建 Eclipse+CDT 集成开发环境
下载CDT 从eclipse官网下载最新的Eclipse IDE for C/C++ Developers,例如eclipse-cpp-mars-1-macosx-cocoa-x86_64.tar.g ...
- android Studio 百度KEY获得发布版 SHA1 的方法
看图说话 build-->Generate Signed APK... create new(看不懂单词意思的同胞可以参考这个网址http://www.cnblogs.com/why168888 ...
- LNMP虚拟机开发环境配置--vagrant+virtualbox+ubuntu14.04
工作一直用的是别人打包好的虚拟机开发环境,感觉确实很酷.所以准备自己配个开发环境,为之后自己开发一些有趣的东西做准备. ok,开始~~~ 一.安装软件 vagrant和virtualbox 此处需注意 ...
- startssl申请配置免费https证书
之前给业务配置都是在沃通上申请免费证书,而后通过反向代理层的Nginx进行https认证. 今天来了个新需求,要求域名直接解析至阿里云SLB.https配置需要通过阿里云的控制台部署这倒无所谓,只是在 ...
- Linux内核笔记--内存管理之用户态进程内存分配
内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...