场景解决方案

最近更新时间:2024-06-13 14:18:11

我的收藏

场景概述

场景介绍

1V1 音视频通话是一种类微信通话的高频使用场景,实时音视频 TRTC 语音通话时延低于300ms,抗丢包率超过80%,抗网络抖动超过1000ms,弱网环境下依然保证语音通话流畅稳定。视频通话支持720p、1080p、2K 及 2K+(特定设备)的高清画质,提供高质量视频通话服务。结合 即时通信 IM 提供的丰富的通话信令管理接口,轻松触达各种应用场景。此外,我们还提供了音视频通话场景化组件,可以直接复用,最大程度降低开发成本,详见 组件介绍




场景玩法

1V1 音视频通话场景不仅只有最基础的类微信通话应用,在其基础上还可以衍生出多种不同玩法,下面简要介绍几种常见的场景玩法。

游戏社交

在游戏领域,音视频通话可以让玩家之间进行实时互动,增强游戏体验。玩家可以在游戏中与好友进行语音或视频聊天,分享游戏心得、技巧,或者一起制定游戏策略。如今,音视频通话被广泛应用于连麦开黑等游戏社交玩法中。

在线客服

1V1 音视频通话可以让客户与客服人员进行实时沟通,解决问题。相比于传统的文字客服,音视频通话可以让客户更直观地描述问题,客服人员也可以更清晰地了解客户需求,提高解决问题的效率。例如,纠纷处理、保险咨询等都是很好的应用场景。

在线问诊

在医疗领域,1V1 音视频通话可以让患者与医生进行远程问诊。患者可以通过音视频通话向医生描述症状,医生也可以根据患者的描述进行初步诊断。这种方式不仅节省了患者的时间和精力,还可以让医生为更多患者提供服务,提高医疗资源的利用率。

金融审核

在金融领域,1V1 音视频通话可以用于身份验证、风险评估等环节。在开展在线理财、开户、面签等业务时,应国家监管要求,必须提供录音录像服务,形成交易记录的视频,存档备查。音视频通话在金融审核领域应用成熟,不仅提高了审核效率,还可以降低欺诈风险。

实现方案

通常实现一个基本的 1V1 音视频通话场景需要涉及到多个功能模块,我们可以将实现方案大致分为三个部分:通话信令控制音视频通话通话功能控制。每个部分的关键动作及功能点如下表所示。
功能模块
关键动作及功能点
通话信令控制
呼叫、接听、拒接、挂断
音视频通话
语音通话、视频通话
通话功能控制
打开关闭麦克风/摄像头/扬声器、听筒免提切换、摄像头切换、大小窗口切换、网络状态提示、通话时长统计
音视频通话场景的完整实现通常需要依赖实时音视频和即时通信的组合能力。实时音视频模块负责音视频通信及设备状态控制,即时通信模块负责信令传输及消息推送。音视频通话场景的主要架构如下图所示:




通话信令控制

根据一个完整的通话流程,通话信令可以分为 呼叫接听拒接挂断 几个部分。以 即时通信 IM 为例,下面介绍用户完成 登录操作 后的通话信令控制部分的具体实现逻辑。

呼叫

呼叫信令可以细分为发起呼叫、取消呼叫、呼叫超时几个部分,其调用时序如下图所示:



发起呼叫:主叫端向被叫端发起呼叫邀请,同时展示呼叫页面并播放铃声;被叫端收到邀请通知,同时展示呼叫页面并播放铃声。
取消呼叫:主叫端可以中途取消呼叫邀请,同时销毁呼叫页面并停止铃声;被叫端收到取消通知,同时销毁呼叫页面并停止铃声。
呼叫超时:当超过 invite 预设的超时时间 timeout 未响应,主叫端和被叫端均会收到超时通知,同时销毁呼叫页面并停止铃声。

接听

被叫端接收到来自主叫端的呼叫邀请后,可以选择接听操作,开始音视频通话。



通话接听后,双方即开始进行音视频互动通信,具体实现逻辑详见 音视频通话

拒接

拒接信令可以细分为主动拒接、忙线拒接两个部分,其调用时序如下图所示:



