linphone-iphone的安装与调试

linphone是一款老牌的全平台的多人语音视频通话业务的软件(始自2001年),不仅支持视频和语音通话,还支持即时消息(可惜只支持文本和图片)。
当然,重要的是:linphone是开源的,毕竟linphone的sip服务和媒体数据处理也大量使用开源框架;更重要的是,linphone官网提供免费的sip服务,这也意味着你不需要自己手动搭建sip服务即可享受voip业务,这对于有voip需求的前端来说无疑是最佳的选择。但是虽然开源,linphone的工程比较庞大,依赖项较多,编译的过程中容易出现问题,那么下面,我将介绍自己linphone-iphone的安装历程。

linphone-iphone的下载

首先进入官网,可以看到linphone的多个产品线,最感兴趣的肯定是liblinphon了,但是这是个坑,一方面,开发文档几乎没有,根本无从下手;另一方面,编译的过程相当痛苦,成功率不高,就算编译出来了也没有成就感可言,不仅需要花费大量的时间写Demo做测试,你还要考虑如何搭建SIP服务器。
如果想体验并快速学习相关的接口,我建议去linphone这一栏,在downloads目录下,你可以看到所有平台的产品都是可以下载源码的,这里选择iphone版。你有两种选择,要么选择官网的git://git.linphone.org/linphone-iphone.git,要么选择github上的git://git.linphone.org/linphone-iphone.git,其实效果差不多,但是记住不要手动下载,而是使用git命令clone到本地,因为模块中的很多依赖库代码都没有放在项目中,需要通过git链接下载。

linphone官网
linphone官网

打开终端,有iTerm2更好,cd到项目放置的目录,输入git clone git://git.linphone.org/linphone-iphone.git命令开始下载,你会发现一切顺利,很快便下载完成,你很高兴的cd进linphone-iphone,输入"./prepare.py",以为脚本会为你解决剩下的一切,然而出现了下面的提示:
补齐依赖项
补齐依赖项

这时打开submodules文件夹就会发现里面的模块全部是空的,看工程所依赖的模块都没下载过来,只是下载了前端的这个空壳。那就照着它说的做好了,输入命令git submodule update --init --recursive,嗯,下载进度又开始了,刚开始也许一切正常,但是过一段时间会发现大多卡在了libxml2这个xml解析模块的下载上了,我用了比较笨的方法:请再来一次...,之前下载失败的部分只需要再输入一次git submodule update --init --recursive就可以继续下载,可惜不支持断点续传,模块需要重头下载,TOT。
但是有更好的解决办法,实际上github是有libxml2分支的,想办法把git中的链接替换掉就行,下面我们通过git命令来修改git配置中的链接来实现下载:
首先在工程目录下,终端中输入git config -l,看到如下信息:
要修改的git仓库地址
要修改的git仓库地址

可以看到libxml2用的源是git://git.gnome.org/libxml2,我们需要换一个能下的,运行git config -e就可以用vim编辑git配置文件了,替换后的样子如下所示:
修改后的效果
修改后的效果

修改后保存,运行git submodule update --init --recursive就可以继续下载了,最终所有源码下载成功,可以开心的编译了,是的,托脚本的福,编译无压力。

linphone-iphone的编译

