点对点音视频通话

点对点音视频通话功能包含点对点的音频通话和点对点的音视频通话,提供呼叫接听挂断话单通知等功能。通过阅读该章节,您可以快速了解点对点实时音视频通话的流程,帮助您迅速搭建一个最简单的点对点实时音视频通话功能。

呼叫/接听流程

sequenceDiagram 主叫->>被叫: 主叫发起通话请求(start) 被叫->>被叫: 被叫收到通话请求回调(onReceive) 被叫->>主叫: 被叫响应通话请求(response) 被叫->>被叫: 呼入的通话已经被该帐号其他端处理回调(onResponsedByOther) 主叫->>主叫: 主叫收到被叫响应回调(onResponse) 主叫->>主叫: 通话建立成功(onCallEstablished) 被叫->>被叫: 通话建立成功(onCallEstablished)

主叫发起通话请求

主叫通过该接口发起点对点通话请求

@protocol NIMNetCallManager <NSObject>
/**
 *  主叫发起通话 - 新接口
 *
 *  @param callees    被叫帐号列表, 现在只支持传入一个被叫
 *  @param type       呼叫类型
 *  @param option     开始通话附带的选项, 可以为空。如果需要 SDK 自动开启摄像头,需要指定 option 的视频采集参数 videoCaptureParam
 *  @param completion 发起通话结果回调
 */
- (void)start:(NSArray<NSString *> *)callees
         type:(NIMNetCallMediaType)type
       option:(nullable NIMNetCallOption *)option
   completion:(nullable NIMNetCallStartHandler)completion;
@end

接口参数

参数 类型 说明
callees NSArray 被叫帐号列表, 现在只支持传入一个被叫
type NIMNetCallMediaType 呼叫类型
option nullable NIMNetCallOption 开始通话附带的选项, 可以为空。如果需要 SDK 自动开启摄像头,需要指定 option 的视频采集参数 videoCaptureParam
completion nullable NIMNetCallStartHandler 发起通话结果回调
    //先初始化 option 参数
    NIMNetCallOption *option = [[NIMNetCallOption alloc] init];
    option.extendMessage = @"音视频请求扩展信息";
    option.apnsContent = @"通话请求";
    option.apnsSound = @"video_chat_tip_receiver.aac";

    //指定 option 中的 videoCaptureParam 参数
    NIMNetCallVideoCaptureParam *param = [[NIMNetCallVideoCaptureParam alloc] init];
    //清晰度480P
    param.preferredVideoQuality = NIMNetCallVideoQuality480pLevel;
    //裁剪类型 16:9
    param.videoCrop  = NIMNetCallVideoCrop16x9;
    //打开初始为前置摄像头
    param.startWithBackCamera = NO;

    //若需要开启前处理指定 videoProcessorParam
    NIMNetCallVideoProcessorParam *videoProcessorParam = [[NIMNetCallVideoProcessorParam alloc] init];
    //若需要通话开始时就带有前处理效果(如美颜自然模式)
    videoProcessorParam.filterType = NIMNetCallFilterTypeZiran;
    param.videoProcessorParam = videoProcessorParam;


    option.videoCaptureParam = param;

    //指定通话类型为 视频通话
    NIMNetCallMediaType type = NIMNetCallMediaTypeVideo;

    //开始通话
   [[NIMAVChatSDK sharedSDK].netCallManager start:callees type:type option:option completion:^(NSError *error, UInt64 callID) {
       if (!error) {
               //通话发起成功

        }else{
            //通话发起失败
        }
  }];

被叫收到通话请求回调

被叫需要来实现该回调来接收通话请求

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 *  被叫收到呼叫(振铃)
 *
 *  @param callID call id
 *  @param caller 主叫帐号
 *  @param type   呼叫类型
 *  @param extendMessage   扩展消息, 透传主叫发起通话时携带的该信息
 */
- (void)onReceive:(UInt64)callID
             from:(NSString *)caller
             type:(NIMNetCallMediaType)type
          message:(nullable NSString *)extendMessage;