主动拒接:被叫端收到呼叫邀请后拒绝邀请,同时销毁呼叫页面并停止铃声;主叫端收到拒绝通知,同时销毁呼叫页面并停止铃声。
忙线拒接:被叫端收到呼叫邀请后,本地判断正在通话中,则直接拒绝邀请;主叫端收到拒绝通知,同时销毁呼叫页面并停止铃声。
注意:
主动拒接和忙线拒接都是使用 reject 信令实现的,但需注意通过信令的自定义数据 data 字段加以区分。

挂断

在通话过程中,主叫和被叫任意一端均可随时选择挂断操作,结束音视频通话。



以主叫端挂断为例,主叫端执行退房操作,被叫端收到远端退房通知,同时执行退房操作,双方通话结束。
说明:
挂断操作没有使用到 IM 信令通知,而是使用 TRTC 远端用户退房回调通知实现。

音视频通话

音视频通话部分主要依赖 实时音视频 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 完成,下面逐项介绍其具体实现。

打开关闭麦克风

Android
iOS
// 打开麦克风
mTRTCCloud.muteLocalAudio(false);
// 关闭麦克风
mTRTCCloud.muteLocalAudio(true);
// 打开麦克风
[self.trtcCloud muteLocalAudio:NO];
// 关闭麦克风
[self.trtcCloud muteLocalAudio:YES];

打开关闭扬声器

Android
iOS
// 打开扬声器
mTRTCCloud.muteAllRemoteAudio(false);
// 关闭扬声器
mTRTCCloud.muteAllRemoteAudio(true);
// 打开扬声器
[self.trtcCloud muteAllRemoteAudio:NO];
// 关闭扬声器
[self.trtcCloud muteAllRemoteAudio:YES];

打开关闭摄像头

Android
iOS
// 打开摄像头, 指定前置或后置摄像头及渲染控件
mTRTCCloud.startLocalPreview(isFrontCamera, videoView);
// 关闭摄像头
mTRTCCloud.stopLocalPreview();
// 打开摄像头, 指定前置或后置摄像头及渲染控件
[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.videoView];
// 关闭摄像头
[self.trtcCloud stopLocalPreview];

听筒免提切换

Android
iOS
// 切换听筒
mTRTCCloud.getDeviceManager().setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteEarpiece);
// 切换免提
mTRTCCloud.getDeviceManager().setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteSpeakerphone);
// 切换听筒
[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];
// 切换免提
[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];

摄像头切换

Android
iOS
// 判断当前是否为前置摄像头
boolean isFrontCamera = mTRTCCloud.getDeviceManager().isFrontCamera();
// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置
mTRTCCloud.getDeviceManager().switchCamera(!isFrontCamera);
// 判断当前是否为前置摄像头
BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];
// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置
[[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];

大小窗口切换

Android
iOS
// 更新本地预览画面渲染控件
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];

网络状态提示

Android
iOS
@Override
public 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 远端用户进房时间作为统计通话时长的开始时间,本地用户退房时间作为统计通话时长的结束时间。
Android
iOS
// 开始通话时间
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 云端录制的具体介绍及开通指引详见 实现云端录制与回放
单流录制可以使用 全局自动录制,混流录制则需使用 API 手动录制

天御内容安全审核

TRTC 联合 T-Sec 天御,提供了实时的音视频内容识别与告警服务,使用实时音视频服务时,支持全局自动或手动发起策略进行音视频内容的识别和告警:
全局自动审核
客户可以指定审核策略和审核流类型,TRTC 云端自动完成应用下所有房间内的音视频内容审核,并通过回调把违规信息发送到客户指定的回调 URL,无需手动发起审核。该方式简单易用,省去了代码接入的工作量,但灵活性欠佳。
TRTC 与天御内容安全审核平台结合的实现原理如下图所示:直播内容安全通过“哑终端”的形式进入指定的 TRTC 房间,作为“观众”拉取音视频流,并针对拉取的音视频流进行内容审核,然后通过回调把违规信息发送到用户指定的 HTTP/HTTPS 服务上。



手动自定义审核
客户只需要调用天御音视频流接口即可实时检测音视频流中是否出现违规内容。音视频安全审核服务会通过回调把违规信息发送给客户指定的回调 URL。该方式更灵活、可定制化更强,但需要调用 REST API 发起审核任务,具有一定的接入复杂度。



