Linphone-iOS-移植

首次写博客,写这博客一是为了后期需移植LinphoneSDK时做个参考,大脑很多东西是会忘记的;二是因为在国内网站上找了好久都没找到如何将LinphoneSDK移植到自己项目里面的资料,只希望这篇博客对后面有人需要使用Linphone实现网络通话功能的同鞋有点帮助,做个借鉴。

对于编译Linphone,各种博客已经一大堆,这里推荐一篇:http://www.successmonkey.co.nz/blog/building-linphone-for-ios,有人翻译了这篇:http://blog.csdn.net/showhilllee/article/details/42966305,可惜LZ克隆的Linphone源码一直不全,最后一步的设置SDK版本无法进行,LZ直接使用了Linphone官网中的SDK,对上面博客中的命令,有些命令无法进行时,尝试着命令最前面加个sudo;官网中SDK的下载地址为:http://www.linphone.org/releases/ios/liblinphone-iphone-sdk-latest.zip

另外,LZ从CSDN网站中下载了一个别人编译好的demo(以下称为第三方demo),不过这demo编译的有点时间了的感觉,关于里面显示为Linphone Core 3.7.0,LZ记得最新的已经到3.8.5了,不过LZ使用Xcode6.3能够跑通,不会报错,需使用的账号需到Linphone官网申请,下载地址为:http://download.csdn.net/detail/showhilllee/8688073,需要2个积分,没积分同鞋可以找我要份,哈哈;有同鞋编译成功最新的也可以发一份给我,先谢过。

好了,接下来进行编写demo,LZ使用的是Xcode7.1,手机使用iPhone5S(iOS8.3系统)和iPhone6(iOS9.1系统)测试均能拨打接听电话。

一、新建工程,导入LiphoneSDK

这时进行编译会报错,这边列出LZ出现的问题及解决办法:

1、提示<libxml/tree.h> file not found

导入libxml2.tbd框架(Xcode7之前为libxml2.dylib),若还会出现此问题请参考博客:http://www.tuicool.com/articles/Nraau2

2、LinphoneSDK中出现例如"ortp/ortp.h" file not found

是因为路劲没有配对,LZ这边设置的路劲如下图:

二、新建PrefixHeader.pch文件,加入#import <linphone/linphonecore.h>

三、Build Settings -> Other Linker Flags 中增加 -ObjC

四、添加库和框架,列表如下:

    • libz.tbd
    • libiconv.tbd
    • libsqlite3.tbd
    • libc++.tbd
    • libstdc++.6.tbd
    • libresolv.tbd
    • AudioToolbox.framework
    • UIKit.framework
    • QuartzCore.framework
    • OpenGLES.framework
    • MessageUI.framework
    • MediaPlayer.framework
    • CoreGraphics.framework
    • MobileCoreServices.framework
    • AddressBookUI.framework
    • AddressBook.framework
    • SystemConfiguration.framework
    • CFNetwork.framework
    • AssetsLibrary.framework
    • AVFoundation.framework
    • CoreAudio.framework
    • CoreMedia.framework
    • CoreTelephony.framework
    • CoreVideo.framework
    • Foundation.framework
    • CoreLocation.framework
五、使用了第三方demo中的几个类文件,如下:

LinphoneManager.[h,m]

FastAddressBook.[h,m]

Utils.[h.m]

UILinphone.[h.m]

ColorSpaceUtilities.[h.m]

六、注册部分,Linphone需先和后台连接成功,才能进行网络通话,LZ这后台的客服系统是购买的第三方系统,只有IP和端口,使用第三方demo,用在官网中申请到的账号(两个账号,两台手机各登录一个账号),此时可以连接成功,并能进行通话;但当User name、Password、Domain修改为我们自己注册好的账户进行登录时则无法登录成功,此处LZ纠结了好久,经过打断点各种修改比对测试,最终成功连接,修改部分如下代码:

- (BOOL)addProxyConfig:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport {
    LinphoneCore* lc = [LinphoneManager getLc];
    LinphoneProxyConfig* proxyCfg = linphone_core_create_proxy_config(lc);
    NSString* server_address = domain;
    
    char normalizedUserName[256];
    linphone_proxy_config_normalize_number(proxyCfg, [username cStringUsingEncoding:[NSString defaultCStringEncoding]], normalizedUserName, sizeof(normalizedUserName));
    
    //    const char* identity = linphone_proxy_config_get_identity(proxyCfg);
    //    if( !identity || !*identity ) identity = "sip:user@example.com";
    
    // 修改部分 1
    const char *identity = [@"sip:User name@IP:端口" cStringUsingEncoding:NSUTF8StringEncoding];
    
    LinphoneAddress* linphoneAddress = linphone_address_new(identity);
    linphone_address_set_username(linphoneAddress, normalizedUserName);
    
    if( domain && [domain length] != 0) {
        if( transport != nil ){
            // 修改部分 2
            server_address = [NSString stringWithFormat:@"%@:%@;transport=%@", server_address, @"端口", [transport lowercaseString]];
        }
        // when the domain is specified (for external login), take it as the server address
        linphone_proxy_config_set_server_addr(proxyCfg, [server_address UTF8String]);
        linphone_address_set_domain(linphoneAddress, [domain UTF8String]);
    }
    
    char* extractedAddres = linphone_address_as_string_uri_only(linphoneAddress);
    
    LinphoneAddress* parsedAddress = linphone_address_new(extractedAddres);
    ms_free(extractedAddres); // 释放
    
    if( parsedAddress == NULL || !linphone_address_is_sip(parsedAddress) ){
        if( parsedAddress ) linphone_address_destroy(parsedAddress);
        UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil)
                                                            message:NSLocalizedString(@"Please enter a valid username", nil)
                                                           delegate:nil
                                                  cancelButtonTitle:NSLocalizedString(@"Continue",nil)
                                                  otherButtonTitles:nil,nil];
        [errorView show];
        return FALSE;
    }
    
    char *c_parsedAddress = linphone_address_as_string_uri_only(parsedAddress);
    
    linphone_proxy_config_set_identity(proxyCfg, c_parsedAddress);
    
    linphone_address_destroy(parsedAddress);
    ms_free(c_parsedAddress);
    
    LinphoneAuthInfo* info = linphone_auth_info_new([username UTF8String]
                                                    , NULL, [password UTF8String]
                                                    , NULL
                                                    , NULL
                                                    ,linphone_proxy_config_get_domain(proxyCfg));
    
    [self setDefaultSettings:proxyCfg];
    
    [self clearProxyConfig];
    
    linphone_proxy_config_enable_register(proxyCfg, true);
    linphone_core_add_auth_info(lc, info);
    linphone_core_add_proxy_config(lc, proxyCfg);
    linphone_core_set_default_proxy_config(lc, proxyCfg);
    return TRUE;
}
注:

