iOS

# 体验提升

# 1. 通话中质量检测

在通话场景中,开发者经常需要了解当前通话的通话质量、设备状态等信息,监测通话的整体体验;也可将部分质量数据在 UI 层面展示给用户,使用户能够及时了解当前通话的整体质量。

Juphoon RTC SDK 支持将关键的音视频状况、网络状况、设备状态的相关指标实时回调给 APP 应用层,应用层可以将收到的数据进行展示或统计。

# 网络质量检测

视频通话过程中,通话中成员的网络状态发生变化导致视频通话出现质量波动的时候,SDK 会通JRTCAgentCallback (opens new window)onMemberUpdate (opens new window) 回调进行上报。

/**
 * 通话中成员属性更新回调
 *
 * 常用的有 {@link ChangeParam#volume 音量值}、{@link ChangeParam#audio 音频上传状态}、{@link ChangeParam#video 视频上传状态}等。<br>
 * 例如当通话中有成员关闭视频传输,通话中所有成员都会收到此回调。
 * @param participant 属性更新的成员对象
 * @param changeParam 更新的属性对象
 */
void onMemberUpdate(JRTCRoomParticipant participant, ChangeParam changeParam);

示例代码:

public void onMemberUpdate(JRTCRoomParticipant part, JRTCRoomParticipant.ChangeParam param) {
	if (param.netStatus) {
		switch (part.getNetStatus()) {
			case JRTCRoom.NET_STATUS_DISCONNECTED:
				// 断开
				break;
			case JRTCRoom.NET_STATUS_VERY_BAD:
				// 非常差
				break;
			case JRTCRoom.NET_STATUS_BAD:
            	// 差
            	break;
        	case JRTCRoom.NET_STATUS_NORMAL:
            	// 一般
            	break;
        	case JRTCRoom.NET_STATUS_GOOD:
            	// 好
            	break;
        	case JRTCRoom.NET_STATUS_VERY_GOOD:
            	// 非常好
            	break;
    	}
    }
}

# 音频质量检测

视频通话过程中,通话中成员的说话声音状态发生变化,SDK 会通过 JRTCAgentCallback (opens new window)onMemberUpdate (opens new window) 回调进行上报。

示例代码:

void onMemberUpdate(JRTCRoomParticipant part, JRTCRoomParticipant.ChangeParam param)
{
    if (param.VolumeStatus){
        switch (part.volumeStatus){
            case VOLUME_STATUS_NONE:
                /// 无声音 1-30
                break;
            case VOLUME_STATUS_VERY_LOW:
                /// 很低 30-40
                break;
            case VOLUME_STATUS_LOW:
                /// 低 40-50
                break;
            case VOLUME_STATUS_MID:
                /// 中 50-70
                break;
            case VOLUME_STATUS_HIGH:
                /// 高 70-80
                break;
            case VOLUME_STATUS_VERY_HIGH:
                /// 很高 >80
                break;
        }
    }
}

# 剩余可用内存检测

通话建立后,JRTCMediaDeviceCallback (opens new window)onMemoryAvailable (opens new window) 将定时上报系统中的内存剩余情况,检测系统的运行情况。

/**
 * 上报剩余可用内存回调
 *
 * 周期性上报一次内存剩余情况
 * @param memorySize  当前剩余可用内存空间(MB)
 */
void onMemoryAvailable(double memorySize);

# 2. 获取统计信息

实时统计信息用于在通话中查看音视频收发情况,以及分辨率、帧率、码率,网络情况等。

