I'm using Twilio video JS SDK with inline Vue 2 for a group video conference app and I'm having an issue with losing audio/video tracks attached to participant components, when one participant disconnects.
Take a room with 4 participants, all have audio and video tracks attached. Now when participant #2 disconnects, the tracks of participant #3 and #4 stop playing (video is stuck, audio not playing anymore).
It's probably caused by re-rendering - when participant disconnects, he is deleted from state.participants and all folowing participants have to re-render - they still have the and elements, just not playing the previously attached tracks.
I've temporarily solved this by keeping all the disconnected participants in the state, and just visually hiding them with v-show="item.connected"
, but I'm planning to add other functionality like pinning, and would generally like to keep my options open with being able to re-render the participant boxes without losing the attached video/audio tracks.
I've looked at some Twilio-video + Vue examples, but all were 1-on-1 rooms, where the track containers were always in place and not moving around. Does anyone know how to tackle this kind of situation in a manner, that uses the reactive DOM principles, instead of trying to bypass them?
Here's HTML
<div class="attendants-window">
<template v-for="item in participants" :key="item.identity">
<div class="twilio-attendant-col" v-show="item.connected">
<div class="twilio-attendant">
<div v-if="!item.video || !videoEnabled" class="twilio-avatar">{{ item.name }}</div>
<div v-show="item.video || !videoEnabled" class="twilio-video" :ref="'media' + item.identity">
// <video> and <audio> are attached here
</div>
<div class="twilio-attendant-controls">
<button @click="onToggleAudio(item.identity)" class="btn">
<i v-if="item.audio" class="fa fa-microphone"></i>
<i v-else class="fa fa-microphone-slash"></i>
</button>
<button v-if="videoEnabled" @click="onToggleVideo(item.identity)" class="btn">
<i class="fa fa-camera position-relative">
<div v-if="!item.video" class="icon-slash"></div>
</i>
</button>
<button @click="onTogglePinned(item.identity)" class="btn">
<i class="fa fa-thumb-tack"></i>
</button>
</div>
</div>
</div>
</template>
</div>
And here's the vue method that attaches the tracks
attachMedia(id, track) {
this.callUsers[id][track.kind] = true
$(this.$refs['media' + id]).append(track.attach())
},