下面的工作进行的比较顺利,无非照着readme一步一步来,缺哪个就去装哪个。

  1. 首先,为了支撑脚本顺利运行,我们需要安装[HomeBrew]((http://brew.sh),有了它编译缺少依赖的日子一去不复返了。
  2. ./prepare.py
    这个时候可以运行该命令来安装linphone-iphone的依赖项了,提示我们需要使用brew安装coreutils automake autoconf libtool intltool wget pkgconfig cmake yasm nasm doxygen ImageMagick optipng libantlr3c gettext,这时homebrew派上了用场,运行命令brew install coreutils automake autoconf libtool intltool wget pkgconfig cmake yasm nasm doxygen ImageMagick optipng libantlr3c gettext就可以自动安装完成,不需要手动配置环境。
  3. 再次运行``./prepare.py`,嗯,提示我们要安装java JDK,那就去装一下好了。这个更简单,直接去网上下载java SE开发套装的软件安装就可以了。
  4. 终于可以开始./prepare.py了,脚本做的比较智能,只要前面步骤都完成了,这一步成功率较高。
  5. 完成这些准备工作后,可以开始重头戏,编译了,运行./prepare.py -c && ./prepare.py && make,大概20分钟左右就可以编译好。可以看到子目录下多出了一个liblinphone-sdk文件夹,里面是编译好的liblinphone在各个平台下的静态库。
  6. 打开linphone.xcodepro,工程文件夹中自带了企业推送证书,可以实现推送,连接真机后,按⌘R就可以享受了。

linphone_iphone的调试

是的,其实到这里基本就结束了。但是我们费这么大功夫不是为了装个Voip玩一玩了事的,而是借鉴里面对接口的调用方式。这里主要了解通话业务相关的代码。

工程目录结构

可能是工程维护时间较长的原因,但说实话,现在还在用xib实在是...不过好处是UI结构简单一看就懂。
与工程相关的类全部放在Classes中,子目录有各页面的ViewController以及liblinphone的中间件,而LinphoneUI中存放自定义的各种控件,Utils中存放用到的工具类和第三方视图类,都不是什么著名的,引起注意的一个是XMLRPC,远程过程调用的一个ios框架;另一个TPMultiLayoutViewController比较重要,工程中几乎所有的UIViewController都继承自它,嗯,似乎它的目的是早年(5年前)用来解决一种布局方式的UIViewController可以同时适用横向和竖向的问题,也是够老了。

跟通话相关的类型主要有:

  1. CallIncomingView:电话打入的视图;
  2. CallOutgoingView:电话打出的视图;
  3. CallView:电话接通后的视图、包括语音聊天、视频聊天、会议电话的视图;
  4. PhoneMainView: 电话视图的容器,单例模式;监听大部分的通话状态变化,负责管理不同通话视图间的跳转和主要业务逻辑;
  5. LinphoneManager:对liblinphone中各种状态的封装以及功能的补充(音频播放、音频设备设置,音频设备占用处理,低电量,新消息处理,前后台处理),中间件。

运行与调试

  1. 注册与使用
    我们来运行一下这个demo(完成度很高,已上架),终于看到了Xcode的"Build success",程序进入后长这个样子:
    Demo效果图
    Demo效果图

    选择CREAT ACCOUNT进行帐号的注册,注册完成即可享受免费的sip服务,进入注册页面后,建议用户名最好填写电话号码或者纯数字帐号,因为sip地址是根据用户名来定义的,例如用户名为username的用户的sip地址为username@sip.linphone.org,而拨号盘只能输入数字...这意味着如果你想直接通过拨号盘或者手机联系人来拨打sip电话(这些sip帐号都是跟电话号码绑定的),就必须是纯数字帐号。虽然也可以通过添加联系人的方式来添加带字母的sip帐号,但这并不方便。注册后在邮箱收到邮件并点击链接验证后帐号注册完成,可以向另一台注册了帐号的设备发送voip通话了。
  2. 代码分析
  • UI
    与通话相关的页面一共有3个:CallIncomingViewCallOutgoingViewCallView,分别为打入电话、呼出电话与通话期间的视图。没有特别难懂的地方,用通知来进行UI更新。
    而"PhoneMainView"则比较特殊,该单例不仅起到业务层的作用,而且是上面3个页面的容器,通过它来进行通话页面之间的切换和管理。
  • 业务,位于linphoneManager
    • 基本业务:

      1. 拨号
      • 判断网络状况
      • 检查是否在GSM通话中
      • 检测提供的addr是否合法
      • 2g网络下是否使用low_bandwidth模式
      • linphone_core_invite_address_with_params
      1. 接听
      • 2g网络是否是同low_bandwidth模式
      • linphone_call_params_enable_video 是否允许视频流
      • linphone_core_accept_call_with_params 接电话
    • 状态监听:
      voip通话状态改变的监听是通过通知kLinphoneCallUpdate下发的,注册该通知后,就可以从userInfo中的keycallstate中分别拿到当前通话的实例以及通话状态码。
      那么,该通知又是怎么来的呢,看了voipManager.m便知,在linphonecore.h文件中有一个void (*LinphoneCoreCallStateChangedCb)(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message)类型的blockcall_state_changed,该回调会在通话状态改变时触发,所以将方法static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state, const char *message)赋值给了该blcok,在该方法中会对各种state进行处理,最后将state、call、message封装到dict后发送通知。

    • 音频设备相关
      需要处理两个问题:

      1. 音频设备占用,这里又分为GSM电话和普通音频应用的占用;
      2. 音频设备监测,主要针对蓝牙设备的接入。
    • 前台与后台
      为了保证应用进入后台也能长时间通话,做了如下处理:

      1. 触发applicationDidEnterBackground时:enterBackgroundMode
      • refreshRegisters
      • 设置超时处理[[UIApplication sharedApplication] setKeepAliveTimeout: 600 handler:^{ linphone_core_iterate }
      • 有通话则延长后台存活时间startCallPausedLongRunningTask
      • [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler
      • 停止视频预览 linphone_core_stop_dtmf_stream
      • 如果不进入后台模式,destroy voip socket if any
      1. 触发applicationDidBecomeActive时:调用becomeActive
      • refreshRegisters
      • 停止后台任务pausedCallBgTaskincallBgTask
      • linphone_core_start_dtmf_stream

其他部分就不一一列举了,说的不够清楚,建议如果感兴趣的话自己实际编译调试一遍,从而对linphone的ios端接口有更深的了解。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容