融云 Web SDK 如何实现语音的收发 ?

Posted 融云RongCloud

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了融云 Web SDK 如何实现语音的收发 ?相关的知识,希望对你有一定的参考价值。

根据融云的开发文档, 总结得出, 融云 WebSDK 需要的是一个 aac 格式的音频 url, 不关注 url 如何生成. 生成 url 的步骤由开发者实现

文档: https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#HQVCMsg

所以关注点放在以下几个问题:

1、Web 端能否实现语音录制

2、结合融云 SDK 实现语音的发送

3、结合融云 SDK 实现语音的接收和播放

Web 端能否实现语音录制

答案是可以. 不过只有部分浏览器支持, 录制的音频格式有很多限制, 且只有当前站点为 localhost 或 https 时才可使用

录制原理: getUserMedia、MediaRecorder

使用 getUserMedia 获取音频流, 使用 MediaRecorder 录音获取音频数据

以下为录制 5s, 获取 File 对象的代码:

// 通过 getUserMedia 获取音频流
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
const mediaRecorder = new MediaRecorder(stream);
const chunks = [];
// 收集音频数据
mediaRecorder.ondataavailable = function (e) {
chunks.push(e.data);
};
// 监听音频录制停止
mediaRecorder.onstop = e => {
const blob = new Blob(chunks);
blob.lastModifiedDate = new Date();
const file = new File([blob], \'audio_file.aac\', { type: "audio/aac" }); // 获取到 File 对象, 可将此对象上传至服务器, 获取音频 url
};
mediaRecorder.start(); // 开始录音. 此处自动开始, 读者可按产品逻辑点击某个按钮触发录音
setTimeout(function () { // 5s 倒计时自动停止录音. 读者可按产品逻辑设置停止时机
mediaRecorder.stop();
}, 5000)
});

获取到 file 对象后, 可将 file 上传至服务器, 获取音频的远端 url

经过测试, 发现录制的音频只能在集成了融云的 android 端播放, ios 端无法播放

经过搜集资料, 发现 MediaRecorder 录音的编码是有限制的, 默认是 webm 格式, 而融云支持播放的是 aac 格式

JS 官方文档也没有给出 MediaRecorder 具体支持的格式, 因为各个浏览器实现的编码都不同, 且就算编码格式支持, 也有可能因为计算资源不足而导致编码失败

官网提供以下代码检测支持状况:

var types = ["video/webm",
"audio/webm",
"video/webm;codecs=vp8",
"video/webm;codecs=daala",
"video/webm;codecs=h264",
"audio/webm;codecs=opus",
"video/mpeg"];

for (var i in types) {
console.log( "Is " + types[i] + " supported? " + (MediaRecorder.isTypeSupported(types[i]) ? "Maybe!" : "Nope :("));
// 重点 API: MediaRecorder.isTypeSupported
}

经过一系列调研, 总结以下几点:

1、需要注意浏览器兼容问题 getUserMedia、MediaRecorder

2、录制上传后的音频为 webm 格式. 融云 iOS 暂不支持播放. 读者可以尝试在录音时将录音数据编码由 webm 转化为 aac 格式. 也可以将数据传给服务端, 由服务端转换格式

3、要注意 getUserMedia 的安全限制. 要求访问站点必须为 localhosthttps

结合融云 SDK 实现语音的发送

根据文章前的描述. 获取到远端音频 url 后, 调用融云的发送消息方法就可以了

注意: 记得先 初始化、连接 融云 SDK

var conversation = im.Conversation.get({
targetId: \'接收方的 userId\',
type: RongIMLib.CONVERSATION_TYPE.PRIVATE
});
conversation.send({
messageType: RongIMLib.MESSAGE_TYPE.HQ_VOICE, // \'RC:HQVCMsg\'
content: {
remoteUrl: \'https://rongcloud-audio.cn.ro...:CDngyWj7ZApNmAfoecng7L_3SaU=\', // 音频 url, 建议格式: aac
duration: 6, // 音频时长
type: \'aac\'
}
}).then(function(message){
console.log(\'发送语音消息成功\', message);
});

结合融云 SDK 实现语音的接收和播放

发送: 依照融云文档设置消息监听即可

var im = RongIMLib.init({ appkey: \'\' }); // 建议全局只初始化一次
var conversationList = []; // 当前已存在的会话列表
im.watch({
message: function(event){
var message = event.message;
console.log(\'有人给我发消息啦: \', message);
}
});

播放: 融云发送的音频默认格式为 aac 格式. Web 端使用 audio 标签直接播放即可

播放时遇到的坑:

Web 收到的消息不是 aac 格式, 而是 amr 格式:

测试时发现 Android 发送的语音消息是 RC:VcMsg, 而不是 RC:HQVCMsg

查看文档, 发现 RC:VcMsg 是融云旧语音消息, RC:HQVCMsg 是新语音消息. 但是融云移动端 IMKit 默认发送还是旧语音消息

根据文档提供的切换接口, 将 Android 发送语音改为 RC:HQVCMsg, 此问题成功解决了

切换文档: https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/android.html#voice

以上是关于融云 Web SDK 如何实现语音的收发 ?的主要内容,如果未能解决你的问题,请参考以下文章

融云 Web SDK 如何实现只有一个设备登入

iOS - 语音云通讯

如何隐藏融云输入框语音按钮

融云 Web SDK 删除历史消息

如何基于 ZEGO SDK 实现 Web 基本消息收发

使用融云 Web SDK 撤回消息