一·效果展示

源码派送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. 【DWR系列06】- DWR日志及js压缩

    img { border: solid 1px } 一.日志 DWR依赖 Apache Commons Logging,可以使用log4j实现日志记录功能. 1.1 日志简介 和其他日志框架一样,当设 ...

  2. 深入理解Java:SimpleDateFormat安全的时间格式化

    这一篇我什么都不写,只推荐一篇大牛的博客,这篇博客给了我很多灵感,让我对多线程理解的更加透彻了; http://www.cnblogs.com/chenying99/articles/3331950. ...

  3. Ubuntu菜鸟入门(五)—— 一些编程相关工具

    一.sublime text3 sudo add-apt-repository ppa:webupd8team/sublime-text- sudo apt-get update sudo apt-g ...

  4. Maven仓库 国内镜像

    <repositories> <repository> <id>repo-mirror</id> <url>http://maven.net ...

  5. 360浏览器导出Excel闪退BUG

    最近这半个月在疯狂的修改各种BUG,所以比较少更新博客. 现在谈谈这个360浏览器导出Excel的BUG的解决方法. 该BUG常出现在win7系统与xp系统导出Excel的瞬间关闭导出弹窗. 目前互联 ...

  6. 商贸食品车销成功应用PDA抄单 现场开单 打印销售单安卓智能手持POS应用

    中小超市配送食品,酒水饮料,业务员以往是挨家挨户抄每个超市需要哪些东西,晚上回公司再统计,打到软件里面,开单配货. 选用PDA后,人手一台,直接在超市里面抄好货物,通过网络传输到公司软件上面,加快了工 ...

  7. DotnetCore Docker

    FROM microsoft/dotnet:1.0.0-preview2-sdk RUN mkdir /app WORKDIR /app COPY project.json /app RUN [&qu ...

  8. c、c++ 常用函数记录

    1.void*  memcpy(char*dest, char*src, size_tnum) 将第二个参数拷贝到第一个参数,最后一个是长度. 2.void *memset(void *s, int ...

  9. BZOJ4596: [Shoi2016]黑暗前的幻想乡

    Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖 怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类) 博丽灵梦和八云紫等人整日高谈所有妖怪 ...

  10. java分享第十四天(TestNG Assert详解)

     TestNG Assert 详解org.testng.Assert 用来校验接口测试的结果,那么它提供哪些方法呢? 中心为Assert测试类,一级节点为方法例如assertEquals,二级结点为参 ...