1、因涉及安全问题,为提供IP和端口详细信息;

2、修改部分为上面代码中的1、2部分,需说明一点的是LZ传入的Domain只有IP,无端口,transport使用的为UDP(使用TCP、TLS都无法成功连接,LZ也不知为什么,若有大侠知道还望告知),LZ传入的参数在代码中写死,如下:

NSString *username  =@"User name";

   NSString *password  = @"Password";

   NSString *domain    = @"IP";

   NSString *transport = @"UDP";

3、此方法在第三方demo中的WizardViewController.m文件中可找到;


七、如何知道有没有登录成功?可监听名为 kLinphoneRegistrationUpdate 的通知,通过 linphone_proxy_config_get_state方法可获取到当前的状态。

八、通过监听名为 kLinphoneCallUpdate 的通知,可知道当前电话的状态,如下代码,可通过 astate 的状态进行各种事件处理:

- (void)callUpdateEvent:(NSNotification*)notif {

   LinphoneCall *acall = [[notif.userInfoobjectForKey: @"call"]pointerValue];

   LinphoneCallState astate = [[notif.userInfoobjectForKey: @"state"]intValue];

    [selfcallUpdate:acall state:astate];

}

九、其他

1、当来电时,不接通电话,会在二十几时自动挂断,在实际使用场合中此时间会较短,可通过如下方法进行设置(安卓中的方法为setIncomingTimeout):

    LinphoneCore *lc=[LinphoneManagergetLc];

  linphone_core_set_inc_timeout(lc,60);// 来电超时自动挂断时间设置

2、来电时无铃声,到后来才发现竟然是没有音频文件,着实让LZ OUT了一把,音频文件在第三方demo中有,为mag.wav文件,LZ将.wav和.caf文件都加入了工程中,高兴了一把,有声音了;

3、回声抑制,有方法进行设置,在查看linphonecore.h文件时有看到过,LZ暂未去研究;

4、因LZ暂时只需先实现通话功能,对于视频通话这块还未进行研究,有研究过的同鞋可分享你们的经验,若后期有进行视频通话这块的研究,到时再跟新此博客;

5、因LZ手中没有iOS7的设备,故在iOS7中未进行测试,iOS8、9均可实现通话功能。

备注:1、感谢上面所使用到的博客的博主,若有地址无法打开,则为国外网站,需翻墙,LZ以购买VPN,上面地址均能打开;

  2、若有在研究Linphone的同鞋,碰到问题可咨询LZ,LZ邮箱为rongfeng.fang@icloud.com,QQ群:345752242,若你发现博客中有问题存在,也烦请告知LZ,以便及时修改;


  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Linphone-iphone demo ios 是一个为 iOS 设备开发的开源软件,它提供了一个优秀的 IP 电话通讯网络服务,该服务可以实现 VoIP 通讯,即语音和视频通话以及音频和视频传输等。 Linphone-iphone demo ios 具有音频或视频呼叫、文本聊天、通讯录、语音信箱、呼叫转移、呼叫保持、呼叫等待等新颖有用的功能。Linphone-iphone demo ios 还支持 SIP 协议、SIP/TLS、SIP/UDP、IMAP、POP3、SMTP、SIP/RTP、SRTP 和 ZRTP 等主流的通信协议,几乎可以适应各类网络环境。 Linphone-iphone demo ios 是一个易于使用和实现的VoIP解决方案,在架构设计上,它可以和其他 VoIP 应用程序进行集成,可以与许多 SIP 服务器进行互操作性测试,并与一些常见 VoIP 应用程序比较常见性和稳定性。 Linphone-iphone demo ios 的整体性能也十分突出。它具有鲜明的 SIP 通信体验,提供了语音质量、通话时延与 VoIP 协议调和的解决方案,以保证声音质量清晰,通话时延低,并且网络环境不会影响通话质量。Linphone-iphone demo ios 的接口和界面设计都采用了最新的 UI 设计和开发技术,效果极佳,让用户使用起来非常友好。 总之,Linphone-iphone demo ios 是一款可以为 iOS 用户提供高质量 VoIP 通信服务的开源软件,丰富的功能、通用的协议以及高质量的音频/视频通话体验,使得它成为 VoIP 领域中一种非常有价值的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值