美文网首页ios 知识点程序员iOS Developer
基于环信实现实时视频语音通话功能

基于环信实现实时视频语音通话功能

作者: 十字云 | 来源:发表于2017-02-24 20:52 被阅读4155次

该文章是建立在已经用环信SDK实现了聊天功能的基础之上,再去添加新的视频语音通话功能。基于环信实现在线聊天功能

实现前的准备工作

1.先在环信官网下载环信SDK 环信SDK下载 我使用的环信SDK版本为 V3.2.0 2016-10-15

2.除了实现聊天功能需要导入的库之外,还需导入libiconv.dylib库,这是环信实时语音包含的依赖库。

3.除了步骤2需要导入支持环信SDK所需要的库之外,还需导入libbz2.1.0.tbd库,因为视频聊天里面包含ffmpeg第三方,它需要这个依赖库。

4.在工程中添加包含视频语音通话功能的SDK HyphenateFullSDK,如果之前使用的是EaseUI所支持的HyphenateSDK,需要将这个简版的SDK删除干净(最好是在Finder中检查一下)否则会引起重复导入冲突。还需要注意一点的是,需要在Other Linker Flags 中添加-ObjC。具体做法 工程>>TARGETS>>Build Settings>>搜索other>>找到Other Linker Flags 添加-ObjC。

5.在环信的demo里找到Call文件夹,选择导入CallViewController ChatDemoHelper EMCallOptions+NSCoding 并导入plugin文件夹 ChatView包含视频语音通话的一些图标,也需要导入。由于环信的SDK做了国际化,所以还需添加Localizable.strings。

环信demo里找到这些 还有这些 里面包含call的一些图标都需要

关于图标我要提一下,由于我使用的是3.2.0,集成成功之后,我发现它给的界面有些简陋。关键的图标都没有,全都用一块块button代替,毫无美感。所以我检查了一下最新版的SDK,发现他们已经完善了这个缺陷,新加的图标挺好看的,我就扣下来放在这个工程里面用了。

实现原理

集成环信,需要导入EaseUIHyphenateFullSDKemotion。一个是UI界面,一个是环信SDK,最后一个是emotion表情包。

实现的第一步是要从聊天界面,点击“+”出现的MoreView开始。这个MoreView出现在EaseUI中,并且视频跟语音的图标一开始是隐藏的,位置也有所变动。

视频语音图标一开始是没有的

下面就是去找到代码所在地,并研究一波。

MoreView
EaseChatBarMoreView.m 中找到- (void)setupSubviewsForType:(EMChatToolbarType)type{}这个方法,在这个方法中我们就能发现,MoreView里面的几个按钮图标就是在这里创建的,如下图。 红线标注的地方一开始是150,而后修改为80
找到了UI创建的地方,这只是第一步。下面就要根据按钮绑定的方法,一步步往下深究。
首先根据_videoCallButton找到绑定的方法takeVideoCallAction,发现它通过代理实现的另一个方法moreViewVideoCallAction:,按住command键单击方法继续跟踪。我们发现在EaseUIEaseMessageViewController.m中,该方法实现了,并且发了一个通知,如下图。 视频通话相关方法
很明显,这就是视频通话的通知,并且我们通过相同的方法不难发现,语音通话的通知跟这个是一样的。我们找到关键字KNOTIFICATION_CALL在环信demo中搜一下,就知道哪个地方接收了通知。 语音、视频通话的通知关键字一样

很明显,ChatDemoHelper就是我们要关注的地方,然后直接到了这里。

接收语音、视频通话的通知
细心的你肯定发现了图上面我注释的那些,ChatDemoHelper.m里面有好多方法我是不需要的,所有我都注释了。现在我讲讲多余的代码是哪些?需要的又是哪些?

图上方我注释的代码分别是:

[[RedPacketUserConfig sharedConfig] beginObserveMessage];//红包相关

[[EMClient sharedClient] addDelegate:self delegateQueue:nil];//添加回调代理

[[EMClient sharedClient].groupManager addDelegate:self delegateQueue:nil];//群组模块代理

[[EMClient sharedClient].contactManager addDelegate:self delegateQueue:nil];//好友模块代理
   
[[EMClient sharedClient].roomManager addDelegate:self delegateQueue:nil];//聊天室模块代理
   
