实现1 对 1 音视频通话
更新时间: 2024/08/14 11:41:36
本文介绍 1 对 1 音视频通话的实现方法。
前提条件
请确保您已完成以下操作:
开发环境
开发环境要求如下:
环境要求 | 说明 |
---|---|
iOS 版本 | 11.0 及以上的 iPhone 或者 iPad 真机 |
CPU 架构 | ARM64、ARMV7 |
IDE | XCode |
其他 | 安装 CocoaPods。 |
示例项目源码
1 对 1 娱乐社交示例项目源码,跑通示例项目的方法请参见跑通示例项目。
注意事项
1 对 1 娱乐社交场景方案的呼叫能力基于云信呼叫组件,具体请参见呼叫组件文档。
技术原理
音视频通话的时序图如下图所示。
sequenceDiagram
actor A as 用户A
participant HJA as 呼叫组件A
participant G2 as RTC服务器
participant XL as 信令服务器
participant HJB as 呼叫组件B
participant server as 业务服务器
actor B as 用户B
A ->> server: 请求校验是否可以发起呼叫
server -->> A: 返回校验结果,分配ChannelName、uid等信息(可选)
Note over A,B: 呼叫
rect rgb(191, 223, 255)
A ->> HJA: A发起呼叫邀请
HJA ->> XL: 呼叫组件发起呼叫邀请
XL -->> HJB: A邀请B的信令
HJB -->> B: A邀请B
B ->> HJB: B接听
HJB ->> XL: B接听
HJB ->> G2: B加入RTC
XL -->> HJA: B接听的信令
HJA ->> G2: A加入RTC
HJA -->> A: B接听
end
Note over A,B: 计费
G2 ->> server: 发送用户A 加入房间的抄送
G2 ->> server: 发送用户B 加入房间的抄送
server ->> server: 开始计费
A ->> server: 通话中客户端向业务服务器发送计费心跳(可选)
alt 一方挂断电话
G2 ->> server: 发送用户离开房间的抄送
server ->> server: 停止计费
server -->> A: 发送通话话单
else 出现欠费
server -->> G2: 出现欠费,销毁房间
G2 -->> HJA: 通话结束
HJA -->> A: 通话结束
G2 -->> HJB: 通话结束
HJB -->> B: 通话结束
end
步骤1 集成呼叫组件 SDK
1 对 1 娱乐社交场景方案的呼叫能力基于云信呼叫组件实现。
- 引入呼叫组件。
V1.8.0 版本开始,呼叫组件内部没有引入 NERTC,请在 Podfile 中添加以下内容,单独引入 NERTC SDK 。
pod 'NERtcCallKit', '1.8.0'
pod 'NERtcSDK', '4.6.43', :subspecs => ['RtcBasic']
// subspecs => ['RtcBasic']用于指定使用RTC基础版本,不包含美颜功能。若要使用美颜功能,此行请修改为 pod 'NERtcSDK', '4.6.43'
步骤2 初始化呼叫组件
呼叫组件实现为单实例,通过接口 NERtcCallKit.sharedInstance
获取此实例,调用实例方法 setupAppKey
完成初始化。
setupAppKey
方法为使用组件前必须调用的方法,若未初始化直接调用其他组件方法,会发生不可预知的问题或故障。
示例代码
#import <NERtcCallKit/NERtcCallKit.h>
@interface SomeViewController()<NERtcCallKitDelegate>
@end
@implementation SomeViewController
- (void)viewDidLoad {
[self setupSDK];
}
- (void)setupSDK {
NERtcCallOptions *option = [NERtcCallOptions new];
option.APNSCerName = @"anps cer name"; //输入 APNs 推送证书名
option.VoIPCerName = "your push kit cer"; //输入 pushkit 的证书名
NERtcCallKit *callkit = [NERtcCallKit sharedInstance];
[callkit setupAppKey:@"app key" options:option];
// 请求 rtc token 服务,若非安全模式则不需设置。V1.8.0及之后版本不需要执行如下配置。V1.8.0之前版本需要执行如下配置。
callkit.tokenHandler = ^(uint64_t uid, void (^complete)(NSString *token, NSError *error)) {
// 获取token以及回传给SDK(通常从业务服务器获取)
NSString *token = @"get your token";
complete(token,nil);
};
}
@end
步骤3 登录和登出
若已经在 App 内实现了 NIMSDK 登录和登出逻辑,则不必调用相应的登录、登出接口,直接跳过此步骤即可。
使用组件的 -[NERtcCallKit login:]
进行登录,使用 -[NERtcCallKit logout:]
进行登出,登出或未进行登录则不能进行呼叫。
示例代码
[[NERtcCallKit sharedInstance] login:@"im accid" token:@"im token" completion:^(NSError * _Nullable error) {
}];
[[NERtcCallKit sharedInstance] logout:^(NSError * _Nullable error) {
}];
步骤4 实现呼叫功能
示例代码
///构造携带数据
NSDictionary *attachment = @{
CALLER_USER_NAME : [NEOneOnOneKit getInstance].localMember.nickName,
CALLER_USER_MOBILE : [NEOneOnOneKit getInstance].localMember.mobile,
CALLER_USER_AVATAR : [NEOneOnOneKit getInstance].localMember.avatar
};
NSString *jsonString = [[NSString alloc]
initWithData:[NSJSONSerialization dataWithJSONObject:attachment
options:NSJSONWritingPrettyPrinted
error:nil]
encoding:NSUTF8StringEncoding];
[[NERtcCallKit sharedInstance] call:accountId
type:(isAudio) ? NERtcCallTypeAudio : NERtcCallTypeVideo
attachment:jsonString
globalExtra:nil
withToken:nil
channelName:nil
completion:^(NSError *_Nullable error) {
@strongify(self) NSLog(@"%@", error);
if (error.code != 0) {
// 未接通
} else {
//已接通
}
}];
步骤5 实现挂断功能
示例代码
[[NECallKitPstn sharedInstance] hangupWithCompletion:^(NSError *_Nullable error) {
}];
步骤6 实现接听功能
示例代码
[[NERtcCallKit sharedInstance] accept:^(NSError *_Nullable error) {
@strongify(self) if (error) {
if (error.code == 10404) {
/// NERTCCallKit 内部问题,后期会优化
///按照正常接听处理
}
NSLog(@"error -- %@", error.description);
}
}];
步骤7 添加呼叫监听
示例代码
///添加监听
[[NECallKitPstn sharedInstance] addDelegate:self];
///对方已取消连接
- (void)onUserCancel:(NSString *)userID {
}
///对方同意
- (void)onUserAccept:(NSString *)userID {
}
/// 远端加入回调
- (void)onUserEnter:(NSString *)userID {
}
/// 自己加入成功的回调,通常用来上报、统计等
- (void)onJoinChannel:(NERtcCallKitJoinChannelEvent *)event {
}
///远端用户拒绝
- (void)onUserReject:(NSString *)userID {
}
///远端用户正在忙
- (void)onUserBusy:(NSString *)userID {
}
/// 连接超时
- (void)onCallingTimeOut {
}
///通话结束
- (void)onCallEnd {
}
/// 本端断网
- (void)onDisconnect:(NSError *)reason {
}
/// 对端断网
- (void)onUserDisconnect:(NSString *)userID {
}
/// 视频关闭
- (void)onVideoMuted:(BOOL)muted userID:(NSString *)userID {
}
///用户离开
- (void)onUserLeave:(NSString *)userID {
}
///发生错误
- (void)onError:(NSError *)error {
}
/// 用户加入
- (void)onNERtcEngineUserDidJoinWithUserID:(uint64_t)userID userName:(NSString *)userName {
}
如果您需要移除呼叫监听,请参考如下示例代码:
oc[[NERtcCallKit sharedInstance] removeDelegate:self];
步骤8 实现小窗功能
示例代码
oc// 小窗模式
// changeToSmall 为父类控制器(NECallViewBaseController)函数
[self changeToSmall];
// 恢复正常模式
// 重写父类函数
- (void)changeToNormal {
self.maskView.hidden = YES;
[super changeToNormal];
//其余操作:例如小窗前大小窗切换了,恢复的时候如果想恢复成小窗前的样式,需要记录状态值,然后在此处恢复的时候需要刷新
}
进阶功能
此文档是否对你有帮助?