該文章是建立在已經(jīng)用環(huán)信SDK實(shí)現(xiàn)了聊天功能的基礎(chǔ)之上,再去添加新的視頻語(yǔ)音通話功能科吭。基于環(huán)信實(shí)現(xiàn)在線聊天功能
實(shí)現(xiàn)前的準(zhǔn)備工作
1.先在環(huán)信官網(wǎng)下載環(huán)信SDK 環(huán)信SDK下載 我使用的環(huán)信SDK版本為 V3.2.0 2016-10-15
。
2.除了實(shí)現(xiàn)聊天功能需要導(dǎo)入的庫(kù)之外蜒灰,還需導(dǎo)入libiconv.dylib
庫(kù)圾亏,這是環(huán)信實(shí)時(shí)語(yǔ)音包含的依賴庫(kù)。
3.除了步驟2需要導(dǎo)入支持環(huán)信SDK所需要的庫(kù)之外祭饭,還需導(dǎo)入libbz2.1.0.tbd
庫(kù)瓮床,因?yàn)橐曨l聊天里面包含ffmpeg
第三方盹舞,它需要這個(gè)依賴庫(kù)。
4.在工程中添加包含視頻語(yǔ)音通話功能的SDK HyphenateFullSDK
隘庄,如果之前使用的是EaseUI
所支持的HyphenateSDK
踢步,需要將這個(gè)簡(jiǎn)版的SDK刪除干凈(最好是在Finder中檢查一下)否則會(huì)引起重復(fù)導(dǎo)入沖突。還需要注意一點(diǎn)的是丑掺,需要在Other Linker Flags 中添加-ObjC获印。具體做法 工程>>TARGETS>>Build Settings>>搜索other>>找到Other Linker Flags 添加-ObjC。
5.在環(huán)信的demo里找到Call文件夾,選擇導(dǎo)入CallViewController ChatDemoHelper EMCallOptions+NSCoding 并導(dǎo)入plugin文件夾 ChatView包含視頻語(yǔ)音通話的一些圖標(biāo),也需要導(dǎo)入街州。由于環(huán)信的SDK做了國(guó)際化,所以還需添加Localizable.strings兼丰。
關(guān)于圖標(biāo)我要提一下,由于我使用的是3.2.0唆缴,集成成功之后鳍征,我發(fā)現(xiàn)它給的界面有些簡(jiǎn)陋。關(guān)鍵的圖標(biāo)都沒(méi)有面徽,全都用一塊塊button代替艳丛,毫無(wú)美感。所以我檢查了一下最新版的SDK斗忌,發(fā)現(xiàn)他們已經(jīng)完善了這個(gè)缺陷质礼,新加的圖標(biāo)挺好看的旺聚,我就扣下來(lái)放在這個(gè)工程里面用了织阳。
實(shí)現(xiàn)原理
集成環(huán)信,需要導(dǎo)入EaseUI
砰粹、HyphenateFullSDK
唧躲、emotion
。一個(gè)是UI界面碱璃,一個(gè)是環(huán)信SDK弄痹,最后一個(gè)是emotion表情包。
實(shí)現(xiàn)的第一步是要從聊天界面嵌器,點(diǎn)擊“+”出現(xiàn)的MoreView開(kāi)始肛真。這個(gè)MoreView出現(xiàn)在EaseUI中,并且視頻跟語(yǔ)音的圖標(biāo)一開(kāi)始是隱藏的爽航,位置也有所變動(dòng)蚓让。
下面就是去找到代碼所在地乾忱,并研究一波。
在
EaseChatBarMoreView.m
中找到- (void)setupSubviewsForType:(EMChatToolbarType)type{}
這個(gè)方法历极,在這個(gè)方法中我們就能發(fā)現(xiàn)窄瘟,MoreView里面的幾個(gè)按鈕圖標(biāo)就是在這里創(chuàng)建的,如下圖趟卸。
找到了UI創(chuàng)建的地方,這只是第一步锄列。下面就要根據(jù)按鈕綁定的方法图云,一步步往下深究。
首先根據(jù)
_videoCallButton
找到綁定的方法takeVideoCallAction
右蕊,發(fā)現(xiàn)它通過(guò)代理實(shí)現(xiàn)的另一個(gè)方法moreViewVideoCallAction:
,按住command鍵單擊方法繼續(xù)跟蹤琼稻。我們發(fā)現(xiàn)在EaseUI
的EaseMessageViewController.m
中,該方法實(shí)現(xiàn)了饶囚,并且發(fā)了一個(gè)通知帕翻,如下圖。
很明顯萝风,這就是視頻通話的通知嘀掸,并且我們通過(guò)相同的方法不難發(fā)現(xiàn),語(yǔ)音通話的通知跟這個(gè)是一樣的规惰。我們找到關(guān)鍵字
KNOTIFICATION_CALL
在環(huán)信demo中搜一下睬塌,就知道哪個(gè)地方接收了通知。
很明顯揩晴,ChatDemoHelper就是我們要關(guān)注的地方,然后直接到了這里贪磺。
細(xì)心的你肯定發(fā)現(xiàn)了圖上面我注釋的那些,
ChatDemoHelper.m
里面有好多方法我是不需要的寒锚,所有我都注釋了〗儆常現(xiàn)在我講講多余的代碼是哪些?需要的又是哪些刹前?
圖上方我注釋的代碼分別是:
[[RedPacketUserConfig sharedConfig] beginObserveMessage];//紅包相關(guān)
[[EMClient sharedClient] addDelegate:self delegateQueue:nil];//添加回調(diào)代理
[[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];//聊天模塊代理
好友泳赋,聊天,回調(diào)相關(guān)代理喇喉,我在自定義聊天功能中用到過(guò)祖今,這里只是需要添加視頻相關(guān)的代理,所以有關(guān)于這些的代理和下面所出現(xiàn)的方法我都注釋了,只保留語(yǔ)音視頻相關(guān)代碼千诬。注釋的代碼太多撒踪,不易貼出,只要注意把上面我指出的那幾類注釋就好大渤,所有涉及call的代碼都保留制妄。
[[EMClient sharedClient].callManager addDelegate:self delegateQueue:nil];//實(shí)時(shí)通訊相關(guān)代理
還有ChatDemoHelper.h
、ChatDemoHelper.m
需要導(dǎo)入和注釋的頭文件泵三。
對(duì)照著看耕捞,有幾個(gè)類不需要,有幾個(gè)是重新導(dǎo)入的烫幕。在
ChatDemoHelper.m
中需要注意的是
- (void)makeCallWithUsername:(NSString *)aUsername
type:(EMCallType)aType{}//發(fā)起視頻
- (void)callDidReceive:(EMCallSession *)aSession{}//接收視頻
這兩個(gè)方法中的mainVC是找不到的俺抽,所有我要找到當(dāng)前視圖控制器,并讓它作為父視圖较曼,模態(tài)彈出CallViewController
磷斧,如下圖所示。
修改的差不多了捷犹,我們就在
MainViewController.m
的 viewDidLoad
中初始化ChatDemoHelper
貼上代碼[ChatDemoHelper shareHelper];
(在程序進(jìn)入的第一個(gè)視圖控制器中初始化)然后運(yùn)行代碼弛饭,調(diào)試一波,發(fā)現(xiàn)功能是能實(shí)現(xiàn)了萍歉,但是UI界面有點(diǎn)丑侣颂,并且沒(méi)有來(lái)電鈴聲(雖然鈴聲相關(guān)的代碼有)。然后我找到
CallViewController .m
修改了一波UI枪孩,并且自己在網(wǎng)上down了一段蘋果來(lái)電鈴聲憔晒,并加了上去,差不多滿足了需求蔑舞。需要注意的是拒担,鈴聲的播放要放在CallViewController.m
的viewDidAppear:(BOOL)animated
中。
細(xì)節(jié)優(yōu)化
1.程序在后臺(tái)攻询,添加推送消息并鈴聲提醒从撼。具體操作如下:
在ChatDemoHelper.m
中找到- (void)callDidReceive:(EMCallSession *)aSession{}
這個(gè)方法,并在這個(gè)方法里設(shè)置本地推送蜕窿。
// 接收到視頻 在方法開(kāi)始的地方設(shè)置本地推送相關(guān)代碼谋逻,原有代碼不變呆馁。
- (void)callDidReceive:(EMCallSession *)aSession
{
// 程序在后臺(tái)
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
UILocalNotification *notify = [[UILocalNotification alloc]init];
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
notify.fireDate = fireDate;
//時(shí)區(qū)
notify.timeZone = [NSTimeZone defaultTimeZone];
//通知內(nèi)容
// 將環(huán)信ID通過(guò)本地?cái)?shù)據(jù)庫(kù)匹配桐经,找到真實(shí)的名字
SaveMingYiModel *mingYiModel = [HaoYouDao selectedFromPeopleTableWithMDsfz:aSession.remoteName];
NSString *stype =nil;
if (aSession.type == EMCallTypeVoice) {
stype = @"實(shí)時(shí)語(yǔ)音";
}
else if (aSession.type == EMCallTypeVideo){
stype = @"視頻通話";
}
NSString *notifyStr = [NSString stringWithFormat:@"%@向您發(fā)起%@",mingYiModel.docName,stype];
notify.alertBody = notifyStr;
// 如果你想震動(dòng)的提示播放音樂(lè)的話就在下面填入你的音樂(lè)文件
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后,需要添加這個(gè)注冊(cè),才能得到授權(quán)
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(), ^{
// 執(zhí)行通知注冊(cè)
[[UIApplication sharedApplication] scheduleLocalNotification:notify];
});
}
//==========后臺(tái)持續(xù)震動(dòng)和播放鈴聲的方法============
void soundCompleteCallback(SystemSoundID sound,void * clientData) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); //震動(dòng)
AudioServicesPlaySystemSound(sound);
}
//結(jié)束鈴聲
-(void)stopAlertSoundWithSoundID:(SystemSoundID)sound {
AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);
}
//============end=================
然后在合適的地方結(jié)束震動(dòng)和提醒鈴聲浙滤。比如在視頻結(jié)束阴挣、接聽(tīng)、拒接纺腊、中斷等方法中加上結(jié)束的代碼畔咧。(代碼中很容易找到相關(guān)方法)
//調(diào)用結(jié)束震動(dòng)和提醒鈴聲的方法
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
[self stopAlertSoundWithSoundID:sound];
代碼實(shí)現(xiàn)的差不多了茎芭,效果圖如下:
**基于環(huán)信實(shí)現(xiàn)在線聊天功能 **
轉(zhuǎn)載請(qǐng)注明出處