美文网首页iOS即時通訊開發PJSIP
快速移植Linphone到自己的项目

快速移植Linphone到自己的项目

作者: WillyGeek | 来源:发表于2017-04-18 15:50 被阅读1070次
    Linphone

    首先我们来看Linphone的简单介绍:

    Linphone for smartphones, tablets and mobile devices.
    Make audio and video calls in HD.
    Create audio conferences.
    Record and store calls.
    View real-time presence status.
    Manage your address book.
    Communicate securely.

    而我们如何快速将最新版本Linphone SDK移植到我们的个人项目呢?我将其分为三个步骤:

    一 . 首先我们需要自己编译一份最新的Linphone SDK

    在此非常感谢作者"whiteking"为我们整理的编译流程,大致分为一下几个步骤,最新版本的Linphone SDK也可以按照下面的步骤进行:

    1.安装 HomeBrew
    2.下载linphone-iphone项目:
    3.配置环境路径
    4.Build SDK
    

    相关命令在编译流程中提到, 在此不过多赘述. 需要提醒一点的就是, 下载过程异常得慢, 本人足足花了一个晚上才下载成功的, 可以睡觉前下载一份, 睡醒应该就能编译了git submodule sync && git submodule update --init --recursive ←这个是submodule即子模块下载, 执行这个命令比较久,睡一觉应该就能下好了.
    编译成功后, 我们需要的SDK就在下面的这个文件里面:

    linphone_sdk

    而我们只需要apple-darwin这个文件就可以了.

    二. 熟悉Linphone Demo项目, 熟悉SDK的接口调用

    可以打开我们刚才编译好的demo, 然后看一下Linphone的架构, 关于架构分析的有作者"杭研融合通信iOS"分享的文章linphone-iphone的安装与调试. 里面也有安装和编译的教程, 可以借鉴一下.
    熟悉Linphone Demo项目, 需要花点时间去熟悉, 所有接口都是用C语言进行封装的, 因此我们需要熟悉如何调用C语言, C语言没有内存管理的概念, 因此我们创建一个对象的同时, 记得用完要把它销毁掉.
    Linphone Demo使用的控制器跳转用的是古老的跳转方式, 还有xib用的是古老的Autoresizing, 有兴趣的童鞋可以去了解一下, 不过这些古老的方式在今天的开发已经被废弃, 从侧面可以看出Linphone这个开源库的历史悠久.
    Linphone Demo核心业务层在于LinphoneManager, 所有核心的操作都在这里面, 因此我们关心的重点在这个文件里面.
    对于呼出或者呼入, 都需要进行以下的步骤:

    1. 初始化
    2.用户的注册
    3.呼入, 呼出
    

    熟悉相关流程之后, 接下来我们就可以进行Linphone的移植了.

    三. Linphone最新版SDK的移植

    首先感谢作者"江湖度"的贡献, 为我们贡献了这篇Linphone-iOS-移植 移植教程. 这里本人在移植的过程与作者"江湖度"移植的前四步基本相同, 在第五步开始有些差异, 本人在第五步用到了Linphone Demo里的几个类文件:

    用到的类文件

    如下:

    ColorSpaceUtilities//颜色相关工具
    Contact//联系人
    FastAddressBook//通讯录
    FileTransferDelegate//文件传输
    LinphoneManager//核心业务管理
    Log//Log
    ProviderDelegate//适配iOS 10 Callkit
    UILabel+Boldify//UILabel粗体
    Utils//工具类
    

    当然上面的文件不可能一下子全部挪过来, 因为绑定了很多Linphone Demo本身很多的东西, 所以需要自己剔除掉没用的东西, 一个一个文件地挪过来, 可以从Log开始, 然后Utils, 然后Contact.... 这部分工作量其实还是蛮大的, 也是需要耐心的工作.

    对了, 记得还要把两个配置文件拖入到我们的工程里面, 里面可以直接通过设置0,1修改配置, 还有一些声音文件也拖入到我们自己的工程里面:

    配置文件

    工程里面打开Voip的开关:

    打开Voip

    既然用到Voip, 我们还需要配置一个Voip的推送证书. 具体百度一下Voip证书配置.

    万事俱备, 接下来我们就可以调用LinphoneManager还有SDK里面的一些方法了.
    初始化:

     [[LinphoneManager instance] startLinphoneCore];
    

    注册:

    - (void)registeByUserName:(NSString *)userName pwd:(NSString *)pwd domain:(NSString *)domain tramsport:(NSString *)transport{
        
        //设置超时
        linphone_core_set_inc_timeout(LC, 60);
        
        //创建配置表
        LinphoneProxyConfig *proxyCfg = linphone_core_create_proxy_config(LC);
       
        //初始化电话号码
        linphone_proxy_config_normalize_phone_number(proxyCfg,userName.UTF8String);
        
        //创建地址
        NSString *address = [NSString stringWithFormat:@"sip:%@@%@",userName,domain];//如:sip:123456@sip.com
        LinphoneAddress *identify = linphone_address_new(address.UTF8String);
       
        linphone_proxy_config_set_identity_address(proxyCfg, identify);
        
        linphone_proxy_config_set_route(
                                        proxyCfg,
                                        [NSString stringWithFormat:@"%s;transport=%s", domain.UTF8String, transport.lowercaseString.UTF8String]
                                        .UTF8String);
        linphone_proxy_config_set_server_addr(
                                              proxyCfg,
                                              [NSString stringWithFormat:@"%s;transport=%s", domain.UTF8String, transport.lowercaseString.UTF8String]
                                              .UTF8String);
        
        linphone_proxy_config_enable_register(proxyCfg, TRUE);
        
        
        //创建证书
        LinphoneAuthInfo *info = linphone_auth_info_new(userName.UTF8String, nil, pwd.UTF8String, nil, nil, linphone_address_get_domain(identify));
        
        //添加证书
        linphone_core_add_auth_info(LC, info);
        
        //销毁地址
        linphone_address_unref(identify);
        
        //注册
        linphone_proxy_config_enable_register(proxyCfg, 1);
            
        //添加到配置表,添加到linphone_core
        linphone_core_add_proxy_config(LC, proxyCfg);
        
        //设置成默认配置表
        linphone_core_set_default_proxy_config(LC, proxyCfg);
        
        
        //设置音频编码格式
      [self synchronizeCodecs:linphone_core_get_audio_codecs(LC)];
    
        
    }
    #pragma mark - 设置音频编码格式
    - (void)synchronizeCodecs:(const MSList *)codecs {
        PayloadType *pt;
        const MSList *elem;
        
        for (elem = codecs; elem != NULL; elem = elem->next) {
            
            pt = (PayloadType *)elem->data;
            
            NSString *sreung = [NSString stringWithFormat:@"%s", pt->mime_type];
            if ([sreung isEqualToString:@"G729"]) {
                
                linphone_core_enable_payload_type(LC, pt, 1);
                
            }else {
                
                linphone_core_enable_payload_type(LC, pt, 0);
            }
            
        }
    }
    

    获取注册的状态:

    - (IBAction)getRegistState:(id)sender {
        
        LinphoneProxyConfig *cfg =  linphone_core_get_default_proxy_config(LC);
        LinphoneRegistrationState state =  linphone_proxy_config_get_state(cfg);
        switch (state) {
            case LinphoneRegistrationNone:{
                
                self.msgLabel.text = @"LinphoneRegistrationNone";
            }
                break;
            case LinphoneRegistrationOk:{
                
                self.msgLabel.text = @"LinphoneRegistrationOk";
            }
                break;
            case LinphoneRegistrationFailed:{
                
                self.msgLabel.text = @"LinphoneRegistrationFailed";
            }
                break;
            case LinphoneRegistrationCleared:{
                
                self.msgLabel.text = @"LinphoneRegistrationCleared";
            }
                break;
            case LinphoneRegistrationProgress:{
                
                self.msgLabel.text = @"LinphoneRegistrationProgress";
            }
            default:
                break;
        }
    
    }
    

    拨打电话:

    #pragma mark - 拨打电话
    - (void)callPhoneWithPhoneNumber:(NSString *)phone{
    
        LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:phone];
        
        [LinphoneManager.instance call:addr];
        if (addr) {
            linphone_address_unref(addr);
        }
      
    }
    

    接听电话:

        LinphoneCall *call = linphone_core_get_current_call(LC);
        if (call) {
             [[LinphoneManager instance] acceptCall:call evenWithVideo:NO];
        }
    
    

    挂断电话

        LinphoneCall *call = linphone_core_get_current_call(LC);
        if (call) {
            linphone_call_terminate(call);
        }
    

    清除配置表

    #pragma mark - 清除配置表, 切换账号时会用到
    - (void)clearProxyConfig {
        
        linphone_core_clear_proxy_config([LinphoneManager getLc]);
        linphone_core_clear_all_auth_info([LinphoneManager getLc]);
    }
    

    前前后后捣鼓Linphone也有一段时间, 苦于Linphone官网没有标准的文档, 也没有最新的SDK说明, 只能网上大量查阅资料, 还有研究Linphone Demo, 才最终调通. 因此, 本人建了个QQ群, 群号: 578410849. 如有什么问题, 欢迎加群咨询.

    相关文章

      网友评论

        本文标题:快速移植Linphone到自己的项目

        本文链接:https://www.haomeiwen.com/subject/icifzttx.html