/**
 * 获取统计信息
 *
 * 以Json字符串形式返回,其中包含 "Config", "Network","Transport" 和 "Participants" 4个节点:
 * {
 *      "Config":                                   // 音视频设置信息
 *      {
 *          "Audio Config:                          // 音频设置
 *          {
 *              "SRTP": off,                        // 是否对音频RTP数据加密,以及加密会显示使用的加密协议,加密协议两端一致才会音频互通正常
 *              "Codec": opus,                      // 本端设置的音频编码
 *              "Payload": 116,                     // 音频payload的大小
 *              "Bitrate": 16000,                   // 音频码率
 *              "Pkt Len": 60,                      // 音频包长
 *              "Nack": off,                        // 丢包是否允许数据包重传
 *              "RTX": off,                         // 是否允许RTX技术
 *              "FEC/RED": off,                     // 是否开启FEC
 *              "AEC": on,                          // 是否开启回声消除
 *              "Mode": OS,                         // AEC模式
 *              "HowlSupp": Auto,                   // AEC HowlSupp模式
 *              "Sts": Auto,                        // AEC Sts模式
 *              "AGC": on,                          // 是否开启发送端自动增益
 *              "Mode": Fixed,                      // 发送端AGC Mode
 *              "Target": 3,                        // 发送端AGC Target
 *              "Gain": 9,                          // 接收端AGC Gain
 *              "Rx AGC": off,                      // 是否开启接收端自动增益
 *              "Mode": Fixed,                      // 接收端AGC Mode
 *              "Target": 3,                        // 接收端AGC Target
 *              "Gain": 9,                          // 接收端AGC Gain
 *              "VAD": off,                         // 是否开启VAD
 *              "Mode": Mid,                        // VAD Mode
 *              "ANR": off,                         // 是否开启发送端噪音抑制
 *              "Mode": High,                       // ANR mode
 *              "Noise": N/A,                       // 噪音音量
 *              "SNR": N/A,                         // 信噪比
 *              "Rx ANR": off,                      // 是否开启接收端噪音抑制
 *              "Mode": Low,                        // 接收端ANR mode
 *              "ARS": off,                         // 是否开启音频码率控制
 *              "BR Min": N/A,                      // ARS码率最小值
 *              "BR Max": N/A                       // ARS码率最大值
 *          },
 *          "Video Config":                         // 视频设置
 *          {
 *              "SRTP": off,                        // 是否对音频RTP数据加密,以及加密会显示使用的加密协议,加密协议两端一致才会音频互通正常
 *              "Codec": H264-SVC,                  // 双方通话采用的编解码类型
 *              "Payload": 125,                     // 视频Payload的大小
 *              "Bitrate": 2250,                    // 视频码率,单位kbps
 *              "Framerate": 24,                    // 视频帧率,单位fps
 *              "Resolution": 1280x720,             // 视频分辨率
 *              "FEC": on|124|123,                  // FEC是否打开和payload的类型号
 *              "FIR": off,                         // 是否允许重发关键帧
 *              "Key Interval": 0,                  // 允许的最小关键帧间隔
 *              "Repeat": 0,                        // 关键帧丢失是否允许重发
 *              "NACK": off,                        // 丢包是否允许数据包重传
 *              "RTX": off,                         // 是否允许RTX技术,RTX的payload类型
 *              "TMMBR": off,                       // 是否允许带宽估计
 *              "RPSI": off,                        // 是否允许RPSI技术
 *              "Small NALU": on,                   // 是否允许NALU技术
 *              "ARS": off,                         // 是否开启ARS自动码率检测
 *              "BR Min": 10,                       // ARS发送码率下限
 *              "BR Max": 2000,                     // ARS发送码率上限
 *              "FR Min": 1,                        // ARS发送帧速率下限
 *              "FR Max": 30,                       // ARS发送帧速率上限
 *              "Res. Ctrl": off,                   // 是否允许分辨率控制
 *              "Res. Mode": 0,                     // 分辨率Mode
 *              "Fr Ctrl": on,                      // 是否允许帧速率控制
 *              "CPU Load Ctrl": off,               // 是否允许CPU控制
 *              "Target": 80,                       // CPU控制的最大使用率
 *              "Bw Efficient": off,                // 是否采用节省带宽模式
 *              "Error Conceal": off,               // 是否允许错误隐藏技术,在解码出错的时候采用
 *              "Enhance color": off,               // 是否采用颜色增强技术
 *              "Boost bright": off,                // 是否采用亮度增强技术
 *              "Boost contrast": off,              // 是否采用对比度增强技术
 *              "RTP Ext": CVO,                     // 使用的RTP扩展的类型
 *              "Render Name": N/A,                 // 渲染图像的名字
 *              "SVC": "320 180 250 640 360 600 1280 720 1400",     // 会议SVC配置
 *              "TemporalLayers": 4,                // 取值1、2、3、4,会议时间层设置
 *              "PreferMode":Clear                  // 偏好设置
 *          }
 *      },
 *      "Network":                                  // 网络统计信息
 *      {
 *          "Send Statistic:                        // 数据发送统计信息
 *          {
 *              "Packets": 181|1305|0|0,            // 发送的数据包的个数。正常包个数 | 探测包个数 | RED包个数 | NACK包个数
 *              "RTT": 4,                           // 网络双向延时的时间,单位为毫秒
 *              "Jitter": 2,                        // 网络的扰动,表征数据包抖动的时间,单位毫秒
 *              "Lost": 2,                          // 丢失的数据包的个数
 *              "LostRate": 0,                      // 当前的丢包率,单位百分比
 *              "RelayLost": 0,                     // 服务器转发丢包率
 *              "RelayRtt": 0,                      // 服务器转发往返时延,单位为毫秒
 *              "BitRate/BWE": 16/1345,             // BitRate表示当前发送的数据包的码率,单位kbps;BWE表示当前发送带宽的估计值
 *              "AudioSend": 0|0,                   // 实际发送音频包次数|估计发送音频包次数
 *              "VideoSend": 0|0,                   // 实际发送视频包次数|估计发送视频包次数
 *              "ScreenSend": 0|0,                  // 实际发送屏幕共享包次数|估计发送屏幕共享包次数
 *              "MaxPredKbps": 100,                 // 发送最大需求码率
 *              "Server(102679111220103708)":       // 选用的第一个服务器
 *              [
 *                  2211(1): BWE(1345|697) LOSS(0|0) OUT(A:37) IN(A:0;)
 *              ]
 *          },
 *          "Recv Statistic":                       // 数据接收统计信息
 *          {
 *              "Packets": 1423|675|0|0,            // 收到的数据包的个数。正常包个数 | 探测包个数 | RED包个数 | NACK包个数
 *              "Jitter": 1,                        // 网络的扰动,表征数据包乱序的时间,单位毫秒
 *              "Lost": 0,                          // 丢失的数据包的个数
 *              "Lost Ratio": 0,                    // 当前的丢包率,单位百分比
 *              "BitRate/BWE":178/2291,             // BitRate表示当前接收的数据包的码率,单位kbps;BWE表示当前接收带宽的估计值
 *              "Server(102679111220103708)":       // 选用的第一个服务器
 *              [
 *                  2211(3): BWE(1979|2150) LOSS(0|0) OUT(A:37;FPS:24,FEC:10,SUB:00f0=3456) IN(A:17;V:2273=2211[00f0]2273)
 *              ]
 *          },
 *      }
 *      "Transport":                                // 运输通道
 *      {
 *          "Local": 2.1923737535:32414,            // 本地地址
 *          "Remote": 2:11023,                      // 远端地址
 *          "LastPaths": 2,2,                       // 最后使用通道
 *          "Path": 2 [udp],                        // 通道名
 *          "Step1": Delay/Loss(S/R): 4/0/0,        // 通道质量
 *          "Cost": 7** (best: -1)                  // 通道分数
 *
 *      },
 *      "Participants":
 *      {
 *          "2333":                                 // 成员为自己
 *          {
 *              "Audio Sending Stats":              // 音频发送数据统计
 *              {
 *                  "Packets": 143,                 // 发送的数据包的个数
 *                  "BitRate": 18.5,                // 发送的数据包的码率,单位kbps
 *                  "FecPrecent": 0                 // 音频Fec保护百分比,N/A表示未开启FEC保护
 *              },
 *              "Video Sending Stats":              // 视频发送数据统计
 *              {
 *                  "Packets": 19502,               // 发送的数据包的个数
 *                  "Capture Res": 640x360,         // 视频采集分辨率
 *                  "Capture Fr": 30,               // 视频采集帧率
 *                  "FPS/IDR": [0|0|24|0]/3,        // 当前视频发送帧速/已发送的视频关键帧数
 *                  "Resolution": 1280x720[0|0|0],  // 当前发送图像最大尺寸。[]中为每种尺寸的帧率,取值范围为0到f(十六进制),0表示该层视频未被发送, 值越大表示该层视频帧率越高;
 *                  "Bitrate/Setrate": 0/2250,      // Bitrate表示当前发送的数据包的码率,单位kbps; Setrate表示视频编码的目标码率,单位kbps。
 *                  "QP": 20,                       // 发送当前图像的量化步长(0-51),越小图像画质越好。
 *                  "EncodeTime": 10,               // 当前编码时间,可以体现终端编码时占用的CPU性能,越大表示CPU占有越高,单位毫秒
 *                  "Codec": H264-SVC,              // 采用的编解码类型
 *                  "FecPrecent": 20                // 视频Fec保护百分比,N/A表示未开启FEC保护
 *              },
 *              "Be Subscribed Stats":              // 被订阅统计信息
 *              {
 *                  "Audio": true,                  // 音频是否被订阅
 *                  "Video": [0|0|F|0]              // [S0|S1|S2|S3]表示4个空间层被订阅
 *              },
 *              "Publish Stats":                    // 当前音视频发布状态
 *              {
 *                  "Audio": true,                  // 当前音频发布状态
 *                  "Video": true                   // 当前视频发布状态
 *              }
 *          },
 *          "6666":                                 // 成员不是自己
 *          {
 *              "Audio Receiving Stats":            // 音频接收统计信息
 *              {
 *                  "Packets": 40243,               // 接收的数据包的个数
 *                  "BitRate": 18.5,                // 当前接收的数据包的码率,单位kbps。
 *                  "EpdRate/lr/dc": 0/0/0,         // expand rate/loss rate/discard rate。neteq buffer中的扩展比例/丢包比例/丢弃比例
 *              },
 *              "Video Receiving Stats":            // 视频接收统计信息
 *              {
 *                  "Packets": 19502,               // 接收的数据包的个数
 *                  "BitRate": 161,                 // 当前发送的数据包的码率,单位kbps
 *                  "FPS/FIR": 24/0,                // 当前视频接收帧率/视频关键帧请求个数
 *                  "Resolution": 1280x720,         // 当前接收分辨率
 *                  "Render FR": 24,                // 当前渲染帧速率
 *                  "Codec": H264-SVC,              // 采用的编解码类型
 *                  "PvMos": 4.9,                   // 表示过去5s平均流畅度MOS分,每5s更新一次。体现视频画面的流畅程度。1到5分,1分最差,5分最好
 *                  "SMOS": 5,                      // 表示当前清晰度MOS分。体现视频画面的清晰程度。1到5分,1分最差,5分最好。前5s是0,是正常现象,因为PvMos还没有值
 *              },
 *              "Subscribed Stats":                 // 订阅统计信息
 *              {
 *                  "Channel Audio": true,          // 当前是否发布音频
 *                  "Audio": true,                  // 当前音频订阅状态
 *                  "Video": [0|0|F|0]              // [S0|S1|S2|S3]表示4个空间层被订阅
 *              }
 *          }
 *      }
 * }
 */
 public abstract String getStatistics();
 
 /**
 * 获取天赛实时统计信息
 *
 * 以Json字符串形式返回,包含以下信息:
 * {
 *  "localActor": "[username:2333@100645.cloud.justalk.com]", // actorID
 *  "sendBWE": "1440",      // 发送带宽估计
 *  "recvBWE": "929",       // 接收带宽估计
 *  "sendBr": "16",         // 发送码率
 *  "recvBr": "772",        // 接收码率
 *  "sendJitter": "1",      // 发送jitter
 *  "recvJitter": "0",      // 接收jitter
 *  "sendLossRate": "0",    // 发送丢包率
 *  "recvLossRate": "0",    // 接收丢包率
 *  "encodeTime": "0",      // 编码时长
 *  "rtt":"5",              // 往返延时
 *  "audioSendBr": "19",    // 音频发送码率
 *  "videoSendBr": "0",     // 视频发送码率
 *  "audioLevel": "58",     // 音量
 *  "event":""
 * }
 */
    public abstract String getJsonStats();

