发布和订阅
上一步我们已经介绍了基本的采集媒体流的方法,下面就可以开始发布和订阅的流程了。发布和订阅都属于房间内的操作,所以请先确保调用代码之前已经加入了房间。
发布
这里我们假定您已经加入了房间,并通过采集媒体流获取了本地流对象 stream
, 使用 publish 来发布媒体流
try {
await myRTC.publish(stream); // myRTC 为加入房间后的 QNRTCSession 实例
} catch(e) {
console.log('publish Error!', e);
}
// or use Promise
myRTC.publish(stream))
.then(() => {
console.log('publish success');
}).catch(e => {
console.log('publish Error!', e);
});
订阅
订阅相比发布会复杂很多,发布只需要加入房间采集到媒体流就可以调用了,但是订阅必须在满足一定外部条件的情况下才能调用:
- 获取订阅目标的用户名 userId
- 订阅目标必须已经发布了自己的媒体流
为了能实时地判断何时可以发起订阅,我们需要时刻监听房间内所有用户状态的变化(用户加入/离开,用户发布/取消发布)。具体推荐的方法见下。
当调用了加入房间的方法之后,我们立刻获得这个房间内已有用户的信息,其中 published
字段代表这个用户是否已经发布了媒体流,此时如果有除自己以外的用户已经发布的话,就满足了订阅条件可以发起订阅了。之后我们再通过事件监听获取之后发生的用户加入/用户发布事件,当满足订阅条件时发起订阅,这样我们就能全局地感知整个房间的用户状态变化了。
这里需要用到 2 个 API,subscribe 用来订阅其他用户发布的媒体流,事件监听 用来通过事件回调同步房间各种状态的变化,事件列表见此。
// myRTC 为加入房间后的 QNRTCSession 实例
// user 代表加入房间返回或者事件返回的单个用户对象
function subscribeUser(myRTC, user) {
// 如果用户没有发布就直接返回
if (!user.published) {
return;
}
// 根据需要选择是使用 Promise 还是 async/await
myRTC.subscribe(user.userId).then(remoteStream => {
// 我们在页面上准备用来显示远端媒体流的元素
const remotePlayer = document.getElementById('remoteplayer');
// 在我们准备的元素上播放远端媒体流
remoteStream.play(remotePlayer);
}).catch(e => {
console.log('subscribe error!', e);
});
}
以上展示了订阅 API 的基本使用方法,下面是配合事件监听和房间用户完成的自动订阅逻辑
// 加入房间
const users = await myRTC.joinRoomWithToken(roomToken);
console.log('joinRoom success! 当前房间用户:', users);
// 监听房间里的用户发布事件,一旦有用户发布,就订阅他
myRTC.on('user-publish', user => {
subscribeUser(myRTC, user);
});
// 判断房间当前的用户是否有可以订阅的
for (let i = 0; i < users.length; i += 1) {
const user = users[i];
// 如果当前房间的用户不是自己并且已经发布
// 那就订阅他
if (user.published && user.userId !== myRTC.userId) {
subscribeUser(myRTC, user);
}
}