我的IVR的起步。学了很快就忘了,不如写点东西纪念一下。
TAPI最新版本是3.1, 基于COM的。2.2是用C描述的,我没多去研究。不过网上很多的资料也都是用2.2写的,3.1的很少,或是没有。
用TAPI3.1我们不仅可以写出基于公共电话交换网(PSTN)上语音呼叫的应用程序,而且可以写出多点传输的IP多媒体会议。
TAPI3.1的四大组成部份:
1 COM API
2 TAPI Server
3 Telephony Service Providers (TSPs)
4 Media Stream Providers (MSPs)
我们最关心当然是第一部份,其它是服务商的事了。
这个COM组件是以DLL型式提供的,存在于系统system32文件夹下,叫TAPI3.DLL。
(刚开始时,我还想着要用VC写的,因为看到MSDN中好多C++的例子,但后来发现,哎,用C#真是太方便了。)
这个DLL中又有三大内容,分别是
1 Call and Media Controls
2 Call Center Controls
3 Rendezvous IP Telephony Conferencing
Call and Media Controls不好翻译,估且叫电话媒体控制吧,其实这里的call我这样的翻译有点不对,
因为这里的意义远已不是只在电话线上传输一个语音信号那样的传统电话了,而是包括语音的任何媒质。
这其实是一个体系的代名词,下面又有分支。
它包括了五个呼叫控制模型,分别是 TAPI, Address, Terminal, Call, 和 CallHub,这五个对象管理着旗下的接口,为我们提供了方便的服务。
TAPI对象描述本地可利用的所有资源。
Address对象描述一个呼叫的源地址或目标地址。
Terminal对象,其实就是一个麦克风或是话筒。
Call对象描述一个或多个Address对象之间的链接。
CallHub对象代表了一系列相关呼叫的集合。
执行一个呼叫和呼叫应答的大体过程。我给了一个简单的例子。
我们首先得在system32下找到tapi3.dll添加引用到我们的工程当中,对类型库的导出内部调用的是tlbimp.exe,你会发现默认会在文件名后加一个lib,嘿嘿。。。
using TAPI3Lib; //添加引用
执行一个呼叫
1. 创建和初始化一个TAPI对象
下面是创建COM类对象,在VC中,我们还要用CoGetClassObject得到类厂对象,或是直接利用CoCreateInstance或CoCreateInstanceEx 直接创建COM对象,而在托管代码中,直接使用new轻松实例化,C#中,COM类就表示为具有无参数构造函数的类。
TAPI3Lib.TAPIClass tapiClass = new TAPI3Lib.TAPIClass();
tapiClass.Initialize(); //初使化TAPI对象。
2. 用TAPI对象解析在一个计算机上的可用地址
IEnumAddress iea = tapiClass.EnumerateAddresses();
iea.Next(1,out iad,ref arg);
3. 解析每一个地址对象所支持的地址类型
通过枚举出的ITAddress的接口对象,iad.AddressName可得接口类型,iad.State可得它的状态。
4. 选择一个地址对象
我的计算机就支持好几个地址如,RAS PPPoE Line0000,H323 线路等等。
5. 用Address对象中的CreateCall方法创建一个Call对象
6. 选择Call对象的适当终端
7. 用Call对象的Connect方法执行一次呼叫
呼叫应答
1. 创建和初始化一个TAPI对象
2. 用TAPI对象解析在一个计算机上的可用地址
3. 解析每一个地址对象所支持的地址类型
4. 选择一个地址对象
5. 用一个Address对象登记呼叫
IEnumCall ec = itaddress.EnumerateCalls();
ec.Next(1,out callinfo,ref arg);
6. 通过ITBasicCallControl就可以对一个call对象连接,回答了。
ITBasicCallControl bc=(TAPI3Lib.ITBasicCallControl)ici;
bc.Answer();
注意:在接口转换时,我们不再调用QueryInterface()而是只用强制转换就可以了。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using TAPI3Lib;
namespace tapi
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private TAPI3Lib.TAPIClass tapiClass;
private System.Windows.Forms.ComboBox comboBox1;
private ITAddress[] address =new TAPI3Lib.ITAddress[10];
private TAPI3Lib.ITBasicCallControl ibc;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private int lines;
private System.Windows.Forms.CheckBox checkBox1;
private int currentLine;
private bool h323;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
InitialCom();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
public void InitialCom()
{
tapiClass = new TAPIClass();
tapiClass.Initialize();
IEnumAddress iea = tapiClass.EnumerateAddresses();
ITAddress iad;
uint arg=0;
lines=0;
//枚举支持线路
for(int i=0;i<10;i++)
{
iea.Next(1,out iad,ref arg);
address[i]=iad;
if(iad!=null)
{
comboBox1.Items.Add(address[i].AddressName);
lines++;
}
else
break;
}
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.Location = new System.Drawing.Point(112, 24);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(216, 20);
this.comboBox1.TabIndex = 0;
this.comboBox1.Text = "请选择一条线路";
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// label1
//
this.label1.Location = new System.Drawing.Point(32, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(48, 23);
this.label1.TabIndex = 1;
this.label1.Text = "线路:";
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(112, 64);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(216, 21);
this.textBox1.TabIndex = 2;
this.textBox1.Text = "";
//
// label2
//
this.label2.Location = new System.Drawing.Point(32, 64);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(72, 23);
this.label2.TabIndex = 3;
this.label2.Text = "电话号码:";
//
// button1
//
this.button1.Location = new System.Drawing.Point(376, 24);
this.button1.Name = "button1";
this.button1.TabIndex = 4;
this.button1.Text = "呼叫";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(376, 64);
this.button2.Name = "button2";
this.button2.TabIndex = 5;
this.button2.Text = "接听";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(376, 104);
this.button3.Name = "button3";
this.button3.TabIndex = 6;
this.button3.Text = "断开";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// checkBox1
//
this.checkBox1.Location = new System.Drawing.Point(112, 96);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(64, 24);
this.checkBox1.TabIndex = 7;
this.checkBox1.Text = "IP电话";
this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(480, 150);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.comboBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
TAPI3Lib.ITAddress ia=null;
ia=address[currentLine];
if(textBox1.Text.Length!=0)
{
try
{
if(!h323)
{
ibc = ia.CreateCall(textBox1.Text,TapiConstants.LINEADDRESSTYPE_PHONENUMBER|TapiConstants.LINEADDRESSTYPE_IPADDRESS,TapiConstants.TAPIMEDIATYPE_DATAMODEM|TapiConstants.TAPIMEDIATYPE_AUDIO);
ibc.SetQOS(TapiConstants.TAPIMEDIATYPE_DATAMODEM|TapiConstants.TAPIMEDIATYPE_AUDIO,QOS_SERVICE_LEVEL.QSL_BEST_EFFORT);
ibc.Connect(false);
}
else
{
ibc = ia.CreateCall(textBox1.Text,TapiConstants.LINEADDRESSTYPE_IPADDRESS,TapiConstants.TAPIMEDIATYPE_AUDIO);
ibc.Connect(false);
}
}
catch(Exception exp)
{
MessageBox.Show("呼叫失败!/n/n "+exp.ToString(),"错误");
}
}
else
MessageBox.Show("请输入要拨打的电话号码。。。");
}
private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
currentLine=comboBox1.SelectedIndex;
}
private void checkBox1_CheckedChanged(object sender, System.EventArgs e)
{
h323=checkBox1.Checked;
}
private void button2_Click(object sender, System.EventArgs e)
{
IEnumCall ec = address[currentLine].EnumerateCalls();
uint arg=0;
ITCallInfo ici;
try
{
ec.Next(1,out ici,ref arg);
ITBasicCallControl bc=(TAPI3Lib.ITBasicCallControl)ici;
bc.Answer();
}
catch(Exception exp)
{
MessageBox.Show("无呼叫可接听! /n/n"+exp.ToString(),"TAPI3");
}
}
private void button3_Click(object sender, System.EventArgs e)
{
IEnumCall ec = address[currentLine].EnumerateCalls();
uint arg = 0;
ITCallInfo ici;
try
{
ec.Next(1,out ici,ref arg);
ITBasicCallControl bc=(ITBasicCallControl)ici;
bc.Disconnect(DISCONNECT_CODE.DC_NORMAL);
ici.ReleaseUserUserInfo();
}
catch(Exception exp)
{
MessageBox.Show("No call to disconnect! /n"+exp.ToString(),"TAPI3");
}
}
}
}