示例代码:

// 获取实时统计信息
agent.getStatistics();

# 3. 获取通话唯一标识

通话唯一标识 getCallId (opens new window) 对应于业务管理平台上的callId,可用于查询录像数据、查询录像上传结果等等。

/**
 * 获取通话唯一标识
 *
 * @return 通话唯一标识
 */
public abstract String getCallId();

示例代码:

// 获取通话唯一标识
String callId = agent.getCallId();

# 4. 获取通话支持的视频分辨率列表

通过该接口获取通话内支持的订阅分辨率列表

/**
 * 获取该通话支持的视频分辨率列表
 *
 * @return 通话视频分辨率列表
 */
public abstract List<JRTCVideoSize> getSupportVideoSizes();

# 5. 电子签名

调用 requestSign (opens new window) 发起电子签名:

/**
 * 请求访客签名
 *
 * 请求访客签名流程:
 * 1. 座席调用此接口向指定访客发送签名请求
 * 2. 座席调用成功后,访客会收到 {@link JRTCGuestCallback#onSignRequest(String, String)}  onSignRequest} 回调
 * 3. 访客进行签名,并将签名图片上传至业务管理平台(需要应用层自行实现)
 * 4. 访客响应座席签名结果
 *
 * @param userId 需要请求签名的访客用户ID
 * @param extraInfo 随路额外消息
 * @return 接口调用结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
public abstract boolean requestSign(String userId, String extraInfo);

示例代码:

//座席发起电子签名
agent.requestSign("agent2","extraInfo");

收到电子签名结果回调

/**
 * 收到签名请求回调
 *
 * 通话中座席调用 {@link JRTCAgent#requestSign requestSign} 接口给访客发送签名请求,访客会收到此回调。
 *
 * @param fromUserId 发起签名请求的座席用户ID
 * @param extraInfo 随路额外消息
 */
