一·效果展示

源码派送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(); //释放资源
}
}
}

四·源码下载

MiniQQ1.1

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

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

循序渐进做项目系列(4)迷你QQ篇(2)——视频聊天!(附源码)的更多相关文章

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

    <循序渐进做项目系列迷你QQ篇>将陆续介绍客户端聊天,文件传输,加好友,群聊,包括语音聊天,视频聊天,远程桌面等等需求如何实现,感兴趣的朋友可以持续关注.考虑到某些需求较为复杂,本系列采用 ...

  2. 循序渐进做项目系列(2):最简单的C/S程序——消息异步调用与消息同步调用

    上篇博客 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法 实现了一个最简单的C/S程序,即让服务器来做加法.当时为了通俗易懂采用了消息异步调用的方式.今天我们要采用消息同步调用的方式 ...

  3. 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法

    (本文是专门针对未接触过C/S开发的初学者而写的,C/S开发高手请自动忽略啊~~) 还在写“Hello world!”式的单机程序吗?还在各种拖控件吗?是否自己都觉得有点low呢?来个质的飞跃吧!看看 ...

  4. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(24)-权限组的设计和实现(附源码)(终结)

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  5. C# 30分钟完成百度人脸识别——进阶篇(文末附源码)

    距离上次入门篇时隔两个月才出这进阶篇,小编惭愧,对不住关注我的卡哇伊的小伙伴们,为此小编用这篇博来谢罪. 前面的准备工作我就不说了,注册百度账号api,创建web网站项目,引入动态链接库引入. 不了解 ...

  6. C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...

  7. 我们一起学习WCF 第一篇初识WCF(附源码供对照学习)

    前言:去年由于工作需要我学习了wcf的相关知识,初期对wcf的作用以及为何用怎么样都是一知半解,也许现在也不是非常的清晰.但是通过项目对wcf的运用在脑海里面也算有了初步的模型.今天我就把我从开始wc ...

  8. 循序渐进做项目系列(5):制作安装包,谁人都可以!——VS制作安装包简明教程

    一开始让我做安装包的时候,其实我是拒绝的.因为我根本就不会做安装包.查了资料之后,我很懵,很晕,很乱,因为不清晰,不简明,不直白.然而经过一番彷徨的挣扎,我终于发现:制作安装包,谁人都可以!故挥狼毫, ...

  9. arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

随机推荐

  1. UE3名称结构(Name)

    解释说明: (1) 直接通过FName的index进行比较来判断两个FName是否相等 (2) 通过FName的index从全局Names数组中取出对应的FNameEntry,可以获得FName的字符 ...

  2. LinkedList源码阅读笔记(基于JDK1.8)

    LinkedList是List接口的一个有序链表实现,存储节点是内部类Node,Node中有两个属性prev和next,负责连接前后两个元素.由于不是使用数组进行存储,所以查询需要遍历链表一半的元素( ...

  3. PHP常用函数、数组方法

    常用函数:rand(); 生成随机数rand(0,50); 范围随机数时间:time(); 取当前时间戳date("Y-m-d H:i:s"); Y:年 m:月份 d:天 H:当前 ...

  4. 安卓四核PDA手持PDA智能POS机 打印二维码 分享

    很多项目都会用到 类似的要求  移动手持终端 通过程序 可以生成条码或二维码 打印出小票或标签纸 下面直接上代码 希望对大家有点用处 private void print(){ csys.setTex ...

  5. Linq的分页

    真有趣. C#里面的List对象.set对象,都可以直接使用Linq(这是因为,它们都实现了接口IEnumable?),比如说:Where().OrderBy()什么的.假如有点SQL基础的人,一看这 ...

  6. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  7. [资料分享]SQL Server 2016/2014/2012/2008简体中文企业版下载+对应补丁

    为什么只提供企业版下载呢?因为不管你是学生还是工作研究人员,企业版都是功能最为齐全的一个版本,比如企业版都集成了SQL Server Management Studio管理界面(俗称企业管理器的可视化 ...

  8. 【BZOJ3172】[Tjoi2013]单词 AC自动机

    [BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...

  9. 说说js作用域

    开始就来说说作用域这个蛋疼的东西.里面可能会出现各种的问题 .先给一个简单的例子大家猜猜结果是什么 var   a="b"; function text(){ alert(a);v ...

  10. Agile

    I think Agile development methodologies is something we get from our practice. It can be just acknow ...