Vue、WebRTC、SocketIO、Node和Redis助力多人视频会议(中)

现在,我们已经找到创建所有RTCPeerConnection之外步骤的通用方法了,接下来就需要适当的组件提供和处理PeerConnection对象和过程中所需信息(远程描述、候选人、请求、回复等等)了。

详见使用 mixins 时所有的合并策略

视频通话和相关控制

考虑到视频相关的情况,我们创建了一个通用的Video.vue组件让视频变得更简单。


<template>

<div class="video">

<div class="video__spinner">

<md-progress-spinner

v-if="!videoStream"

class="md-accent"

md-mode="indeterminate">

</md-progress-spinner>

</div>

<AudioVideoControls

v-if="displayControls"

:pauseVideo="pauseVideo"

:pauseAudio="pauseAudio">

</AudioVideoControls>

<video :id="videoId" autoplay="true"> </video>

</div>

</template>

<script>

export default {

name: "Video",

components: { AudioVideoControls },

props: {

videoId: String,

displayControls: Boolean,

videoStream: MediaStream,

pauseVideo: Function,

pauseAudio: Function,

}

}

</script>

(视频组件)

不管是哪种情况,组件都会获取合适的媒体流以及输入值的剩余部分。

pauseVideo和pauseAudio是通用的mixin媒体方法。

此外,我们还添加了视频音频控制(AudioVideControls.vue),这样,每一端都可以分别暂停/恢复或关闭/开启自己的视频和音频,具体操作如下。


// Pause video

this.ls.getVideoTracks().forEach(t => t.enabled = !t.enabled)

// Pause audio

this.ls.getAudioTracks().forEach(t => t.enabled = !t.enabled)

这并不意味着你每次都要重启webRTC连接,你只需启用/禁用音频/视频本地流轨道就可以了。

音频

在我们之前发布的版本中,音频问题较突出。所以这次我们在请求用户媒体时的普通配置中设置约束,从而解决了反馈的问题。


constraints: {

audio: {

echoCancellation: true,

noiseSuppression: true,

autoGainControl: false

}

}

MediaTrack API中可查看所有可用的约束条件。

但这还不够。为了消除回声和噪音,我们还需要将本地视频元素的音量静音并设置为0,如下所示:


// Local video

<video id="localVideo" autoplay="true" muted> </video>

// Fix volume to 0

this.myVideo.volume = 0

注:这个操作只静音了本地播放,并不意味着你把正在运行的音频流也静音了。

WebRTC 适配器

为了处理可能会出现的浏览器问题,我们引入了WebRTC适配器,把代码和不同的WebRTC浏览器实现连接起来。


import adapter from ‘webrtc-adapter’

console.log(`Browser ${adapter.browserDetails.browser} — version ${adapter.browserDetails.version}`)

用户信息

如上所述,用户无法一边私聊一边参加会议。所以我们在用户进入房间时,就在Redis中存储的对象中添加了一个会议标志(joinRoom web socket服务器监听器),来监测用户状态。


try {

// add user to the suitable ROOM

await ChatRedis.addUser(room, userName, { username, status,

privateChat: false,

conference: false

})

const users = await ChatRedis.getUsers(room)

// Notify all the users in the same room

namespace.in(room).emit(‘newUser’, { users, username })

} catch (error) {

console.log(error)

}

注:我们更改了redis hash模式中的密钥(从socketId 变成了userName),这使得从web socket连接中获取用户信息更方便了。

会议

某一用户发起会议,会议开始,该用户成为该房间管理员。当开启app时,管理员会自动加入由自己用户名定义的会议室。

注:每个用户名在系统中都是唯一不重复的,所以每个web socket会议室都是独一无二的。

为做到这一点,我们开发了一个新的 joinConference 服务器监听器。

文章地址:https://levelup.gitconnected.com/multiparty-video-conference-using-vue-webrtc-socketio-node-redis-e8c5a059d332

原文作者:Adrián García Diéguez