void onSignRequest(String fromUserId, String extraInfo);

# 6. 文件上传

# 使用老的 upload 服务文件上传

/**
 * 获取文件上传路径
 *
 * 调用此接口,fileId 非必须指定时可传空字符串 <br>
 * 调用成功后,文件上传路径等具体信息可通过 {@link JRTCClientCallback#onGetUploadUrlResult onGetUploadUrlResult} 回调获取 <br>
 * @param fileId 文件id
 * @note 文件 id 用于断点续传,第二次续传文件时需要传递前一次获取到的 fileId
 *       首次新文件上传,建议传空,fileId 由服务器自动生成下发
 * @return 接口调用结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
public abstract boolean getUploadUrl(String fileId);

文件上传地址会在 JRTCClientCallback (opens new window) 里的 onGetUploadUrlResponse (opens new window) 中获得

/**
 * 获取文件上传地址等信息回调
 *
 * 通话中访客可调用 {@link JRTCClient#getUploadUrl getUploadUrl} 接口获取文件上传的地址等信息,具体信息通过此回调获取。
 * @note
 * 一般上传本地文件到服务器时,需要先调用 {@link JRTCClient#getUploadUrl getUploadUrl} 接口,然后通过此回调的信息再上传至服务器。
 * @param result 获取结果,true 表示获取成功,false 表示获取失败
 * @param token 校验用的token
 * @param url 文件上传地址
 * @param fileId 文件id
 * @param offset 文件续传位置
 */