@end
参数 类型 说明
callID UInt64 call id
caller NSString 主叫帐号
type NIMNetCallMediaType 呼叫类型
extendMessage nullable NSString 扩展消息, 透传主叫发起通话时携带的该信息
//被叫收到呼叫
- (void)onReceive:(UInt64)callID from:(NSString *)caller type:(NIMNetCallMediaType)type message:(NSString *)extendMessage
{
    //弹出来电通知VC
    UIViewController *vc;
    switch (type) {
        case NIMNetCallTypeVideo:{
            vc = [[NTESVideoChatViewController alloc] initWithCaller:caller callId:callID];
        }
            break;
        case NIMNetCallTypeAudio:{
            vc = [[NTESAudioChatViewController alloc] initWithCaller:caller callId:callID];
        }
            break;
        default:
            break;
    }

    [self presentViewController:vc
               animated:YES
             completion:nil];
}

被叫响应通话请求

被叫收到通话请求后,可以通过该接口来响应点对点通话请求

@protocol NIMNetCallManager <NSObject>
/**
 *  被叫响应呼叫
 *
 *  @param callID      call id
 *  @param accept      是否接听
 *  @param option      开始通话附带的选项, 可以为空。如果需要 SDK 自动开启摄像头,需要指定 option 的视频采集参数 videoCaptureParam
 *  @param completion  响应呼叫结果回调
 *
 *  @discussion 被叫拒绝接听时, 主叫不需要再调用hangup:接口
 */
- (void)response:(UInt64)callID
          accept:(BOOL)accept
          option:(nullable NIMNetCallOption *)option
      completion:(nullable NIMNetCallResponseHandler)completion;
@end
参数 类型 说明
callID UInt64 call id
accept BOOL 是否接听
option nullable NIMNetCallOption 开始通话附带的选项, 可以为空。如果需要 SDK 自动开启摄像头,需要指定 option 的视频采集参数 videoCaptureParam
completion nullable NIMNetCallResponseHandler 响应呼叫结果回调
//初始化option
NIMNetCallOption *option = [[NIMNetCallOption alloc] init];

//指定 option 中的 videoCaptureParam 参数
NIMNetCallVideoCaptureParam *param = [[NIMNetCallVideoCaptureParam alloc] init];
option.videoCaptureParam = param;

//同意接听
 BOOL accept = YES;

//被叫响应通话
[[NIMAVChatSDK sharedSDK].netCallManager response:_callId accept:accept option: option completion:^(NSError *error, UInt64 callID) {
     //链接成功
    if (!error) {

    }
    //链接失败
    else{
    }
}];

主叫收到被叫响应回调

主叫收到被叫响应回调

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 *  主叫收到被叫响应
 *
 *  @param callID   call id
 *  @param callee 被叫帐号
 *  @param accepted 是否接听
 */
- (void)onResponse:(UInt64)callID
              from:(NSString *)callee
          accepted:(BOOL)accepted;
@end
参数 类型 说明
callID UInt64 call id
callee NSString 被叫帐号
accepted BOOL 是否接听
//主叫收到被叫响应
- (void)onResponse:(UInt64)callID from:(NSString *)callee accepted:(BOOL)accepted
{
    if (self.callInfo.callID == callID) {
        if (!accepted) {
            [self.navigationController.view makeToast:@"对方拒绝接听"
                                             duration:2
                                             position:CSToastPositionCenter];
        }else{
              //停止播放提示音
              [self.player stop];

              //刷新UI
              ...
         }
    }
}

呼入的通话已经被该帐号其他端处理回调

呼入的通话已经被该帐号其他端处理回调

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 *  这通呼入通话已经被该帐号其他端处理
 *
 *  @param callID   呼入通话的call id
 *  @param accepted 是否被接听
 */
- (void)onResponsedByOther:(UInt64)callID
                  accepted:(BOOL)accepted;
@end
参数 类型 说明
callID UInt64 call id
accepted BOOL 是否被接听
//呼入的通话已经被该帐号其他端处理回调
-(void)onResponsedByOther:(UInt64)callID accepted:(BOOL)accepted
{
    [self.view.window makeToast:@"已在其他端处理"
                       duration:2
                       position:CSToastPositionCenter];                  
    [self dismiss];
}

