可能有些同学并不知道 RTC 的相关概念, 这里先简单说一下。
WebRTC(web Real-Time Communication) 是指网站实时音视频通话技术。
这项技术允许网络应用或者网络站点,在不借助任何中间媒介和第三方工具的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和音频流或者其他任意数据的传输,感兴趣的小伙伴可以自行搜索了解下。
TRTC (Tencent Real-Time Communication)是腾讯业务中的一项,也是 WebRTC的一种实现。
TRTC 主要提供了两个场景
那么与其他的 WebRTC 相比,TRTC 具有哪些优点呢?
首先需要登录腾讯云 TRTC,点击链接微信扫码注册即可,然后按照相关法律法规要求,进行实名认证,这里就不过多赘述了。
实名认证后,进入应用管理,创建自己的应用。
TRTC 以项目的方式进行接口管理,每一个创建成功的项目,都会被分配携带一个 SDKAppID
和 SecretKey
。其中
⚠️ 请不要泄漏你的SecretKey
,否则可能造成流量盗用
完成上面的步骤以后,就可以进入到第三步了。
src/utils/generateTestUserSig.ts
文件中的SDKAPPID
和SECRETKEY
替换为上面创建好的项目的SDKAppID
和 SecretKey
。npm start
就可以看到效果了。当然了,到这一步只能算万里长征的第一步。后面我们还需要针对性的理解几个概念。
在理解实际的直播场景之前,我们需要先理解如下几个概念:
name | desc | functional |
---|---|---|
Client | 音视频通话客户端对象 | 进入通话房间、发布本地数据流、订阅远端数据流 |
Stream | 数据流(音频、视频) | 播放、暂停 |
LocalStream | 本地数据流 | TRTC.createStream() 创建 |
RemoteStream | 远端数据流 | Client.on(‘stream-added’)获取 |
roomId | 房间标识(唯一) | - |
role | 用户标识(唯一) | - |
userSig | 进房鉴权票据 | - |
有些童鞋被本地数据流和远端数据流的概念困扰,这里简单说一下,本地数据流可以理解为自己的声音和图像,远端数据流就是房间中其他人的声音和图像。
userSig 是比较特殊的一项,因为它是通过计算得到的加密数据。
每个用户在进入房间都需要验证 userSig,就好比你进入电影院看电影要买电影票一样,本质上,它是一种安全保护签名,目的是为了阻止恶意攻击者盗用云服务使用权。
userSig 由 HMAC SHA256 加密算法基于SDKAppID
和UserID
等数据计算得出,其计算的基本方式是
hmacsha256(
secretkey,
(userid + sdkappid + currtime + expire +
base64(userid + sdkappid + currtime + expire)))
这个加密还是很复杂的,但是放在前端依旧不安全,在真实的线上环境, UserSig 的计算代码应该放在业务服务器上,然后由 App 在需要的时候向服务器获取实时算出的 UserSig
更多内容在这里
有了上面的概念支持,我们大概就知道视频房间是什么样子的。接下来看一下 client
生命周期。
从生命周期图中可以看出来,TRTC 的设计是非常简洁的,从创建房间到加入、离开只需要调用几个固定的方法,这些方法都可以在这里找到,感兴趣的话可以点开看详细的内容。
为了演示方便,我直接在 demo 项目中动手了,需求就是创建一个直播间。
在router 中加入一个新的路由
{
path: '/myroom',
name: 'myroom',
component: () => import('../views/video/myroom.vue'),
},
然后在myroom.vue
中写入如下代码
<template>
<div id="local"></div>
</template>
<script lang="ts" setup>
import TRTC from 'trtc-js-sdk';
import { genTestUserSig } from '@/utils/generateTestUserSig';
import { getParamKey } from '@/utils/utils';
const userId = getParamKey('userId');
const { sdkAppId, userSig } = genTestUserSig({ sdkAppId: 0, userId, secretKey: '' });
const Client = TRTC.createClient({
mode: 'rtc',
sdkAppId,
userId,
userSig,
});
Client
.join({
roomId: 111,
role: 'anchor',
})
.then(async () => {
console.log('进房成功');
})
.catch((error) => {
console.error(`进房失败,请稍后再试${error}`);
});
</script>
访问页面和控制台,已经能够看到控制台打印出了进房成功
但是页面并没有呈现任何内容,这是因为此时我们还没有对本地的数据流进行采集、播放。加入如下代码
...
.then(async () => {
console.log('进房成功');
const localStream = TRTC.createStream({
userId,
audio: true,
video: true,
cameraId: (await TRTC.getCameras())[0].deviceId,
microphoneId: (await TRTC.getMicrophones())[0].deviceId,
});
localStream.setVideoProfile('480p');
await localStream.initialize();
localStream.play('local');
await Client.publish(localStream);
})
...
这里已经对本地的数据流进行了采集和播放,并指定了摄像头和麦克风,页面此时可以看到自己了,当然,为了不影响你们的学习兴趣,我自己马赛克了
在router 中变更路由
...
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'custom',
component: () => import('../views/video/index.vue'),
},
{
path: '/room/:id',
name: 'home',
component: Index,
},
{
path: '/myroom',
name: 'myroom',
component: () => import('../views/video/myroom.vue'),
},
{
path: '/invite',
name: 'invite',
component: () => import('../views/Invite.vue'),
},
];
...
我们在/video/index.vue
中创建多个用户,并将每个用户的房间号设置为同样的111
在点击进入按钮的事件里,调用
const handlejoin = (o: List) => {
store.$patch({
sdkAppId: getParamKey('sdkAppId'),
secretKey: getParamKey('secretKey'),
userId: getParamKey('userId'),
roomId: `${o.id}`,
});
const { id } = o;
router.push(`/room/${id}`);
};
由于每次进入的房间号是一样的,所以所有用户都会进入同一个房间。然后点击离开,当前用户就会脱离房间了。
最后,代码放在github了。