[[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];//聊天模块代理

好友,聊天,回调相关代理,我在自定义聊天功能中用到过,这里只是需要添加视频相关的代理,所以有关于这些的代理和下面所出现的方法我都注释了,只保留语音视频相关代码。注释的代码太多,不易贴出,只要注意把上面我指出的那几类注释就好,所有涉及call的代码都保留。

[[EMClient sharedClient].callManager addDelegate:self delegateQueue:nil];//实时通讯相关代理

还有ChatDemoHelper.hChatDemoHelper.m需要导入和注释的头文件。

ChatDemoHelper.h ChatDemoHelper.m
对照着看,有几个类不需要,有几个是重新导入的。在ChatDemoHelper.m中需要注意的是
- (void)makeCallWithUsername:(NSString *)aUsername
                        type:(EMCallType)aType{}//发起视频

- (void)callDidReceive:(EMCallSession *)aSession{}//接收视频

这两个方法中的mainVC是找不到的,所有我要找到当前视图控制器,并让它作为父视图,模态弹出CallViewController,如下图所示。

找到当前视图控制器
修改的差不多了,我们就在MainViewController.mviewDidLoad中初始化ChatDemoHelper贴上代码[ChatDemoHelper shareHelper];(在程序进入的第一个视图控制器中初始化)
然后运行代码,调试一波,发现功能是能实现了,但是UI界面有点丑,并且没有来电铃声(虽然铃声相关的代码有)。然后我找到CallViewController .m修改了一波UI,并且自己在网上down了一段苹果来电铃声,并加了上去,差不多满足了需求。需要注意的是,铃声的播放要放在CallViewController.mviewDidAppear:(BOOL)animated中。 呼叫界面 视频通话界面

细节优化

1.程序在后台,添加推送消息并铃声提醒。具体操作如下:
ChatDemoHelper.m中找到- (void)callDidReceive:(EMCallSession *)aSession{}这个方法,并在这个方法里设置本地推送。

// 接收到视频 在方法开始的地方设置本地推送相关代码,原有代码不变。
- (void)callDidReceive:(EMCallSession *)aSession
{
    // 程序在后台
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
      
        UILocalNotification *notify = [[UILocalNotification alloc]init];
        NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
        notify.fireDate = fireDate;
        
        //时区
        notify.timeZone = [NSTimeZone defaultTimeZone];
        //通知内容
        // 将环信ID通过本地数据库匹配,找到真实的名字
        SaveMingYiModel *mingYiModel = [HaoYouDao selectedFromPeopleTableWithMDsfz:aSession.remoteName];
        
        
        NSString *stype =nil;
        if (aSession.type == EMCallTypeVoice) {
            
            stype = @"实时语音";
        }
        else if (aSession.type == EMCallTypeVideo){
           
            stype = @"视频通话";
        }
        NSString *notifyStr = [NSString stringWithFormat:@"%@向您发起%@",mingYiModel.docName,stype];
        
        notify.alertBody = notifyStr;
        
        // 如果你想震动的提示播放音乐的话就在下面填入你的音乐文件
        NSString *path = [[NSBundle mainBundle] pathForResource:@"callRing" ofType:@"mp3"];
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &sound);
        AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, soundCompleteCallback, NULL);
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        AudioServicesPlaySystemSound(sound);
        
        // ios8后,需要添加这个注册,才能得到授权
        if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
            UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
            
            UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
                                                                                     categories:nil];
            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        }
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
             // 执行通知注册
            [[UIApplication sharedApplication] scheduleLocalNotification:notify];
        });
      
    }

//==========后台持续震动和播放铃声的方法============
void soundCompleteCallback(SystemSoundID sound,void * clientData) {
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);  //震动
    AudioServicesPlaySystemSound(sound);
}
//结束铃声
-(void)stopAlertSoundWithSoundID:(SystemSoundID)sound {
    AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);
}
//============end=================

然后在合适的地方结束震动和提醒铃声。比如在视频结束、接听、拒接、中断等方法中加上结束的代码。(代码中很容易找到相关方法)

//调用结束震动和提醒铃声的方法
 AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
   [self stopAlertSoundWithSoundID:sound];

代码实现的差不多了,效果图如下:

后台震动铃声提醒,并发送通知

**基于环信实现在线聊天功能 **

转载请注明出处

相关文章

网友评论

  • 君莫叹人生如若初见:博主你好,我想问一下iOS视频通话完成后,挂断后如何在消息体里面返回通话时长,android有此功能,好像iOS没有。
    请问你有思路没。
  • 小痕_e5bb:请问在使用环信及时语音、视频时,APP在后台或杀死后台后,别人给自己发送视频请求了,怎么处理?运行环信demo在后台都没反应,跪求指点~~~
    十字云:- (void)callDidReceive:(EMCallSession *)aSession{} 程序在后台时,通过这个协议方法,发送本地通知,调起视频通话。具体代码,在本文中 细节优化部分。在我的APP中,程序完全杀死,用户就处于离线状态,对方好友不能发起视频,所以就没做了。现在想想,这种情况可以通过推送完成,发送一个视频回话的通知。
  • 0792bc92b5c4:您好,请问一下,为什么视频后,消息记录里不展示 语音电话或者视频 类的消息呢?
    十字云:这个还真没有,只是实时调起通话,并没有将通话记录,时长加入消息列表。这个功能我没有深究,不知道是不是环信里面缺少的,抱歉。
  • 梁森的简书:用cocoapods集成过吗?
    十字云:@阳光黑 没有
  • 十字云:具体步骤我都写的很详细的了,去环信官网下SDK,自己配置下,这些操作都要别人手把手教你么?需要注意的地方我也标注了,不难。要demo?没有。
  • 3cd1959d4274:能否分享一下demo,谢谢
  • 叶星龙:环信的实时语音界面能自定义?
    十字云:能啊,关于UI的都能自定义。
  • 奔向大牛:你好,我想请问下你那边语音通话收到推送的时候,进入app语音接入会不会有延迟,我自己集成了也下载了环信的demo测试,延时都挺高的,大概在5秒左右,请问下有好的解决办法吗?求指教,谢啦
    十字云:@十字云 我这边用户处于真正离线状态不能建立视频通话,也就没有考虑视频远程推送。
    十字云:@奔向大牛 你说的是语音视频在离线状态下的推送么?是这样的,我实现的逻辑是这样的,只有在用户同时在线的情况下才能建立视频通话,在一方处于离线的状态下不能发起视频通话的。我做的推送是本地推送,也就是APP处于后台五分钟左右,还是在线的的情况下会有推送。这种情况下没有发现有多大的延迟。
    奔向大牛:app在离线的状态下,收到推送重新打开app的时候哈
  • 飞飞飞鱼哥:学习学习
  • 铮铮钱钱:能不能把demo贴出来,谢谢
    李某lkb:求demo

本文标题:基于环信实现实时视频语音通话功能

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