diff --git a/assets/css/components/calls/window.css b/assets/css/components/calls/window.css index 3cc330de..96599f03 100644 --- a/assets/css/components/calls/window.css +++ b/assets/css/components/calls/window.css @@ -53,4 +53,13 @@ .call-window .members-area span { margin: 0px 5px; +} + +.call-window .videos-area { + display: flex; + flex-direction: row; +} + +.call-window .videos-area video { + } \ No newline at end of file diff --git a/assets/js/components/calls/window.js b/assets/js/components/calls/window.js index 2aecdfc1..6dc01f82 100644 --- a/assets/js/components/calls/window.js +++ b/assets/js/components/calls/window.js @@ -14,8 +14,15 @@ class CallWindow extends CustomEvents { */ constructor(conv) { super() + + // Initialize variables this.conv = conv; this.callID = conv.ID; + + /** @type {Map} */ + this.videoEls = new Map() + + this.construct(conv); } @@ -68,6 +75,13 @@ class CallWindow extends CustomEvents { }) + // Create videos area + this.videosArea = createElem2({ + appendTo: this.rootEl, + type: "div", + class: "videos-area" + }) + // Join the call await ws("calls/join", { @@ -215,6 +229,15 @@ class CallWindow extends CustomEvents { if(el) el.remove() + + // Remove video (if any) + if(this.videoEls.has(userID)) { + const el = this.videoEls.get(userID); + this.videoEls.delete(userID) + + el.pause() + el.remove() + } } /** @@ -229,10 +252,20 @@ class CallWindow extends CustomEvents { /** * Add video stream to the user * - * + * @param {number} peerID Remove peer ID + * @param {boolean} muted True to mute video + * @param {MediaStream} stream Target stream */ - addVideoStream(video) { + addVideoStream(peerID, muted, stream) { + const videoEl = document.createElement("video"); + this.videosArea.appendChild(videoEl) + videoEl.muted = muted; + + videoEl.srcObject = stream + videoEl.play() + + this.videoEls.set(peerID, videoEl) } /** @@ -246,6 +279,9 @@ class CallWindow extends CustomEvents { audio: true }) + // Show user video + this.addVideoStream(userID(), true, stream) + this.mainPeer = new SimplePeer({ initiator: true, trickle: true, // Allow exchange of multiple ice candidates