命令行调用器示例
命令行调用器示例
引言
我开始认真研究命令行调用是在我选择它作为博士论文的课题时。我在瑞典的一所计算机大学学习,我总是觉得与 VoIP 相关的课程最有趣。然后,命令行调用进入了我的视野。
在这篇短文中(我也得完成我的论文),我试图介绍一些关于这个主题的基本编程知识。我的目的是帮助那些与我分享这种兴趣的人(也许也从事论文工作)。与此同时,我不想让这篇文章变得过于专业,所以我也将尝试总结一些关于 VoIP 的一般知识。让我们从这里开始。
VoIP 是“基于互联网协议的语音”(Voice over Internet Protocol)的缩写。顾名思义,它打破了传统的电话系统(或“普通旧电话系统”——简称:POTS),并使用互联网连接代替电话。这可以从个人和商业方面带来许多优势。但这篇文章的目的不是要收集所有这些东西。让我们沿着技术路线前进。
要通过 VoIP 进行通信,您需要使用一项服务。市面上有很多 VoIP 服务提供商……您必须选择最适合您通信需求和期望的一个(或多个)。但这东西究竟是如何运作的呢?您的声音如何从一个系统传到另一个系统?
VoIP 技术的本质是使用 IP 网络,通过 ADSL 或其他互联网连接,拨打或接听来自/到 POTS 陆地电话网络的电话。这意味着,您甚至可以通过您的计算机与使用陆地电话号码的人通话。
在大多数情况下,VoIP 解决方案是免费的(主要是在两台计算机之间,但也经常在计算机和陆地电话或移动电话之间)。但即使不是(取决于服务提供商),它仍然比传统方式便宜。研究表明,与使用 POTS 线路相比,使用 VoIP 可能会让您在本地通话中节省高达 40% 的费用,在国际通话中节省高达 90% 的费用。
开发您自己的 VoIP 应用程序的最简单方法是使用为此目的制作的 SDK。我经过了漫长的搜索才找到了我的 SDK,但如果您想要正确的东西,您需要这样做。您自己进行研究以找到最符合您要求的解决方案。我需要一个 SDK 来仔细研究命令行调用者的源代码。
所描述的 SDK 的命令行调用者是一个用 C# 编写的示例程序。电话可以直接从该程序中拨打,无需任何丰富的界面。通话是通过命令行提示符进行的,您需要在其中提供 .exe 文件的参数。EXE 文件的参数是要拨打的电话号码。此命令行调用者不使用本地麦克风通过 RTP 数据包发送音频数据。该程序使用一个 mp3 文件并为被叫方播放此文件。这就是我一直在寻找的。
现在,我们终于来到了最重要的部分:编码。我想通过一个编码示例来展示命令行调用的伟大之处。此代码展示了如何将 MP3 播放连接到您的电话呼叫。
初始化默认值
1. static void Main(string[] args)
2. {
3. displayName = "CommandLineCaller";
4. domainServerPort = 5060;
5. registerPassword = string.Empty;
6. registrationRequired = false;
7. localAddress = SoftPhoneFactory.GetLocalIP().ToString();
8. mp3FilePath = "..\\..\\Resources\\test.mp3";
9.
10. . . .
11.
解析命令行参数
1. if(!ParseArgs(args))
2. {
3. PrintHelp();
4. Console.ReadLine();
5. return;
6. }
(如果参数有效,ParseArgs()
方法返回 true
,如果参数缺失或配置错误,则返回 false
。)
打开 .mp3 文件。
1. {
2. mp3StreamPlayback = new MP3StreamPlayback(mp3FilePath);
3. }
4. catch (Exception ex)
5. {
6. Console.WriteLine(ex.Message);
7. Console.ReadLine();
8. return;
9. }
因此,创建了 phoneCallMediaSender
和 MediaConnector
类的新实例,并且 mp3StreamPlayback
通过 Connect()
方法连接到 phoneCallMediaSender
。看起来像这样
1. phoneCallMediaSender = new PhoneCallMediaSender();
2. mediaConnector = new MediaConnector();
3. mediaConnector.Connect(mp3StreamPlayback, phoneCallMediaSender);
基于预定义的值和命令行参数创建 softPhone
和 phoneLine
1. softPhone = SoftPhoneFactory.CreateSoftPhone(localAddress, 5000, 5100, 5060);
2. phoneLine = softPhone.CreatePhoneLine
(new SIPAccount(registrationRequired, displayName, userName, registerName,
3. registerPassword, domainServerHost, domainServerPort));
(这些行创建了一个新事件处理程序,用于当电话线路状态更改时的事件。此事件处理程序是 phoneLine_PhoneLineStateChanged
。)
正在注册电话线路
1. phoneLine.PhoneLineStateChanged += phoneLine_PhoneLineStateChanged;
2. softPhone.RegisterPhoneLine(phoneLine);
如果不需要注册或电话线路已成功注册,则调用 CreateCall()
方法
1. static void phoneLine_PhoneLineStateChanged(object sender, VoIPEventArgs e)
2. {
3. Console.WriteLine("Phone line state has changed to {0}.", e.Item);
4. if (e.Item == PhoneLineState.NoRegNeeded ||
e.Item == PhoneLineState.RegistrationSucceded)
5. CreateCall();
6. }
最后,拨打电话
1. static void CreateCall()
2. {
3. if (phoneCall != null)
4. return;
5. Console.WriteLine("Creating new call ...");
6. phoneCall = softPhone.CreateCallObject(phoneLine, dialNumber);
7. phoneCall.CallErrorOccured += phoneCall_CallErrorOccured;
8. phoneCall.CallStateChanged += phoneCall_CallStateChanged;
9. phoneCallMediaSender.AttachToCall(phoneCall);
10. phoneCall.Start();
11. }
如果 callstate
为 InCall
,则通过调用 mp3StreamPlayback.StartStreaming()
方法为被叫方播放 MP3 文件。
1. static void phoneCall_CallStateChanged(object sender, VoIPEventArgs e)
2. {
3. Console.WriteLine("Call state has changed to {0}", e.Item);
4. if (e.Item == CallState.InCall)
5. mp3StreamPlayback.StartStreaming();
6. }
看到了吗?对于熟悉编程的人来说,这并不复杂。我希望您觉得我的文章很有趣,并且希望越来越多的人会沉浸在 VoIP 技术的魅力中。
如果您想了解更多信息,我建议您查看这个网站,我用它作为本文的来源