[mirotalksfu] - improve Video grid view and UI
هذا الالتزام موجود في:
151
public/Room.html
151
public/Room.html
@@ -34,6 +34,7 @@
|
|||||||
<!-- StyleSheet -->
|
<!-- StyleSheet -->
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/Room.css" />
|
<link rel="stylesheet" href="/css/Room.css" />
|
||||||
|
<link rel="stylesheet" href="/css/VideoGrid.css" />
|
||||||
|
|
||||||
<!-- https://animate.style 4 using for swal fadeIn-Out -->
|
<!-- https://animate.style 4 using for swal fadeIn-Out -->
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
<script src="/modules/MediasoupClient.js"></script>
|
<script src="/modules/MediasoupClient.js"></script>
|
||||||
<script src="/js/Room.js"></script>
|
<script src="/js/Room.js"></script>
|
||||||
<script src="/js/RoomClient.js"></script>
|
<script src="/js/RoomClient.js"></script>
|
||||||
|
<script src="/js/VideoGrid.js"></script>
|
||||||
<script src="https://kit.fontawesome.com/d2f1016e6f.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/d2f1016e6f.js" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.rawgit.com/muaz-khan/DetectRTC/master/DetectRTC.js"></script>
|
<script src="https://cdn.rawgit.com/muaz-khan/DetectRTC/master/DetectRTC.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
|
||||||
@@ -71,107 +73,68 @@
|
|||||||
</head>
|
</head>
|
||||||
<body onload="initClient()">
|
<body onload="initClient()">
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div class="container-xxl">
|
|
||||||
<div id="control" class="fadein hidden">
|
<div id="loadingDiv" class="center pulsate">
|
||||||
<button id="exitButton" class="hidden">
|
<h1>Loading...</h1>
|
||||||
<i class="fas fa-arrow-left"></i>
|
<pre>
|
||||||
</button>
|
Please allow the camera or microphone
|
||||||
<button id="shareButton" class="hidden">
|
access to use this app.
|
||||||
<i class="fas fa-share-alt"></i>
|
</pre>
|
||||||
</button>
|
</div>
|
||||||
<div class="dropdown">
|
|
||||||
<button id="devicesButton" class="hidden">
|
<button id="openNavButton" class="hidden">☰ open</button>
|
||||||
<i class="fas fa-cogs"></i>
|
<div id="control" class="sidenav hidden">
|
||||||
</button>
|
<button id="closeNavButton" class="closebtn">×</button>
|
||||||
<div id="myDevices" class="dropdown-content fadein">
|
<button id="shareButton" class="hidden"><i class="fas fa-share-alt"></i> Share</button>
|
||||||
<div id="devicesList">
|
<div class="dropdown">
|
||||||
<br />
|
<button id="settingsButton" class="hidden"><i class="fas fa-cogs"></i> Settings</button>
|
||||||
<i class="fas fa-video"></i> Video:
|
<div id="settings" class="dropdown-content fadein">
|
||||||
<select id="videoSelect" class="form-select text-light bg-dark"></select>
|
<div id="devicesList">
|
||||||
<br />
|
<i class="fas fa-video"></i> Video
|
||||||
<i class="fas fa-microphone"></i> Microphone:
|
<select id="videoSelect" class="form-select text-light bg-dark"></select>
|
||||||
<select id="microphoneSelect" class="form-select text-light bg-dark"></select>
|
<br />
|
||||||
<br />
|
<i class="fas fa-microphone"></i> Microphone
|
||||||
<i class="fas fa-volume-up"></i> Speaker:
|
<select id="microphoneSelect" class="form-select text-light bg-dark"></select>
|
||||||
<select id="speakerSelect" class="form-select text-light bg-dark"></select>
|
<br />
|
||||||
</div>
|
<i class="fas fa-volume-up"></i> Speaker
|
||||||
|
<select id="speakerSelect" class="form-select text-light bg-dark"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown">
|
</div>
|
||||||
<button id="recButton" class="hidden">
|
<div class="dropdown">
|
||||||
<i class="fas fa-record-vinyl"></i>
|
<button id="recButton" class="hidden"><i class="fas fa-record-vinyl"></i> Recording</button>
|
||||||
</button>
|
<div id="recording" class="dropdown-content fadein">
|
||||||
<div id="recording" class="dropdown-content fadein">
|
<div id="recordingCommand" class="recording">
|
||||||
<div id="recordingCommand" class="recording">
|
<button id="startRecButton" class="hidden"><i class="fas fa-record-vinyl"></i> Start</button>
|
||||||
<br />
|
<button id="stopRecButton" class="hidden"><i class="fas fa-stop-circle"></i> Stop</button>
|
||||||
<button id="startRecButton" class="hidden">
|
<button id="pauseRecButton" class="hidden"><i class="far fa-pause-circle"></i> Pause</button>
|
||||||
<i class="fas fa-record-vinyl"></i>
|
<button id="resumeRecButton" class="hidden"><i class="far fa-play-circle"></i> Resume</button>
|
||||||
</button>
|
<p id="recordingStatus">🔴 REC 0s</p>
|
||||||
<button id="stopRecButton" class="hidden">
|
|
||||||
<i class="fas fa-stop-circle"></i>
|
|
||||||
</button>
|
|
||||||
<button id="pauseRecButton" class="hidden">
|
|
||||||
<i class="far fa-pause-circle"></i>
|
|
||||||
</button>
|
|
||||||
<button id="resumeRecButton" class="hidden">
|
|
||||||
<i class="far fa-play-circle"></i>
|
|
||||||
</button>
|
|
||||||
<p id="recordingStatus">🔴 REC 0s</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button id="chatButton" class="hidden">
|
|
||||||
<i class="fas fa-comments"></i>
|
|
||||||
</button>
|
|
||||||
<button id="fullScreenButton" class="hidden">
|
|
||||||
<i class="fas fa-expand-alt"></i>
|
|
||||||
</button>
|
|
||||||
<button id="swapCameraButton" class="hidden">
|
|
||||||
<i class="fas fa-sync-alt"></i>
|
|
||||||
</button>
|
|
||||||
<button id="startAudioButton" class="hidden">
|
|
||||||
<i class="fas fa-microphone-slash"></i>
|
|
||||||
</button>
|
|
||||||
<button id="stopAudioButton" class="hidden">
|
|
||||||
<i class="fas fa-microphone"></i>
|
|
||||||
</button>
|
|
||||||
<button id="startVideoButton" class="hidden">
|
|
||||||
<i class="fas fa-video-slash"></i>
|
|
||||||
</button>
|
|
||||||
<button id="stopVideoButton" class="hidden">
|
|
||||||
<i class="fas fa-video"></i>
|
|
||||||
</button>
|
|
||||||
<button id="startScreenButton" class="hidden">
|
|
||||||
<i class="fas fa-desktop"></i>
|
|
||||||
</button>
|
|
||||||
<button id="stopScreenButton" class="hidden">
|
|
||||||
<i class="fas fa-stop-circle"></i>
|
|
||||||
</button>
|
|
||||||
<button id="participantsButton" class="hidden">
|
|
||||||
<i class="fas fa-users"></i>
|
|
||||||
</button>
|
|
||||||
<button id="lockRoomButton" class="hidden">
|
|
||||||
<i class="fas fa-lock-open"></i>
|
|
||||||
</button>
|
|
||||||
<button id="unlockRoomButton" class="hidden">
|
|
||||||
<i class="fas fa-lock"></i>
|
|
||||||
</button>
|
|
||||||
<button id="aboutButton" class="hidden">
|
|
||||||
<i class="fas fa-question"></i>
|
|
||||||
</button>
|
|
||||||
<p id="sessionTime"></p>
|
|
||||||
</div>
|
</div>
|
||||||
|
<button id="chatButton" class="hidden"><i class="fas fa-comments"></i> Chat</button>
|
||||||
|
<button id="fullScreenButton" class="hidden"><i class="fas fa-expand-alt"></i> Full screen</button>
|
||||||
|
<button id="swapCameraButton" class="hidden"><i class="fas fa-sync-alt"></i> Swap Cam</button>
|
||||||
|
<button id="startAudioButton" class="hidden"><i class="fas fa-microphone-slash"></i> Start audio</button>
|
||||||
|
<button id="stopAudioButton" class="hidden"><i class="fas fa-microphone"></i> Stop audio</button>
|
||||||
|
<button id="startVideoButton" class="hidden"><i class="fas fa-video-slash"></i> Start video</button>
|
||||||
|
<button id="stopVideoButton" class="hidden"><i class="fas fa-video"></i> Stop video</button>
|
||||||
|
<button id="startScreenButton" class="hidden"><i class="fas fa-desktop"></i> Start screen</button>
|
||||||
|
<button id="stopScreenButton" class="hidden"><i class="fas fa-stop-circle"></i> Stop screen</button>
|
||||||
|
<button id="participantsButton" class="hidden"><i class="fas fa-users"></i> Participants</button>
|
||||||
|
<button id="lockRoomButton" class="hidden"><i class="fas fa-lock-open"></i> Lock room</button>
|
||||||
|
<button id="unlockRoomButton" class="hidden"><i class="fas fa-lock"></i> Unlock room</button>
|
||||||
|
<button id="aboutButton" class="hidden"><i class="fas fa-question"></i> About</button>
|
||||||
|
<button id="exitButton" class="hidden"><i class="fas fa-phone-slash"></i> Leave</button>
|
||||||
|
<button id="sessionTime" class="far fa-clock"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="container-xxl">
|
|
||||||
<div id="videoMedia" class="hidden">
|
<div id="videoMediaContainer">
|
||||||
<div id="localMedia" class="containers">
|
<!-- <div class="Camera"></div> -->
|
||||||
<!--<video id="localVideo" autoplay inline class="vid mirror"></video>-->
|
|
||||||
<!--<video id="localScreen" autoplay inline class="vid"></video>-->
|
|
||||||
</div>
|
|
||||||
<div id="remoteVideos" class="containers"></div>
|
|
||||||
<div id="remoteAudios"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="remoteAudios"></div>
|
||||||
|
|
||||||
<section id="chatRoom" class="chat-room center fadein">
|
<section id="chatRoom" class="chat-room center fadein">
|
||||||
<section id="msger" class="msger">
|
<section id="msger" class="msger">
|
||||||
<header id="chatHeader" class="chat-header">
|
<header id="chatHeader" class="chat-header">
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Comfortaa:wght@500&display=swap');
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
# Keyframes
|
# Keyframes
|
||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
@@ -30,11 +32,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--body-bg: linear-gradient(to left, #1f1e1e, #000000);
|
||||||
--msger-top: 50%;
|
--msger-top: 50%;
|
||||||
--msger-left: 50%;
|
--msger-left: 50%;
|
||||||
--msger-height: 680px;
|
--msger-height: 680px;
|
||||||
--msger-width: 420px;
|
--msger-width: 420px;
|
||||||
--msger-bg: linear-gradient(to left, #383838, #000000);
|
--msger-bg: linear-gradient(to left, #1f1e1e, #000000);
|
||||||
--left-msg-bg: #222328;
|
--left-msg-bg: #222328;
|
||||||
--right-msg-bg: #0a0b0c;
|
--right-msg-bg: #0a0b0c;
|
||||||
--box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
--box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||||
@@ -42,7 +45,7 @@
|
|||||||
|
|
||||||
* {
|
* {
|
||||||
outline: none;
|
outline: none;
|
||||||
font-family: 'Verdana';
|
font-family: 'Comfortaa';
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@@ -50,37 +53,113 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-image: url('../images/background.jpg');
|
background: var(--body-bg);
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
# Control buttons
|
# Loading...
|
||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#loadingDiv {
|
||||||
|
color: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--body-bg);
|
||||||
|
}
|
||||||
|
#loadingDiv h1 {
|
||||||
|
font-size: 70px;
|
||||||
|
}
|
||||||
|
#loadingDiv pre {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------
|
||||||
|
# Buttons bar
|
||||||
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#openNavButton {
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav {
|
||||||
|
z-index: 3;
|
||||||
|
height: 100%;
|
||||||
|
width: 0;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
overflow-x: hidden;
|
||||||
|
transition: 0.5s;
|
||||||
|
padding-top: 60px;
|
||||||
|
animation: show 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav button {
|
||||||
|
padding: 8px 8px 8px 32px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 20px;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav button:hover {
|
||||||
|
color: rgb(0, 180, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav .closebtn {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 25px;
|
||||||
|
font-size: 36px;
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidenav::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
.sidenav::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.sidenav::-webkit-scrollbar-thumb {
|
||||||
|
background: rgb(255 255 255 / 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-height: 450px) {
|
||||||
|
.sidenav {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.sidenav button {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#control {
|
#control {
|
||||||
z-index: 1;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 250px;
|
||||||
background: black;
|
background: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#control button {
|
#control button {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
#control p {
|
|
||||||
font-size: small;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
#exitButton:hover {
|
#exitButton:hover {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settings {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
# Room QR
|
# Room QR
|
||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
@@ -91,100 +170,6 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
|
||||||
# Video grid
|
|
||||||
--------------------------------------------------------------*/
|
|
||||||
|
|
||||||
.containers {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
column-gap: 10px;
|
|
||||||
row-gap: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 720px) {
|
|
||||||
.containers {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
column-gap: 10px;
|
|
||||||
row-gap: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.vid {
|
|
||||||
flex: 0 1 auto;
|
|
||||||
height: 360px;
|
|
||||||
border-radius: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
video {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
box-shadow: var(--box-shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
video:hover {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
video:fullscreen {
|
|
||||||
object-fit: contain; /* cover; */
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mirror {
|
|
||||||
-webkit-transform: rotateY(180deg);
|
|
||||||
-moz-transform: rotateY(180deg);
|
|
||||||
transform: rotateY(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#videoMedia {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#localMedia,
|
|
||||||
#remoteVideos {
|
|
||||||
margin: 10px;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pn {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px;
|
|
||||||
width: auto;
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-top: 325px;
|
|
||||||
color: white;
|
|
||||||
background: rgba(0, 0, 0, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.d,
|
|
||||||
.d video {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.d p {
|
|
||||||
position: absolute;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px;
|
|
||||||
width: auto;
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 5px;
|
|
||||||
top: 315px;
|
|
||||||
color: white;
|
|
||||||
background: rgba(0, 0, 0, 0.7);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
# Dropdown menù
|
# Dropdown menù
|
||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
@@ -195,21 +180,20 @@ video:fullscreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content {
|
.dropdown-content {
|
||||||
z-index: 2;
|
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
min-width: 200px;
|
max-width: 230px;
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
color: white;
|
color: white;
|
||||||
overflow: auto;
|
overflow: hidden;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: var(--box-shadow);
|
box-shadow: var(--box-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content select {
|
.dropdown-content select {
|
||||||
width: auto;
|
width: 210px;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,15 +201,15 @@ video:fullscreen {
|
|||||||
# Recording
|
# Recording
|
||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
.recording {
|
#recording {
|
||||||
display: flex;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recording button,
|
#recording button,
|
||||||
.recording p {
|
#recording p {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin: 1px;
|
margin: 1px;
|
||||||
font-size: 0.8em;
|
font-size: 1.2rem;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +218,7 @@ video:fullscreen {
|
|||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
.chat-room {
|
.chat-room {
|
||||||
z-index: 3;
|
z-index: 4;
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
height: var(--msger-height);
|
height: var(--msger-height);
|
||||||
@@ -406,7 +390,7 @@ video:fullscreen {
|
|||||||
.chat-msger-inputarea {
|
.chat-msger-inputarea {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: #222328;
|
background: #1f1e1e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-msger-input {
|
.chat-msger-input {
|
||||||
@@ -427,14 +411,13 @@ video:fullscreen {
|
|||||||
--------------------------------------------------------------*/
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
emoji-picker {
|
emoji-picker {
|
||||||
top: 0px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 45px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 92%;
|
||||||
--background: #16171b;
|
--background: #16171b;
|
||||||
--num-columns: 9;
|
--num-columns: 8;
|
||||||
--emoji-size: 1.5rem;
|
--emoji-size: 1.5rem;
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
@@ -506,6 +489,7 @@ emoji-picker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
@@ -525,7 +509,7 @@ emoji-picker {
|
|||||||
|
|
||||||
p,
|
p,
|
||||||
button {
|
button {
|
||||||
background: black;
|
background: transparent;
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
@@ -619,3 +603,11 @@ button:hover {
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
z-index:
|
||||||
|
- 1 videoMediaContainer
|
||||||
|
- 2 buttonBar
|
||||||
|
- 3 sidenav
|
||||||
|
- 4 chat
|
||||||
|
*/
|
||||||
|
|||||||
80
public/css/VideoGrid.css
Normal file
80
public/css/VideoGrid.css
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*--------------------------------------------------------------
|
||||||
|
# Video grid
|
||||||
|
--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#videoMediaContainer {
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#videoMediaContainer div {
|
||||||
|
/* Camera */
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
align-self: center;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: 0px 12px 22px rgba(0, 0, 0, 0.4);
|
||||||
|
animation: show 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#videoMediaContainer p {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
width: auto;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
video:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
video:fullscreen {
|
||||||
|
object-fit: contain;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mirror {
|
||||||
|
-webkit-transform: rotateY(180deg);
|
||||||
|
-moz-transform: rotateY(180deg);
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes show {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.4) translateY(20px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
|
|||||||
|
|
||||||
const RoomURL = window.location.href;
|
const RoomURL = window.location.href;
|
||||||
|
|
||||||
const swalBackground = 'rgba(0, 0, 0, 0.7)';
|
const swalBackground = 'linear-gradient(to left, #1f1e1e, #000000)';
|
||||||
const swalImageUrl = '../images/pricing-illustration.svg';
|
const swalImageUrl = '../images/pricing-illustration.svg';
|
||||||
|
|
||||||
const url = {
|
const url = {
|
||||||
@@ -43,34 +43,14 @@ function getRandomNumber(length) {
|
|||||||
|
|
||||||
function initClient() {
|
function initClient() {
|
||||||
if (!DetectRTC.isMobileDevice) {
|
if (!DetectRTC.isMobileDevice) {
|
||||||
setTippy('sessionTime', 'Session time', 'bottom');
|
setTippy('closeNavButton', 'Close', 'right');
|
||||||
setTippy('exitButton', 'Exit room', 'bottom');
|
|
||||||
setTippy('shareButton', 'Share Room', 'bottom');
|
|
||||||
setTippy('devicesButton', 'Devices', 'bottom');
|
|
||||||
setTippy('chatButton', 'Chat', 'bottom');
|
|
||||||
setTippy('chatCleanButton', 'Clean', 'bottom');
|
|
||||||
setTippy('chatSaveButton', 'Save', 'bottom');
|
|
||||||
setTippy('chatCloseButton', 'Close', 'bottom');
|
|
||||||
setTippy('chatMessage', 'Press enter to send', 'top-start');
|
setTippy('chatMessage', 'Press enter to send', 'top-start');
|
||||||
setTippy('chatSendButton', 'Send', 'top');
|
setTippy('chatSendButton', 'Send', 'top');
|
||||||
setTippy('chatEmojiButton', 'Emoji', 'top');
|
setTippy('chatEmojiButton', 'Emoji', 'top');
|
||||||
setTippy('fullScreenButton', 'Full Screen', 'bottom');
|
setTippy('chatCleanButton', 'Clean', 'bottom');
|
||||||
setTippy('recButton', 'Recording', 'bottom');
|
setTippy('chatSaveButton', 'Save', 'bottom');
|
||||||
setTippy('startRecButton', 'Start Recording', 'bottom');
|
setTippy('chatCloseButton', 'Close', 'bottom');
|
||||||
setTippy('stopRecButton', 'Stop Recording', 'bottom');
|
setTippy('sessionTime', 'Session time', 'right');
|
||||||
setTippy('pauseRecButton', 'Pause Recording', 'bottom');
|
|
||||||
setTippy('resumeRecButton', 'Resume Recording', 'bottom');
|
|
||||||
setTippy('stopAudioButton', 'Stop Audio', 'bottom');
|
|
||||||
setTippy('startAudioButton', 'Start Audio', 'bottom');
|
|
||||||
setTippy('swapCameraButton', 'Swap Camera', 'bottom');
|
|
||||||
setTippy('startVideoButton', 'Start Video', 'bottom');
|
|
||||||
setTippy('stopVideoButton', 'Stop Video', 'bottom');
|
|
||||||
setTippy('startScreenButton', 'Start Screen', 'bottom');
|
|
||||||
setTippy('stopScreenButton', 'Stop Screen', 'bottom');
|
|
||||||
setTippy('participantsButton', 'Show participants', 'bottom');
|
|
||||||
setTippy('lockRoomButton', 'Room Lock', 'bottom');
|
|
||||||
setTippy('unlockRoomButton', 'Room Unlock', 'bottom');
|
|
||||||
setTippy('aboutButton', 'About', 'bottom');
|
|
||||||
}
|
}
|
||||||
initEnumerateDevices();
|
initEnumerateDevices();
|
||||||
}
|
}
|
||||||
@@ -115,6 +95,7 @@ async function initEnumerateDevices() {
|
|||||||
if (!isAudioAllowed && !isVideoAllowed) {
|
if (!isAudioAllowed && !isVideoAllowed) {
|
||||||
window.location.href = `/permission?room_id=${room_id}&message=Not allowed both Audio and Video`;
|
window.location.href = `/permission?room_id=${room_id}&message=Not allowed both Audio and Video`;
|
||||||
} else {
|
} else {
|
||||||
|
hide(loadingDiv);
|
||||||
getPeerGeoLocation();
|
getPeerGeoLocation();
|
||||||
whoAreYou();
|
whoAreYou();
|
||||||
}
|
}
|
||||||
@@ -251,11 +232,15 @@ function whoAreYou() {
|
|||||||
function handleAudio(e) {
|
function handleAudio(e) {
|
||||||
isAudioOn = isAudioOn ? false : true;
|
isAudioOn = isAudioOn ? false : true;
|
||||||
e.target.className = 'fas fa-microphone' + (isAudioOn ? '' : '-slash');
|
e.target.className = 'fas fa-microphone' + (isAudioOn ? '' : '-slash');
|
||||||
|
setColor(e.target, isAudioOn ? 'white' : 'red');
|
||||||
|
setColor(startAudioButton, isAudioOn ? 'white' : 'red');
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleVideo(e) {
|
function handleVideo(e) {
|
||||||
isVideoOn = isVideoOn ? false : true;
|
isVideoOn = isVideoOn ? false : true;
|
||||||
e.target.className = 'fas fa-video' + (isVideoOn ? '' : '-slash');
|
e.target.className = 'fas fa-video' + (isVideoOn ? '' : '-slash');
|
||||||
|
setColor(e.target, isVideoOn ? 'white' : 'red');
|
||||||
|
setColor(startVideoButton, isVideoOn ? 'white' : 'red');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
@@ -287,8 +272,8 @@ async function shareRoom(useNavigator = false) {
|
|||||||
<canvas id="qrRoom"></canvas>
|
<canvas id="qrRoom"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<p style="color:white;">Share this meeting invite others to join.</p>
|
<p style="background:transparent; color:white;">Share this meeting invite others to join.</p>
|
||||||
<p style="color:rgb(8, 189, 89);">` +
|
<p style="background:transparent; color:rgb(8, 189, 89);">` +
|
||||||
RoomURL +
|
RoomURL +
|
||||||
`</p>`,
|
`</p>`,
|
||||||
showDenyButton: true,
|
showDenyButton: true,
|
||||||
@@ -323,12 +308,13 @@ async function shareRoom(useNavigator = false) {
|
|||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
function makeRoomQR() {
|
function makeRoomQR() {
|
||||||
|
let qrSize = DetectRTC.isMobileDevice ? 128 : 256;
|
||||||
let qr = new QRious({
|
let qr = new QRious({
|
||||||
element: document.getElementById('qrRoom'),
|
element: document.getElementById('qrRoom'),
|
||||||
value: RoomURL,
|
value: RoomURL,
|
||||||
});
|
});
|
||||||
qr.set({
|
qr.set({
|
||||||
size: 256,
|
size: qrSize,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,9 +345,8 @@ function joinRoom(peer_name, room_id) {
|
|||||||
} else {
|
} else {
|
||||||
console.log('05 ----> join to Room ' + room_id);
|
console.log('05 ----> join to Room ' + room_id);
|
||||||
rc = new RoomClient(
|
rc = new RoomClient(
|
||||||
localMedia,
|
|
||||||
remoteVideos,
|
|
||||||
remoteAudios,
|
remoteAudios,
|
||||||
|
videoMediaContainer,
|
||||||
window.mediasoupClient,
|
window.mediasoupClient,
|
||||||
socket,
|
socket,
|
||||||
room_id,
|
room_id,
|
||||||
@@ -379,7 +364,7 @@ function joinRoom(peer_name, room_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function roomIsReady() {
|
function roomIsReady() {
|
||||||
control.className = '';
|
show(openNavButton);
|
||||||
show(exitButton);
|
show(exitButton);
|
||||||
show(shareButton);
|
show(shareButton);
|
||||||
show(recButton);
|
show(recButton);
|
||||||
@@ -402,10 +387,9 @@ function roomIsReady() {
|
|||||||
};
|
};
|
||||||
show(fullScreenButton);
|
show(fullScreenButton);
|
||||||
}
|
}
|
||||||
show(devicesButton);
|
show(settingsButton);
|
||||||
if (isAudioAllowed) show(startAudioButton);
|
if (isAudioAllowed) show(startAudioButton);
|
||||||
if (isVideoAllowed) show(startVideoButton);
|
if (isVideoAllowed) show(startVideoButton);
|
||||||
show(videoMedia);
|
|
||||||
show(participantsButton);
|
show(participantsButton);
|
||||||
show(lockRoomButton);
|
show(lockRoomButton);
|
||||||
show(aboutButton);
|
show(aboutButton);
|
||||||
@@ -423,6 +407,10 @@ function show(elem) {
|
|||||||
elem.className = '';
|
elem.className = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setColor(elem, color) {
|
||||||
|
elem.style.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// SET CHAT MOBILE
|
// SET CHAT MOBILE
|
||||||
// ####################################################
|
// ####################################################
|
||||||
@@ -441,7 +429,7 @@ function startSessionTimer() {
|
|||||||
let callStartTime = Date.now();
|
let callStartTime = Date.now();
|
||||||
setInterval(function printTime() {
|
setInterval(function printTime() {
|
||||||
let callElapsedTime = Date.now() - callStartTime;
|
let callElapsedTime = Date.now() - callStartTime;
|
||||||
sessionTime.innerHTML = getTimeToString(callElapsedTime);
|
sessionTime.innerHTML = ' ' + getTimeToString(callElapsedTime);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,13 +479,19 @@ function stopRecordingTimer() {
|
|||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
function handleButtons() {
|
function handleButtons() {
|
||||||
|
openNavButton.onclick = () => {
|
||||||
|
openNav();
|
||||||
|
};
|
||||||
|
closeNavButton.onclick = () => {
|
||||||
|
closeNav();
|
||||||
|
};
|
||||||
exitButton.onclick = () => {
|
exitButton.onclick = () => {
|
||||||
rc.exit();
|
rc.exit();
|
||||||
};
|
};
|
||||||
shareButton.onclick = () => {
|
shareButton.onclick = () => {
|
||||||
shareRoom(true);
|
shareRoom(true);
|
||||||
};
|
};
|
||||||
devicesButton.onclick = () => {
|
settingsButton.onclick = () => {
|
||||||
rc.toggleDevices();
|
rc.toggleDevices();
|
||||||
};
|
};
|
||||||
chatButton.onclick = () => {
|
chatButton.onclick = () => {
|
||||||
@@ -584,7 +578,7 @@ function handleSelects() {
|
|||||||
rc.closeThenProduce(RoomClient.mediaType.audio, microphoneSelect.value);
|
rc.closeThenProduce(RoomClient.mediaType.audio, microphoneSelect.value);
|
||||||
};
|
};
|
||||||
speakerSelect.onchange = () => {
|
speakerSelect.onchange = () => {
|
||||||
rc.attachSinkId(localMedia, speakerSelect.value);
|
rc.attachSinkId(rc.myVideoEl, speakerSelect.value);
|
||||||
};
|
};
|
||||||
videoSelect.onchange = () => {
|
videoSelect.onchange = () => {
|
||||||
rc.closeThenProduce(RoomClient.mediaType.video, videoSelect.value);
|
rc.closeThenProduce(RoomClient.mediaType.video, videoSelect.value);
|
||||||
@@ -614,20 +608,24 @@ function handleInputs() {
|
|||||||
|
|
||||||
function handleRoomClientEvents() {
|
function handleRoomClientEvents() {
|
||||||
rc.on(RoomClient.EVENTS.startRec, () => {
|
rc.on(RoomClient.EVENTS.startRec, () => {
|
||||||
|
console.log('Room Client start recoding');
|
||||||
hide(startRecButton);
|
hide(startRecButton);
|
||||||
show(stopRecButton);
|
show(stopRecButton);
|
||||||
show(pauseRecButton);
|
show(pauseRecButton);
|
||||||
startRecordingTimer();
|
startRecordingTimer();
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.pauseRec, () => {
|
rc.on(RoomClient.EVENTS.pauseRec, () => {
|
||||||
|
console.log('Room Client pause recoding');
|
||||||
hide(pauseRecButton);
|
hide(pauseRecButton);
|
||||||
show(resumeRecButton);
|
show(resumeRecButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.resumeRec, () => {
|
rc.on(RoomClient.EVENTS.resumeRec, () => {
|
||||||
|
console.log('Room Client resume recoding');
|
||||||
hide(resumeRecButton);
|
hide(resumeRecButton);
|
||||||
show(pauseRecButton);
|
show(pauseRecButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.stopRec, () => {
|
rc.on(RoomClient.EVENTS.stopRec, () => {
|
||||||
|
console.log('Room Client stop recoding');
|
||||||
hide(stopRecButton);
|
hide(stopRecButton);
|
||||||
hide(pauseRecButton);
|
hide(pauseRecButton);
|
||||||
hide(resumeRecButton);
|
hide(resumeRecButton);
|
||||||
@@ -635,8 +633,10 @@ function handleRoomClientEvents() {
|
|||||||
stopRecordingTimer();
|
stopRecordingTimer();
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.startAudio, () => {
|
rc.on(RoomClient.EVENTS.startAudio, () => {
|
||||||
|
console.log('Room Client start audio');
|
||||||
hide(startAudioButton);
|
hide(startAudioButton);
|
||||||
show(stopAudioButton);
|
show(stopAudioButton);
|
||||||
|
setColor(startAudioButton, 'red');
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.pauseAudio, () => {
|
rc.on(RoomClient.EVENTS.pauseAudio, () => {
|
||||||
console.log('Room Client pause audio');
|
console.log('Room Client pause audio');
|
||||||
@@ -649,12 +649,15 @@ function handleRoomClientEvents() {
|
|||||||
show(stopAudioButton);
|
show(stopAudioButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.stopAudio, () => {
|
rc.on(RoomClient.EVENTS.stopAudio, () => {
|
||||||
|
console.log('Room Client stop audio');
|
||||||
hide(stopAudioButton);
|
hide(stopAudioButton);
|
||||||
show(startAudioButton);
|
show(startAudioButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.startVideo, () => {
|
rc.on(RoomClient.EVENTS.startVideo, () => {
|
||||||
|
console.log('Room Client start video');
|
||||||
hide(startVideoButton);
|
hide(startVideoButton);
|
||||||
show(stopVideoButton);
|
show(stopVideoButton);
|
||||||
|
setColor(startVideoButton, 'red');
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.pauseVideo, () => {
|
rc.on(RoomClient.EVENTS.pauseVideo, () => {
|
||||||
console.log('Room Client pause video');
|
console.log('Room Client pause video');
|
||||||
@@ -667,10 +670,12 @@ function handleRoomClientEvents() {
|
|||||||
show(stopVideoButton);
|
show(stopVideoButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.stopVideo, () => {
|
rc.on(RoomClient.EVENTS.stopVideo, () => {
|
||||||
|
console.log('Room Client stop audio');
|
||||||
hide(stopVideoButton);
|
hide(stopVideoButton);
|
||||||
show(startVideoButton);
|
show(startVideoButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.startScreen, () => {
|
rc.on(RoomClient.EVENTS.startScreen, () => {
|
||||||
|
console.log('Room Client start screen');
|
||||||
hide(startScreenButton);
|
hide(startScreenButton);
|
||||||
show(stopScreenButton);
|
show(stopScreenButton);
|
||||||
});
|
});
|
||||||
@@ -681,22 +686,35 @@ function handleRoomClientEvents() {
|
|||||||
console.log('Room Client resume screen');
|
console.log('Room Client resume screen');
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.stopScreen, () => {
|
rc.on(RoomClient.EVENTS.stopScreen, () => {
|
||||||
|
console.log('Room Client stop screen');
|
||||||
hide(stopScreenButton);
|
hide(stopScreenButton);
|
||||||
show(startScreenButton);
|
show(startScreenButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.roomLock, () => {
|
rc.on(RoomClient.EVENTS.roomLock, () => {
|
||||||
|
console.log('Room Client lock room');
|
||||||
hide(lockRoomButton);
|
hide(lockRoomButton);
|
||||||
show(unlockRoomButton);
|
show(unlockRoomButton);
|
||||||
|
setColor(unlockRoomButton, 'red');
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.roomUnlock, () => {
|
rc.on(RoomClient.EVENTS.roomUnlock, () => {
|
||||||
|
console.log('Room Client unlock room');
|
||||||
hide(unlockRoomButton);
|
hide(unlockRoomButton);
|
||||||
show(lockRoomButton);
|
show(lockRoomButton);
|
||||||
});
|
});
|
||||||
rc.on(RoomClient.EVENTS.exitRoom, () => {
|
rc.on(RoomClient.EVENTS.exitRoom, () => {
|
||||||
|
console.log('Room Client leave room');
|
||||||
window.location.href = '/newroom';
|
window.location.href = '/newroom';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openNav() {
|
||||||
|
control.classList.toggle('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeNav() {
|
||||||
|
control.classList.toggle('show');
|
||||||
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// SHOW LOG
|
// SHOW LOG
|
||||||
// ####################################################
|
// ####################################################
|
||||||
@@ -746,8 +764,14 @@ async function getRoomParticipants() {
|
|||||||
let peer_name = peer_info.peer_name;
|
let peer_name = peer_info.peer_name;
|
||||||
let peer_id = peer_info.peer_id;
|
let peer_id = peer_info.peer_id;
|
||||||
rc.peer_id === peer_id
|
rc.peer_id === peer_id
|
||||||
? (table += `<tr><td>- 👤 ${peer_name} (me)</td><td></td></tr>`)
|
? (table += `<tr>
|
||||||
: (table += `<tr id='${peer_id}'><td>- 👤 ${peer_name}</td><td><button id='${peer_id}' onclick="rc.peerAction('me',this.id,'eject')">eject</button></td></tr>`);
|
<td>👤 ${peer_name} (me)</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>`)
|
||||||
|
: (table += `<tr id='${peer_id}'>
|
||||||
|
<td>👤 ${peer_name}</td>
|
||||||
|
<td><button id='${peer_id}' onclick="rc.peerAction('me',this.id,'eject')">eject</button></td>
|
||||||
|
</tr>`);
|
||||||
}
|
}
|
||||||
table += `</table></div>`;
|
table += `</table></div>`;
|
||||||
|
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ let recordedBlobs;
|
|||||||
|
|
||||||
class RoomClient {
|
class RoomClient {
|
||||||
constructor(
|
constructor(
|
||||||
localMediaEl,
|
|
||||||
remoteVideoEl,
|
|
||||||
remoteAudioEl,
|
remoteAudioEl,
|
||||||
|
videoMediaContainer,
|
||||||
mediasoupClient,
|
mediasoupClient,
|
||||||
socket,
|
socket,
|
||||||
room_id,
|
room_id,
|
||||||
@@ -63,9 +62,8 @@ class RoomClient {
|
|||||||
isVideoOn,
|
isVideoOn,
|
||||||
successCallback,
|
successCallback,
|
||||||
) {
|
) {
|
||||||
this.localMediaEl = localMediaEl;
|
|
||||||
this.remoteVideoEl = remoteVideoEl;
|
|
||||||
this.remoteAudioEl = remoteAudioEl;
|
this.remoteAudioEl = remoteAudioEl;
|
||||||
|
this.videoMediaContainer = videoMediaContainer;
|
||||||
this.mediasoupClient = mediasoupClient;
|
this.mediasoupClient = mediasoupClient;
|
||||||
|
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
@@ -103,6 +101,7 @@ class RoomClient {
|
|||||||
this.recScreenStream = null;
|
this.recScreenStream = null;
|
||||||
this._isRecording = false;
|
this._isRecording = false;
|
||||||
|
|
||||||
|
this.myVideoEl = null;
|
||||||
this.connectedRoom = null;
|
this.connectedRoom = null;
|
||||||
this.debug = false;
|
this.debug = false;
|
||||||
|
|
||||||
@@ -484,6 +483,8 @@ class RoomClient {
|
|||||||
track.stop();
|
track.stop();
|
||||||
});
|
});
|
||||||
elem.parentNode.removeChild(elem);
|
elem.parentNode.removeChild(elem);
|
||||||
|
|
||||||
|
resizeVideoMedia();
|
||||||
}
|
}
|
||||||
this.producers.delete(producer.id);
|
this.producers.delete(producer.id);
|
||||||
});
|
});
|
||||||
@@ -495,6 +496,8 @@ class RoomClient {
|
|||||||
track.stop();
|
track.stop();
|
||||||
});
|
});
|
||||||
elem.parentNode.removeChild(elem);
|
elem.parentNode.removeChild(elem);
|
||||||
|
|
||||||
|
resizeVideoMedia();
|
||||||
}
|
}
|
||||||
this.producers.delete(producer.id);
|
this.producers.delete(producer.id);
|
||||||
});
|
});
|
||||||
@@ -602,27 +605,27 @@ class RoomClient {
|
|||||||
async handleProducer(id, type, stream) {
|
async handleProducer(id, type, stream) {
|
||||||
let elem, d, p;
|
let elem, d, p;
|
||||||
d = document.createElement('div');
|
d = document.createElement('div');
|
||||||
d.className = 'd';
|
d.className = 'Camera';
|
||||||
d.id = id + '_d';
|
d.id = id + '_d';
|
||||||
elem = document.createElement('video');
|
elem = document.createElement('video');
|
||||||
elem.setAttribute('id', id);
|
elem.setAttribute('id', id);
|
||||||
elem.setAttribute('playsinline', true);
|
elem.setAttribute('playsinline', true);
|
||||||
elem.autoplay = true;
|
elem.autoplay = true;
|
||||||
elem.poster = image.poster;
|
elem.poster = image.poster;
|
||||||
if (this.isMobileDevice || type === mediaType.screen) elem.className = 'vid';
|
this.isMobileDevice || type === mediaType.screen ? (elem.className = '') : (elem.className = 'mirror');
|
||||||
else elem.className = 'vid mirror';
|
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
p.id = id + '_name';
|
p.id = id + '_name';
|
||||||
p.className = 'pn';
|
|
||||||
p.innerHTML = '👤 ' + this.peer_name + ' (me)';
|
p.innerHTML = '👤 ' + this.peer_name + ' (me)';
|
||||||
d.appendChild(elem);
|
d.appendChild(elem);
|
||||||
d.appendChild(p);
|
d.appendChild(p);
|
||||||
this.localMediaEl.appendChild(d);
|
this.videoMediaContainer.appendChild(d);
|
||||||
this.attachMediaStream(elem, stream, type, 'Producer');
|
this.attachMediaStream(elem, stream, type, 'Producer');
|
||||||
|
this.myVideoEl = elem;
|
||||||
this.handleFS(elem.id);
|
this.handleFS(elem.id);
|
||||||
this.setTippy(elem.id, 'Full Screen', 'top-end');
|
this.setTippy(elem.id, 'Full Screen', 'top-end');
|
||||||
this.popupPeerInfo(p.id, this.peer_info);
|
this.popupPeerInfo(p.id, this.peer_info);
|
||||||
this.sound('joined');
|
this.sound('joined');
|
||||||
|
resizeVideoMedia();
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,6 +701,8 @@ class RoomClient {
|
|||||||
track.stop();
|
track.stop();
|
||||||
});
|
});
|
||||||
d.parentNode.removeChild(d);
|
d.parentNode.removeChild(d);
|
||||||
|
|
||||||
|
resizeVideoMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -780,25 +785,26 @@ class RoomClient {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case mediaType.video:
|
case mediaType.video:
|
||||||
d = document.createElement('div');
|
d = document.createElement('div');
|
||||||
d.className = 'd';
|
d.className = 'Camera';
|
||||||
d.id = id + '_d';
|
d.id = id + '_d';
|
||||||
elem = document.createElement('video');
|
elem = document.createElement('video');
|
||||||
elem.setAttribute('id', id);
|
elem.setAttribute('id', id);
|
||||||
elem.setAttribute('playsinline', true);
|
elem.setAttribute('playsinline', true);
|
||||||
elem.autoplay = true;
|
elem.autoplay = true;
|
||||||
elem.className = 'vid';
|
elem.className = '';
|
||||||
elem.poster = image.poster;
|
elem.poster = image.poster;
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
p.id = id + '_name';
|
p.id = id + '_name';
|
||||||
p.innerHTML = '👤 ' + peer_name;
|
p.innerHTML = '👤 ' + peer_name;
|
||||||
d.appendChild(elem);
|
d.appendChild(elem);
|
||||||
d.appendChild(p);
|
d.appendChild(p);
|
||||||
this.remoteVideoEl.appendChild(d);
|
this.videoMediaContainer.appendChild(d);
|
||||||
this.attachMediaStream(elem, stream, type, 'Consumer');
|
this.attachMediaStream(elem, stream, type, 'Consumer');
|
||||||
this.handleFS(elem.id);
|
this.handleFS(elem.id);
|
||||||
this.setTippy(elem.id, 'Full Screen', 'top-end');
|
this.setTippy(elem.id, 'Full Screen', 'top-end');
|
||||||
this.popupPeerInfo(p.id, peer_info);
|
this.popupPeerInfo(p.id, peer_info);
|
||||||
this.sound('joined');
|
this.sound('joined');
|
||||||
|
resizeVideoMedia();
|
||||||
break;
|
break;
|
||||||
case mediaType.audio:
|
case mediaType.audio:
|
||||||
elem = document.createElement('audio');
|
elem = document.createElement('audio');
|
||||||
@@ -822,6 +828,8 @@ class RoomClient {
|
|||||||
if (elem) elem.parentNode.removeChild(elem);
|
if (elem) elem.parentNode.removeChild(elem);
|
||||||
if (d) d.parentNode.removeChild(d);
|
if (d) d.parentNode.removeChild(d);
|
||||||
|
|
||||||
|
resizeVideoMedia();
|
||||||
|
|
||||||
this.consumers.delete(consumer_id);
|
this.consumers.delete(consumer_id);
|
||||||
this.sound('left');
|
this.sound('left');
|
||||||
}
|
}
|
||||||
@@ -959,7 +967,7 @@ class RoomClient {
|
|||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
toggleDevices() {
|
toggleDevices() {
|
||||||
this.getId('myDevices').classList.toggle('show');
|
this.getId('settings').classList.toggle('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
async sound(name) {
|
async sound(name) {
|
||||||
|
|||||||
58
public/js/VideoGrid.js
Normal file
58
public/js/VideoGrid.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function Area(Increment, Count, Width, Height, Margin = 10) {
|
||||||
|
let i = 0;
|
||||||
|
let w = 0;
|
||||||
|
let h = Increment * 0.75 + Margin * 2;
|
||||||
|
while (i < Count) {
|
||||||
|
if (w + Increment > Width) {
|
||||||
|
w = 0;
|
||||||
|
h = h + Increment * 0.75 + Margin * 2;
|
||||||
|
}
|
||||||
|
w = w + Increment + Margin * 2;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (h > Height) return false;
|
||||||
|
else return Increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeVideoMedia() {
|
||||||
|
let Margin = 2;
|
||||||
|
let Scenary = document.getElementById('videoMediaContainer');
|
||||||
|
let Width = Scenary.offsetWidth - Margin * 2;
|
||||||
|
let Height = Scenary.offsetHeight - Margin * 2;
|
||||||
|
let Cameras = document.getElementsByClassName('Camera');
|
||||||
|
let max = 0;
|
||||||
|
|
||||||
|
// loop (i recommend you optimize this)
|
||||||
|
let i = 1;
|
||||||
|
while (i < 5000) {
|
||||||
|
let w = Area(i, Cameras.length, Width, Height, Margin);
|
||||||
|
if (w === false) {
|
||||||
|
max = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
max = max - Margin * 2;
|
||||||
|
setWidth(max, Margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth(width, margin) {
|
||||||
|
let Cameras = document.getElementsByClassName('Camera');
|
||||||
|
for (var s = 0; s < Cameras.length; s++) {
|
||||||
|
Cameras[s].style.width = width + 'px';
|
||||||
|
Cameras[s].style.margin = margin + 'px';
|
||||||
|
Cameras[s].style.height = width * 0.7 + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
'load',
|
||||||
|
function (event) {
|
||||||
|
resizeVideoMedia();
|
||||||
|
window.onresize = resizeVideoMedia;
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
المرجع في مشكلة جديدة
حظر مستخدم