void onGetUploadUrlResponse(boolean result, String token, String url, String fileId, long offset);

示例代码:

// 获取文件上传路径信息
client.getUploadUrl();

// 收到获取文件上传地址等信息回调
public void onGetUploadUrlResponse(boolean result, String token, String url, String fileId, long offset) {
    // 获取到文件上传地址等信息后,上传文件至服务器
}

# 使用新 upload 服务文件上传

获取文件上传或断点续传信息 requestFileUploadInfo (opens new window)

/**
 * 获取文件上传或断点续传信息
 *
 * @param serialId               业务id,必选,如果是通话业务相关文件,需要传通话唯一标识 callId
 * @param requestFileUploadParam 请求文件上传信息参数,必选
 * @return 接口调用结果
 * - 操作id: 接口调用成功,对应 {@link JRTCClientCallback#onRequestFileUploadInfoResponse(int, boolean, String, String, long, String, long, int, String, String, String)} onRequestFileUploadInfoResponse }  回调的 operatorId 参数
 * - -1: 接口调用异常,不会收到回调
 * @note 目前仅支持视频和图片类型文件上传,服务端会通过文件后缀名判断
 * @see JRTCRequestFileUploadParam
 */
public abstract int requestFileUploadInfo(String serialId, JRTCRequestFileUploadParam requestFileUploadParam);