通话建立结果回调

点对点通话建立成功后,将会通过该回调告知用户

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 点对点通话建立成功

 @param callID call id
 */
- (void)onCallEstablished:(UInt64)callID;
@end
参数 类型 说明
callID UInt64 call id
//通话建立成功回调
-(void)onCallEstablished:(UInt64)callID
{
    //通话建立成功 开始计时 刷新UI
}

挂断流程

sequenceDiagram A->>B: 结束通话(hangup) B->>B: 收到对方结束通话回调(onHangup) B->>B: 通话断开(onCallDisconnected) B->>B: 话单通知 A->>A: 通话断开(onCallDisconnected) A->>A: 话单通知

结束通话

主叫或被叫可以通过该接口挂断电话

@protocol NIMNetCallManager <NSObject>
/**
 *  挂断通话
 *
 *  @param callID 需要挂断电话的call id, 如果尚未获取到call id就填0
 *
 *  @discussion 被叫在响应呼叫之前不要调用挂断接口
 */
- (void)hangup:(UInt64)callID;
@end
参数 类型 说明
callID UInt64 需要挂断电话的call id, 如果尚未获取到call id就填0
//挂断电话
[[NIMAVChatSDK sharedSDK].netCallManager hangup:_callId];

收到对方结束通话回调

对方挂断电话后,SDK通过该回调告知用户

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 *  对方挂断电话
 *
 *  @param callID call id
 *  @param user   对方帐号
 */
- (void)onHangup:(UInt64)callID
              by:(NSString *)user;
@end
参数 类型 说明
callID UInt64 call id
user NSString 对方帐号
//收到对方挂断电话
-(void)onHangup:(UInt64)callID by:(NSString *)user
{
     //停止播放提示音 并推出vc
     [self.player stop];
     [self dismiss:nil];
}

通话断开

通话异常断开后,将会通过该回调告知用户

@protocol NIMNetCallManagerDelegate <NSObject>
/**
 通话异常断开

 @param callID call id
 @param error 断开的原因,如果是 nil 表示正常退出
 */
- (void)onCallDisconnected:(UInt64)callID
                 withError:(nullable NSError *)error;
@end
参数 类型 说明
callID UInt64 call id
error nullable NSError 断开的原因,如果是 nil 表示正常退出
//通话异常断开回调
- (void)onCallDisconnected:(UInt64)callID withError:(NSError *)error
{
    //停止计时 并推出vc
    [self.timer stopTimer];
    [self dismiss:nil];
}

话单通知

当结束网络通话后,网易云通信服务器会下发一条话单通知,用来表示这次通话的信息。 其中定义了:

解析话单通知消息的详细步骤:

  1. 判断消息是否为通知消息

    • 判断 NIMMessagemessageType 字段是否为 NIMMessageTypeNotification
  2. 判断通知消息是否为话单通知

    • NIMMessagemessageObject 字段强类型转换为 NIMNotificationObject
    • 判断转换后的 NIMNotificationObjectnotificationType 字段是否为 NIMNotificationTypeNetCall
  3. 解析话单通知的具体内容

    • NIMNotificationObjectcontent 字段强类型转换为 NIMNetCallNotificationContent
    • 查看转换后 NIMNetCallNotificationContent 的具体字段。其中,callType 字段为话单通知的具体通话类型。 eventType 字段表示具体的通话事件类型。
  4. 示例

//需要先自己获取消息 message
- (void)onRecvMessages:(NSArray *)messages
{
    NIMMessage *message = messages.firstObject;
    [self messageFormContent:message];
}

//然后解析 解析过程
- (void)messageFormContent:(NIMMessage *)message{
    if (message.messageType == NIMMessageTypeNotification ) {
        NIMNotificationObject *object = message.messageObject;
        if (object.notificationType == NIMNotificationTypeNetCall) {
            NIMNetCallNotificationContent *content = (NIMNetCallNotificationContent *)object.content;
            //音频通话
            if (content.callType == NIMNetCallTypeAudio) {
            }
            //视频通话
            else
            {
            }
        }
    }
}