該文章是建立在已經用環信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。
關於圖示我要提一下,由於我使用的是3.2.0,整合成功之後,我發現它給的介面有些簡陋。關鍵的圖示都沒有,全都用一塊塊button代替,毫無美感。所以我檢查了一下最新版的SDK,發現他們已經完善了這個缺陷,新加的圖示挺好看的,我就扣下來放在這個工程裡面用了。 ###實現原理整合環信,需要匯入EaseUI
、HyphenateFullSDK
、emotion
。一個是UI介面,一個是環信SDK,最後一個是emotion表情包。
實現的第一步是要從聊天介面,點選“+”出現的MoreView開始。這個MoreView出現在EaseUI中,並且視訊跟語音的圖示一開始是隱藏的,位置也有所變動。
下面就是去找到程式碼所在地,並研究一波。 在EaseChatBarMoreView.m
中找到- (void)setupSubviewsForType:(EMChatToolbarType)type{}
這個方法,在這個方法中我們就能發現,MoreView裡面的幾個按鈕圖示就是在這裡建立的,如下圖。
找到了UI建立的地方,這只是第一步。下面就要根據按鈕繫結的方法,一步步往下深究。
首先根據_videoCallButton
找到繫結的方法takeVideoCallAction
,發現它通過代理實現的另一個方法moreViewVideoCallAction:
,按住command鍵單擊方法繼續跟蹤。我們發現在EaseUI
的EaseMessageViewController.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.h
、ChatDemoHelper.m
需要匯入和註釋的標頭檔案。
ChatDemoHelper.m
中需要注意的是
- (void)makeCallWithUsername:(NSString *)aUsername
type:(EMCallType)aType{}//發起視訊
- (void)callDidReceive:(EMCallSession *)aSession{}//接收視訊
複製程式碼
這兩個方法中的mainVC是找不到的,所有我要找到當前檢視控制器,並讓它作為父檢視,模態彈出CallViewController
,如下圖所示。
MainViewController.m
的 viewDidLoad
中初始化ChatDemoHelper
貼上程式碼[ChatDemoHelper shareHelper];
(在程式進入的第一個檢視控制器中初始化)
然後執行程式碼,除錯一波,發現功能是能實現了,但是UI介面有點醜,並且沒有來電鈴聲(雖然鈴聲相關的程式碼有)。然後我找到CallViewController .m
修改了一波UI,並且自己在網上down了一段蘋果來電鈴聲,並加了上去,差不多滿足了需求。需要注意的是,鈴聲的播放要放在CallViewController.m
的viewDidAppear:(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];
複製程式碼
程式碼實現的差不多了,效果圖如下:
**基於環信實現線上聊天功能 **
轉載請註明出處 © XDChang