说明:
全局自动审核接入指引详见 自动审核接入;手动审核接入指引详见 手动审核接入

视频美颜特效

视频通话场景中,美颜是一个被高频使用的功能。美颜不但能提升用户的颜值,也能通过一些贴纸特效增加通话互通的趣味性。TRTC 支持 腾讯美颜特效 的集成,同时也支持市面上主流第三方美颜产品的接入,例如火山美颜、相芯美颜等。

美颜接入流程





API 调用时序





美颜产品对比

美颜类型
美颜效果
接入成本
费用成本
虚拟数字人
支持终端
基础效果好,高级效果大眼/瘦脸等效果显著
较低
适中
支持
Android/iOS/PC/Flutter/Web/小程序
基础效果好,高级效果大眼/瘦脸等效果一般
较高
适中
支持
Android/iOS/PC/Untiy
基础效果好,高级效果大眼/瘦脸等效果较好
较高
偏高
支持
Android/iOS/PC/Linux

离线消息推送

音视频通话场景通常需要用到离线消息推送,被叫用户 App 不在线时也能收到新的来电消息。即时通信 IM 提供了两种集成方式:自集成推送推送插件。推送插件(TIMPush)为您提供稳定、及时、多样化的推送服务。相比自集成推送,推送插件只需进行简单配置,即可一键式集成接入多个厂商的推送服务。

步骤一:开通推送插件

进入 IM 控制台 > 插件市场,单击 立即购买 免费试用 。(每个应用可免费试用一次,有效期7天)




步骤二:集成推送插件

1. 注册应用到厂商推送平台
离线推送需要将您自己的应用注册到各个厂商的推送平台,得到 AppID 和 AppKey 等参数,用于实现离线推送功能。目前国内支持的手机厂商有:小米华为荣耀OPPOVIVO魅族,境外支持 Google FCM。iOS 需要向 Apple 申请 APNs 推送证书,详见 申请 APNs 证书
2. IM 控制台配置厂商推送证书
登录腾讯云 即时通信 IM 控制台,在推送管理 > 接入设置功能栏添加各个厂商推送证书,并将您在之前步骤获取到各厂商的 AppId、AppKey、AppSecret 等参数配置给添加的推送证书。iOS 配置方式详见 上传证书到控制台
小米
华为
OPPO
VIVO
魅族
荣耀
Google FCM
厂商推送平台



IM 控制台配置



厂商推送平台



IM 控制台配置



说明:
Client ID 对应 AppID,Client Secret 对应 AppSecret。

厂商推送平台



IM 控制台配置



厂商推送平台



IM 控制台配置



说明:
回执配置请参考 消息触达统计配置-vivo

厂商推送平台



IM 控制台配置



说明:
回执配置请参考 消息触达统计配置-魅族

厂商推送平台



IM 控制台配置



厂商推送平台



IM 控制台配置



3. 下载并添加配置文件
完成控制台厂商推送信息填写后,下载并添加配置文件到工程。将下载的 timpush-configs.json 文件添加到应用模块的 assets 目录下:
3.1 选择下载配置文件 timpush-configs.json



3.2 添加到工程



4. 集成 TIMPush 插件
Android
iOS
// 推送主包必须要集成
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 frameworks
use_frameworks!
use_modular_headers!
# Pods for Example
pod 'TIMPush', '7.7.5283'
end
执行以下命令,安装 TIMPush 组件。
pod install # 如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。 pod repo update

步骤三:使用离线消息推送

Android
iOS
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() {
@Override
public void onError(int code, String desc) {
// 发送邀请信令失败
}

@Override
public 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、加速分发播放、版权保护等一体化的高品质媒体服务。
安全服务
提供音频审核服务,自动识别音频中出现的可能令人反感、不安全或不适宜内容,支持自定义黑名单热词,识别自定义类型的音频内容。
安全服务
针对多种形式的视频文件/视频流进行多样化的场景检测和内容识别,精准识别视频中出现可能令人反感、不安全或不适宜内容。
数据存储
提供音视频录制文件、音视频切片文件的存储服务。