WebRTC 通话的挂起与恢复

作者:追风剑情 发布于:2024-2-19 10:55 分类:Unity3d

  通话挂起是指在通话过程中一方临时暂停对话,并通过友好的方式提示对方进行等待; 通话恢复是指由通话挂起恢复正常通话。

  这两项技术经常用于电话客服或者电话转接的场景,比如当电话客服需要时间进行某项操作时,会提示客户进行等待,而为了让客户保持耐心,在等待期间会播放一段轻松的音乐。

  将 RTCRtpTransceiver.direction 属性和 RTCRtpSender.replaceTrack() 方法相结合,可以实现通话挂起与恢复功能。

通话挂起

  我们来设想一个场景,一位客户正在与客服通话,客户提出了一项业务请求,客服表示可以满足但是需要一段时间处理,此时客服将通话挂起,提示客户进行等待。

  客服方将从话简采集到的语音替换为一段音乐,并停止播放从客户端发送过来的语音,将收发器的方向设置为只发送(sendonly)。

  通过本章对RTP媒体API的介绍,我们已经知道,调用replaceTrack替换媒体轨道不需要进行重新协商,而对收发器方向的修改则需要重新进行ICE协商,在doOffer流程中生成了本地提案,并通过信令服务器发送给客户方。客服端代码逻辑如下所示。

async function playMusicOnHold() {
	try {
		// audio是RTP收发器,musicTrack是播放音乐的音频轨道
		await audio.sender.replaceTrack(musicTrack);
		// 使接收到的音频静音
		audio.receiver.track.enabled = false;
		// 将direction设为只发送(sendonly),此时需要重新协商
		audio.direction = 'sendonly';
		// 生成提案并发送给对等方
		await doOffer();
	} catch (err) {
		console.error(err);
	}
}

  客户方也会进行相应处理,按照业务逻辑,客户方此时不应再发送语音数据,同时应该能够收听到等待音乐。

  当客户方接收到客服方通过信令服务器传输过来的包含了sendonly的提案后,首先调用setRemoteDescription应用提案,然后调用replaceTrack()方法传人参数null移除音轨这会导致停止发送音频数据。

  客户方相应地将direction调整为只接收(recvonly),与客服方的sendonly 保持一致这避免了方向不一致导致反复协商。最后在doAnswer中生成自己的会话描述信息并发送给客服方,完成重新协商的过程。

async function handleSendonlyOffer() {
	try {
		// 首先应用sendonly提案
		await pc.setRemoteDescription(sendonlyOffer);
		// 停止发送音频
		await audio.sender.replaceTrack(null);
		// 相应地将direction调整为只接收
		audio.direction = 'recvonly';
		// 回应提案
		await doAnswer();
	} catch (err) {
		// 错误处理
	}
}

通话恢复

  客服办理完业务,停止挂起状态,恢复通话,代码逻辑如代码清单所示。首先使用从话筒采集到的音频轨道替换挂起状态播放的音乐,这个步骤可以马上生效,不需要进行重新协商。然后取消接收音频静音,这样就可以听到客户那边的语音了。将direction改为收发(sendrecv),这一步需要进行重新协商,在doOffer流程中生成了本地提案,并通过信令服务器发送给客户方。

async function stopOnHoldMusic() {
	// audio是RTP收发器,micTrack是从话简采集的音频轨道
	await audio.sender.replaceTrack(micTrack);
	// 取消接收音频静音
	audio.receiver.track.enabled = true;
	// 将方向设为收发(sendrecv)
	audio.direction = 'sendrecv';
	// 生成提案并发送给对等方
	await doOffer();
}

  客户方的音乐播放停止了,而且应该能够听到客服的语音信息,但是因为收发器方向 还是只接收的状态,所以无法对话。

  如下面的代码清单所示,对客服方取消挂起操作进行回应,客户方收到了从信令服务器发送过来的提案SDP信息,调用setRemoteDescription()方法进行设置,随后使用replaceTrack加入话简音频轨道并将接收器方向改为收发(sendrecv),最后在doAnswer 流程中生成自己的会话描述信息并发送给客服方,完成ICE重新协商过程。至此,客户方可以正常发送自己的语音了,双方通话恢复正常。

async function onOffHold() {
	try {
		// 首先应用sendrecv提案
		await pc.setRemoteDescription(sendrecvOffer);
		// 开始发送话简音轨
		await audio.sender.replaceTrack(micTrack);
		// 将收发方向设为sendrecv
		audio.direction = 'sendrecv';
		// 生成本地SDP应答,回复给对方
		await doAnswer();
	} catch (err) {
		// 错误处理
	}
}

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号