Duane Burton Sr. Technical Marketing Engineer
Intel Corporation
Jim Huang
Sr. Technical Marketing Engineer
Intel Corporation
2002年六月
应用于
Microsoft® Windows® XP
摘要: 本文介绍了怎样利用实时通信(RTC)应用编程接口(API)来实现音视频会议、应用程序共享、白板、简单的点对点聊天和音视频调节向导。RTC API提供了卓越的基于PC的通信上的革新,这可应用于所有基于Microsoft Windows XP的应用程序。
下载 RTCSampleCode.zip.
目录
绪论
RTC客户端接口
初始化会话
处理RTC事件
创建会话
处理实时流会话事件
关闭会话
平台性能
结论
参考资料
绪论
微软的实时通信(RTC)应用编程接口(API)提供了显著的基于PC的通信上的革新—即时消息、音视频会议和应用程序共享/合作,这可应用于所有基于Microsoft® Windows® XP的应用程序。
使用RTC的API来进行通信是一个非常简单的过程。
1、客户端应用程序确定参与通信的平台的性能。
2、应用程序选择通信中首选的视音频设备。
3、应用程序初始化会话。
4、RTC层调整数据的获取、压缩和传输,这使得应用程序不用负责这一任务。使用哪一种音视频的编码解码器 由通信双方的连接质量决定。
5、参与会话的应用程序接受、解压并重放被传输的数据。
插图见连接:
图一、音视频会议的界面
本文描述了怎样为一个应用程序添加PC-to-PC的RTC基本能力;我们假定你对使用COM对象开发Windows应用程序已经很熟悉。本文所讨论的源代码可在本文开始所给出的连接里获得。我们以后将会讨论PC-to-Phone、现场能力和XML配置。
例子代码展示了使用实时通信API实现音视频会议、应用程序共享、白板、简单的点对点聊天和音视频调节向导的基本要素。其他RTC 支持但本文没有讨论的特征有回波抵消(AEC)、前向错误校验(FEC)、 带宽估计、动态抖动缓冲管理、自动增益控制(AGC)和服务质量(QC)控制算法。在《Microsoft Windows的实时通信客户端的媒体支持》中描述了上述特征。
RTC客户端接口
所需头文件: rtccore.h
你的应用程序需要通过CoCreateInstance()来获得RTC接口,CLSID_RTCClient(GUID = {7a42ea29-a2b7-40c4-b091-f6f024aa89be})作为参数。一旦获得了接口,用Initialize()来初始化COM对象,以确定该平台的通信能力。
// Initialize the RTC COM object
hr = CoCreateInstance (CLSID_RTCClient, NULL,
CLSCTX_INPROC_SERVER, IID_IRTCClient,
(LPVOID *)&m_pClient);
// Initialize the client interface
hr = m_pClient->Initialize();
选择通信能力
下一步是选择首选的通信类型和相关设备(摄像机、麦克风等)。缺省配置是激活所有通信类型。如果会话的参与者能共享应用程序、传送即时消息和音视频会议,那么这些通信类型自动被激活。如果某一参与者不支持某种通信类型,那么所有的参与者都不能激活该类型。
m_pClient->SetPreferredMediaTypes ( RTCMT_ALL, VARIANT_TRUE );
会议参与者的平台性能和可用带宽决定了使用哪一种codec。
· 视频:Windows RTC 客户端支持分辨率为QCIF(176×144)的H.261和H.263 codecs。 这些比特率可变的codecs以6~125 Kbps传送视频数据。使用IRTCClient方法中的put_MaxBitRate和put_TemporalSpatialTradeOff有可能会影响到视频传送的空间和瞬时清晰度。
· 音频:Windows RTC客户端支持许多音频codec。音频codec由连接的两端共同决定。下表列出了所支持的音频codec。
|
CODEC |
取样率(kHz) |
比特率(Kbps) |
帧长 (msec) |
|
G.711 |
8 |
64 |
20 |
|
G.722.1 |
16 |
24 |
20 |
|
G.723 |
8 |
6.4 |
30, 60, or 90 |
|
GSM |
8 |
13 |
20 |
|
DVI4 |
8 |
32 |
20 |
|
SIREN |
16 |
16 |
20, or 40 |
调整通信设备
选择了首选的通信类型和相关设备之后,调整通信设备。RTC的API提供了向导对摄像机和麦克风进行调整。使用RTCClient中的方法InvokeTuningWizard()可调整它们的设置。
插图见连接:
图2:摄像机调节向导
图3:麦克风调节向导
初始化会话
在应用程序与其他参与者连接之前,它必须能够处理会话中的RTC事件。PC-to-PC的通信中,应用程序捕获即时消息事件、音量事件、媒体事件、客户端消息事件和会话状态改变事件。下述代码展示了怎样创建一个事件过滤器来捕获RTC客户端的特定事件。
lEventMask设置了一组应用程序感兴趣的事件。(为获得全部的事件列表,可在MSDN站点搜索RTC_EVENT,这样可以获得关于每一事件的更多信息。)CRTCEvents 类在客户端之间分配事件。 RTCEvents 对象在应用程序和 IRTCEventNotification接口之间创建接口。 所有的RTC事件由RTCEvents 类处理。
// Set the event filter to listen for RTC events
// Using RTCEF_ALL will listen for all events
// For the sample application, we will demonstrate how to set the
// event listener for a limited set of events.
long lEventMask = RTCEF_SESSION_STATE_CHANGE |
RTCEF_MESSAGING |
RTCEF_MEDIA |
RTCEF_INTENSITY |
RTCEF_CLIENT;
hr = m_pClient->put_EventFilter( lEventMask );
// Create the event sink object
m_pEvents = new CRTCEvents;
// initialize the event handler
hr = m_pEvents->Advise( m_pClient, m_hWnd );
// Set the listen mode for RTC client
// RTCLM_BOTH opens the standard SIP port 5060, as well as
// a dynamic port.
hr = m_pClient->put_ListenForIncomingSessions(RTCLM_BOTH);
音视频的媒体类型可在会话过程中添加或删除,因此客户端必须能监听这些类型的事件。在“处理实时流会话事件”这一节中可获得关于状态改变和事件处理的更多信息。
处理RTC事件
一旦事件处理者IRTCEventNotification接收器中进行了注册,接收和处理RTC事件就变得相当的容易了。当例子程序接收到RTC事件时,应用程序的事件处理者就对应用程序的消息处理者发一个消息。OnRTCEvent() 处理应用程序接收到的所有事件。
OnRTCEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
// Based on the RTC_EVENT type, query for the
// appropriate event interface and call a helper
// method to handle the event
switch ( wParam )
{
….
….
….
case RTCE_MEDIA:
{
IRTCMediaEvent * pEvent = NULL;
hr = pDisp->QueryInterface( IID_IRTCMediaEvent,
(void **)&pEvent );
if (SUCCEEDED(hr))
{
OnRTCMediaEvent(pEvent);
SAFE_RELEASE(pEvent);
}
}
break;
….
….
….
}
创建一个会话
当你在RTC中发起一个呼叫之前,你必须创建并且初始化一个会话。 然后你可以输入参与者的IP地址来发起一个呼叫。可可能通过属于一个e-mail 地址或者一个电话号码来激活一个会话。然而,这一功能需要一个SIP注册服务器,对它的讨论超出了本文的范围。参阅MSDN可获得关于SIP注册服务器的更多信息。
RTC目前还不支持多方视频通话,因此应用程序在初始化一个新会话之前,必须保证没有视频会议在进行。在它第一个发布版本中,Windows RTC客户端只支持多方电话会议,并不支持多方音视频会话和视频会议。
为与另一台PC通话,确定RTC会话类型并且使用IRTCSession接口创建一个同类型的会话。下列代码展示了如何创建会话。
HRESULT CAVDConfDlg::MakeCall(RTC_SESSION_TYPE enType, BSTR bstrURI)
{
...
// Create the session
IRTCSession * pSession = NULL;
hr = m_pClient->CreateSession(enType, NULL, NULL, 0, &pSession);
// Add the participant to the session
hr = pSession->AddParticipant(bstrURI, NULL, &m_Participant);
...
return S_OK;
}
处理实时流会话事件
根据不同的会话类型,存在媒体事件、音量事件、即时消息事件和会话状态改变事件。
媒体事件
处理媒体事件需要得到媒体类型、事件类型和原因,然后发送消息给会话窗口。应用程序可以使用