/**
 * 获取文件上传或断点续传信息响应
 *
 * @param operatorId       操作id,对应 {@link JRTCClient#requestFileUploadInfo(String, JRTCRequestFileUploadParam) requestFileUploadInfo} 的返回值
 * @param result           请求是否成功
 *                         - true: 请求成功
 *                         - false:请求失败
 * @param url              上传地址,分片录制文件上传场景,首次请求分片上传信息时有效
 * @param token            文件上传所需token,用于校验上传合法性,需要在上传文件的时候携带
 * @param requestTimestamp 本次请求发起时间戳,用于控制上传地址有效期,需要在上传文件的时候携带
 * @param extraInfo        随路参数
 * @param fileSize         文件大小
 * @param offset           偏移量
 * @param fileType         文件类型
 * @param serverOid        上传目标服务Oid
 * @param reason           请求失败原因描述,当 result 为 false 时有效
 */
void onRequestFileUploadInfoResponse(int operatorId, boolean result, String url, String token, long requestTimestamp, String extraInfo, long fileSize, int offset, String fileType, String serverOid, String reason);

示例代码:

// 创建上传文件参数对象
JRTCRequestFileUploadParam fileUploadParam = new JRTCRequestFileUploadParam();
fileUploadParam.setFileName("");
...
// 获取文件上传或断点续传信息
client.requestFileUploadInfo("serialId",fileUploadParam);

public void onRequestFileUploadInfoResponse(int operatorId, boolean result, String url, String token, long requestTimestamp, String extraInfo, long fileSize, int offset, String fileType, String serverOid, String reason){
	if (result) {
     // 根据返回 url 进行文件上传
  } else {
     // 查看 reason 值(请求失败原因)
  }
}

文件上传成功后,再调用 completeFileUpload (opens new window)接口确认文件已上传

/**
 * 文件上传完成确认
 *
 * @param serialId                业务id,必选,如果是通话业务相关文件,需要传通话唯一标识 callId
 * @param completeFileUploadParam 文件上传完成确认参数,必选
 * @return 接口调用结果
 * - 操作id: 接口调用成功,对应 {@link JRTCClientCallback#onCompleteFileUploadResponse(int, boolean, String, String, String, String) onCompleteFileUploadResponse} 回调的 operatorId 参数
 * - -1: 接口调用异常,不会收到回调
 * @note 通过 http 上传文件完成后,需要调用该接口确认完成,否则上传文件将无法在平台查询到
 * @see JRTCCompleteFileUploadParam
 */
public abstract int completeFileUpload(String serialId, JRTCCompleteFileUploadParam completeFileUploadParam);

/**
 * 文件上传完成确认响应
 *
 * @param operatorId 操作id,对应 {@link JRTCClient#completeFileUpload(String, JRTCCompleteFileUploadParam) completeFileUpload} 的返回值
 * @param result     请求是否成功
 *                   - true: 请求成功
 *                   - false:请求失败
 * @param fileName   服务器合并后的文件名
 * @param extraInfo  随路参数
 * @param fileType   文件类型
 * @param reason     请求失败原因描述,当 result 为 false 时有效
 */
void onCompleteFileUploadResponse(int operatorId, boolean result, String fileName, String extraInfo, String fileType, String reason);

示例代码:

// 文件上传完成确认
JRTCCompleteFileUploadParam fileUploadParam = new JRTCCompleteFileUploadParam();
client.completeFileUpload("serialId",fileUploadParam);

// 文件上传完成确认响应
public onCompleteFileUploadResponse(int operatorId, boolean result, String fileName, String extraInfo, String fileType, String reason){
  if (result) {
    
  }
}