场景概述
场景介绍
1V1 音视频通话是一种类微信通话的高频使用场景,实时音视频 TRTC 语音通话时延低于300ms,抗丢包率超过80%,抗网络抖动超过1000ms,弱网环境下依然保证语音通话流畅稳定。视频通话支持720p、1080p、2K 及 2K+(特定设备)的高清画质,提供高质量视频通话服务。结合 即时通信 IM 提供的丰富的通话信令管理接口,轻松触达各种应用场景。此外,我们还提供了音视频通话场景化组件,可以直接复用,最大程度降低开发成本,详见 组件介绍。
场景玩法
1V1 音视频通话场景不仅只有最基础的类微信通话应用,在其基础上还可以衍生出多种不同玩法,下面简要介绍几种常见的场景玩法。
游戏社交
在游戏领域,音视频通话可以让玩家之间进行实时互动,增强游戏体验。玩家可以在游戏中与好友进行语音或视频聊天,分享游戏心得、技巧,或者一起制定游戏策略。如今,音视频通话被广泛应用于连麦开黑等游戏社交玩法中。
在线客服
1V1 音视频通话可以让客户与客服人员进行实时沟通,解决问题。相比于传统的文字客服,音视频通话可以让客户更直观地描述问题,客服人员也可以更清晰地了解客户需求,提高解决问题的效率。例如,纠纷处理、保险咨询等都是很好的应用场景。
在线问诊
在医疗领域,1V1 音视频通话可以让患者与医生进行远程问诊。患者可以通过音视频通话向医生描述症状,医生也可以根据患者的描述进行初步诊断。这种方式不仅节省了患者的时间和精力,还可以让医生为更多患者提供服务,提高医疗资源的利用率。
金融审核
在金融领域,1V1 音视频通话可以用于身份验证、风险评估等环节。在开展在线理财、开户、面签等业务时,应国家监管要求,必须提供录音录像服务,形成交易记录的视频,存档备查。音视频通话在金融审核领域应用成熟,不仅提高了审核效率,还可以降低欺诈风险。
实现方案
功能模块 | 关键动作及功能点 |
通话信令控制 | 呼叫、接听、拒接、挂断 |
音视频通话 | 语音通话、视频通话 |
通话功能控制 | 打开关闭麦克风/摄像头/扬声器、听筒免提切换、摄像头切换、大小窗口切换、网络状态提示、通话时长统计 |
音视频通话场景的完整实现通常需要依赖实时音视频和即时通信的组合能力。实时音视频模块负责音视频通信及设备状态控制,即时通信模块负责信令传输及消息推送。音视频通话场景的主要架构如下图所示:
通话信令控制
呼叫
呼叫信令可以细分为发起呼叫、取消呼叫、呼叫超时几个部分,其调用时序如下图所示:
发起呼叫:主叫端向被叫端发起呼叫邀请,同时展示呼叫页面并播放铃声;被叫端收到邀请通知,同时展示呼叫页面并播放铃声。
取消呼叫:主叫端可以中途取消呼叫邀请,同时销毁呼叫页面并停止铃声;被叫端收到取消通知,同时销毁呼叫页面并停止铃声。
呼叫超时:当超过 invite 预设的超时时间 timeout 未响应,主叫端和被叫端均会收到超时通知,同时销毁呼叫页面并停止铃声。
接听
被叫端接收到来自主叫端的呼叫邀请后,可以选择接听操作,开始音视频通话。
拒接
拒接信令可以细分为主动拒接、忙线拒接两个部分,其调用时序如下图所示:
主动拒接:被叫端收到呼叫邀请后拒绝邀请,同时销毁呼叫页面并停止铃声;主叫端收到拒绝通知,同时销毁呼叫页面并停止铃声。
忙线拒接:被叫端收到呼叫邀请后,本地判断正在通话中,则直接拒绝邀请;主叫端收到拒绝通知,同时销毁呼叫页面并停止铃声。
注意:
挂断
在通话过程中,主叫和被叫任意一端均可随时选择挂断操作,结束音视频通话。
以主叫端挂断为例,主叫端执行退房操作,被叫端收到远端退房通知,同时执行退房操作,双方通话结束。
说明:
挂断操作没有使用到 IM 信令通知,而是使用 TRTC 远端用户退房回调通知实现。
音视频通话
语音通话
通话接通后,通话双方需要进入同一个 TRTC 房间,并开启本地音频采集和推流,同时互相拉取对方音频流,实现语音通话。
关于开始通话和结束通话的音视频相关接口的调用时序如下图所示:
注意:
语音通话模式下,TRTC 进房场景需选用 TRTC_APP_SCENE_AUDIOCALL,同时不要指定进房角色 TRTCRoleType。
开始音频采集
startLocalAudio
可同时设置音质参数,语音通话模式建议设置 TRTC_AUDIO_QUALITY_SPEECH。SDK 默认的自动订阅模式下,用户进入房间后,会立刻接收到该房间中的音频流,音频会自动解码播放,无需手动拉流。
视频通话
呼叫通话阶段,通话双方均需设置视频编码参数,同时开启本地视频预览。通话接通后,通话双方需要进入同一个 TRTC 房间,并开启本地音频采集和推流,同时互相拉取对方音频流和视频流,实现音视频通话。
关于呼叫通话、开始通话、结束通话的音视频相关接口的调用时序如下图所示:
注意:
视频通话模式下,TRTC 进房场景需选用 TRTC_APP_SCENE_VIDEOCALL,同时不要指定进房角色 TRTCRoleType。
进房之前调用
startLocalPreview
,SDK 只会开启摄像头预览,并一直等到您调用 enterRoom
之后才开始推流。开始音频采集
startLocalAudio
可同时设置音质参数,视频通话模式建议设置 TRTC_AUDIO_QUALITY_SPEECH。SDK 默认的自动订阅模式下,音频会自动解码播放,视频需要手动调用
startRemoteView
拉取远端视频流渲染播放。通话功能控制
音视频通话过程中,可能会涉及系列功能控制,例如:打开关闭麦克风、打开关闭扬声器、打开关闭摄像头、听筒免提切换、摄像头切换、大小窗口切换、网络状态提示、通话时长统计,这些功能控制及状态提示大多通过 TRTC SDK 完成,下面逐项介绍其具体实现。
打开关闭麦克风
// 打开麦克风mTRTCCloud.muteLocalAudio(false);// 关闭麦克风mTRTCCloud.muteLocalAudio(true);
// 打开麦克风[self.trtcCloud muteLocalAudio:NO];// 关闭麦克风[self.trtcCloud muteLocalAudio:YES];
打开关闭扬声器
// 打开扬声器mTRTCCloud.muteAllRemoteAudio(false);// 关闭扬声器mTRTCCloud.muteAllRemoteAudio(true);
// 打开扬声器[self.trtcCloud muteAllRemoteAudio:NO];// 关闭扬声器[self.trtcCloud muteAllRemoteAudio:YES];
打开关闭摄像头
// 打开摄像头, 指定前置或后置摄像头及渲染控件mTRTCCloud.startLocalPreview(isFrontCamera, videoView);// 关闭摄像头mTRTCCloud.stopLocalPreview();
// 打开摄像头, 指定前置或后置摄像头及渲染控件[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.videoView];// 关闭摄像头[self.trtcCloud stopLocalPreview];
听筒免提切换
// 切换听筒mTRTCCloud.getDeviceManager().setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteEarpiece);// 切换免提mTRTCCloud.getDeviceManager().setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteSpeakerphone);
// 切换听筒[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];// 切换免提[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
摄像头切换
// 判断当前是否为前置摄像头boolean isFrontCamera = mTRTCCloud.getDeviceManager().isFrontCamera();// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置mTRTCCloud.getDeviceManager().switchCamera(!isFrontCamera);
// 判断当前是否为前置摄像头BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置[[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];
大小窗口切换
// 更新本地预览画面渲染控件mTRTCCloud.updateLocalView(previewView);// 更新远端用户视频渲染控件mTRTCCloud.updateRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, previewView);
// 更新本地预览画面渲染控件[self.trtcCloud updateLocalView:self.previewView];// 更新远端用户视频渲染控件[self.trtcCloud updateRemoteView:self.previewView streamType:TRTCVideoStreamTypeBig forUser:self.userId];
网络状态提示
@Overridepublic void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality, ArrayList<TRTCCloudDef.TRTCQuality> remoteQuality) {if (remoteQuality.size() > 0) {switch (remoteQuality.get(0).quality) {case TRTCCloudDef.TRTC_QUALITY_Excellent:Log.i(TAG, "对方网络非常好");break;case TRTCCloudDef.TRTC_QUALITY_Good:Log.i(TAG, "对方网络比较好");break;case TRTCCloudDef.TRTC_QUALITY_Poor:Log.i(TAG, "对方网络一般");break;case TRTCCloudDef.TRTC_QUALITY_Bad:Log.i(TAG, "对方网络较差");break;case TRTCCloudDef.TRTC_QUALITY_Vbad:Log.i(TAG, "对方网络很差");break;case TRTCCloudDef.TRTC_QUALITY_Down:Log.i(TAG, "对方网络极差");break;default:Log.i(TAG, "未定义");break;}}}
#pragma mark - TRTCCloudDelegate- (void)onNetworkQuality:(TRTCQualityInfo *)localQuality remoteQuality:(NSArray<TRTCQualityInfo *> *)remoteQuality {if (remoteQuality.count > 0) {switch(remoteQuality[0].quality) {case TRTCQuality_Unknown:NSLog(@"未定义");break;case TRTCQuality_Excellent:NSLog(@"对方网络非常好");break;case TRTCQuality_Good:NSLog(@"对方网络比较好");break;case TRTCQuality_Poor:NSLog(@"对方网络一般");break;case TRTCQuality_Bad:NSLog(@"对方网络较差");break;case TRTCQuality_Vbad:NSLog(@"对方网络很差");break;case TRTCQuality_Down:NSLog(@"对方网络极差");break;default:break;}}}
注意:
localQuality
的 userId 字段为空,代表本地用户网络质量评估结果。remoteQuality
代表远端用户网络质量评估结果,其结果受远端和本地共同影响。通话时长统计
推荐使用 TRTC 远端用户进房时间作为统计通话时长的开始时间,本地用户退房时间作为统计通话时长的结束时间。
// 开始通话时间long callStartTime = 0;// 结束通话时间long callFinishTime = 0;// 通话持续时长(秒)long callDuration = 0;// 远端用户进房回调@Override public void onRemoteUserEnterRoom(String userId) { callStartTime = System.currentTimeMillis(); }// 本地用户退房回调@Override public void onExitRoom(int reason) { callFinishTime = System.currentTimeMillis();callDuration = (callFinishTime - callStartTime) / 1000; }
// 开始通话时间@property (nonatomic, assign) NSTimeInterval callStartTime;// 结束通话时间@property (nonatomic, assign) NSTimeInterval callFinishTime;// 通话持续时长(秒)@property (nonatomic, assign) NSInteger callDuration;// 远端用户进房回调- (void)onRemoteUserEnterRoom:(NSString *)userId {self.callStartTime = [[NSDate date] timeIntervalSince1970];}// 本地用户退房回调- (void)onExitRoom:(NSInteger)reason {self.callFinishTime = [[NSDate date] timeIntervalSince1970];self.callDuration = (NSInteger)(self.callFinishTime - self.callStartTime);}
注意:
高级功能
录制与审核
1V1 音视频通话场景很多情况下需要录制及存储通话内容,以便备案及后期审查。同时还有对音视频通话内容进行实时安全审核的需求,以便及时管控涉嫌违法违规的通话。下面分别介绍推荐的录制方案:TRTC 云端录制,以及推荐的审核方案:天御内容安全审核。
TRTC 云端录制
TRTC 最新升级的云端录制,不依赖云直播的能力,无需旁路转推云直播,使用 TRTC 内部的实时录制集群进行音视频录制,拥有更完整统一的录制体验。
单流录制:通过 TRTC 的云端录制功能,您可以将房间中通话双方的音视频流都录制成独立的文件。
混流录制:将同一个房间中的所有音视频媒体流混流录制成一个文件。
天御内容安全审核
TRTC 联合 T-Sec 天御,提供了实时的音视频内容识别与告警服务,使用实时音视频服务时,支持全局自动或手动发起策略进行音视频内容的识别和告警:
全局自动审核
客户可以指定审核策略和审核流类型,TRTC 云端自动完成应用下所有房间内的音视频内容审核,并通过回调把违规信息发送到客户指定的回调 URL,无需手动发起审核。该方式简单易用,省去了代码接入的工作量,但灵活性欠佳。
TRTC 与天御内容安全审核平台结合的实现原理如下图所示:直播内容安全通过“哑终端”的形式进入指定的 TRTC 房间,作为“观众”拉取音视频流,并针对拉取的音视频流进行内容审核,然后通过回调把违规信息发送到用户指定的 HTTP/HTTPS 服务上。
手动自定义审核
客户只需要调用天御音视频流接口即可实时检测音视频流中是否出现违规内容。音视频安全审核服务会通过回调把违规信息发送给客户指定的回调 URL。该方式更灵活、可定制化更强,但需要调用 REST API 发起审核任务,具有一定的接入复杂度。
视频美颜特效
视频通话场景中,美颜是一个被高频使用的功能。美颜不但能提升用户的颜值,也能通过一些贴纸特效增加通话互通的趣味性。TRTC 支持 腾讯美颜特效 的集成,同时也支持市面上主流第三方美颜产品的接入,例如火山美颜、相芯美颜等。
美颜接入流程
API 调用时序
美颜产品对比
离线消息推送
音视频通话场景通常需要用到离线消息推送,被叫用户 App 不在线时也能收到新的来电消息。即时通信 IM 提供了两种集成方式:自集成推送 和 推送插件。推送插件(TIMPush)为您提供稳定、及时、多样化的推送服务。相比自集成推送,推送插件只需进行简单配置,即可一键式集成接入多个厂商的推送服务。
步骤一:开通推送插件
步骤二:集成推送插件
1. 注册应用到厂商推送平台
离线推送需要将您自己的应用注册到各个厂商的推送平台,得到 AppID 和 AppKey 等参数,用于实现离线推送功能。目前国内支持的手机厂商有:小米、华为、荣耀、OPPO、VIVO、魅族,境外支持 Google FCM。iOS 需要向 Apple 申请 APNs 推送证书,详见 申请 APNs 证书。
2. IM 控制台配置厂商推送证书
登录腾讯云 即时通信 IM 控制台,在推送管理 > 接入设置功能栏添加各个厂商推送证书,并将您在之前步骤获取到各厂商的 AppId、AppKey、AppSecret 等参数配置给添加的推送证书。iOS 配置方式详见 上传证书到控制台。
厂商推送平台
IM 控制台配置
厂商推送平台
IM 控制台配置
说明:
Client ID 对应 AppID,Client Secret 对应 AppSecret。
厂商推送平台
IM 控制台配置
厂商推送平台
IM 控制台配置
厂商推送平台
IM 控制台配置
3. 下载并添加配置文件
完成控制台厂商推送信息填写后,下载并添加配置文件到工程。将下载的 timpush-configs.json 文件添加到应用模块的 assets 目录下:
3.1 选择下载配置文件 timpush-configs.json
3.2 添加到工程
4. 集成 TIMPush 插件
// 推送主包必须要集成implementation 'com.tencent.timpush:timpush:7.7.5283'// 按照需要集成对应厂商implementation 'com.tencent.timpush:huawei:7.7.5283'implementation 'com.tencent.timpush:xiaomi:7.7.5283'implementation 'com.tencent.timpush:oppo:7.7.5283'implementation 'com.tencent.timpush:vivo:7.7.5283'implementation 'com.tencent.timpush:honor:7.7.5283'implementation 'com.tencent.timpush:meizu:7.7.5283'implementation 'com.tencent.timpush:fcm:7.7.5283'
说明:
1. TIMPush 需要集成 IMSDK 在 7.6.5011 版本及以上。
2. 无 UI 或者没有集成其他插件的用户,需要增加集成 TUICore,支持源码和 Maven 集成,方式如下:
def projects = this.rootProject.getAllprojects().stream().map { project -> project.name }.collect() api projects.contains("tuicore") ? project(':tuicore') : "com.tencent.timpush:tuicore:7.7.5286"
TIMPush 组件支持 cocoapods 集成,您需要在 Podfile 中添加组件依赖。
target 'YourAppName' do# Uncommment the next line if you're using Swift or would like to use dynamic frameworksuse_frameworks!use_modular_headers!# Pods for Examplepod 'TIMPush', '7.7.5283'end
执行以下命令,安装 TIMPush 组件。
pod install # 如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。 pod repo update
步骤三:使用离线消息推送
V2TIMOfflinePushInfo v2TIMOfflinePushInfo = new V2TIMOfflinePushInfo();v2TIMOfflinePushInfo.setTitle("推送标题");v2TIMOfflinePushInfo.setDesc("推送内容");// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致v2TIMOfflinePushInfo.setAndroidOPPOChannelID("tuikit");v2TIMOfflinePushInfo.setAndroidHuaWeiCategory("IM");v2TIMOfflinePushInfo.setAndroidVIVOCategory("IM");// 设置自定义铃声v2TIMOfflinePushInfo.setIOSSound("phone_ringing.mp3");v2TIMOfflinePushInfo.setAndroidSound("phone_ringing");// 发送通话邀请信令V2TIMManager.getSignalingManager().invite(userId, data, false, v2TIMOfflinePushInfo, timeout, new V2TIMCallback() {@Overridepublic void onError(int code, String desc) {// 发送邀请信令失败}@Overridepublic void onSuccess() {// 发送邀请信令成功}});
TUIOfflinePushInfo *pushInfo = [TUIOfflinePushInfo new];pushInfo.title = @"推送标题";pushInfo.desc = @"推送内容";// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致pushInfo.AndroidOPPOChannelID = @"tuikit";pushInfo.AndroidHuaWeiCategory = @"IM";pushInfo.AndroidVIVOCategory = @"IM";// 设置自定义铃声pushInfo.iOSSound = @"phone_ringing.mp3";pushInfo.AndroidSound = @"phone_ringing";// 发送通话邀请信令[[V2TIMManager sharedInstance] invite:userId data:data onlineUserOnly:NO offlinePushInfo:pushInfo timeout:30 succ:^{NSLog(@"sendInvitation success");} fail:^(int code, NSString *desc) {NSLog(@"sendInvitation error %d", code);}];
方案配套产品
系统层级 | 产品名称 | 场景用途 |
接入层 | 提供低延时、高品质的音视频实时互动解决方案,是音视频通话场景的基础底座能力。 | |
接入层 | 提供高可靠且稳定的信令传输、自定义消息收发,实现音视频通话场景的通话信令控制。 | |
接入层 | 提供美颜、滤镜、美妆、趣味贴纸、Moji 表情、虚拟形象等实时特效处理能力。 | |
云端服务 | 面向音视频媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。 | |
安全服务 | 提供音频审核服务,自动识别音频中出现的可能令人反感、不安全或不适宜内容,支持自定义黑名单热词,识别自定义类型的音频内容。 | |
安全服务 | 针对多种形式的视频文件/视频流进行多样化的场景检测和内容识别,精准识别视频中出现可能令人反感、不安全或不适宜内容。 | |
数据存储 | 提供音视频录制文件、音视频切片文件的存储服务。 |