ajout app
BIN
MiroTalk SFU/public/advertisers/Contabo.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
MiroTalk SFU/public/advertisers/ContaboLogo.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
365
MiroTalk SFU/public/css/GroupChat.css
Normal file
@ -0,0 +1,365 @@
|
||||
.container {
|
||||
padding: 2px !important;
|
||||
transition:
|
||||
width 0.5s,
|
||||
background 2s ease !important;
|
||||
/* overflow-y: auto;
|
||||
overflow-x: hidden; */
|
||||
}
|
||||
|
||||
/* Chat Room */
|
||||
.chat-container {
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
width: var(--msger-width);
|
||||
height: var(--msger-height);
|
||||
min-width: var(--msger-width);
|
||||
min-height: var(--msger-height);
|
||||
padding: 3px;
|
||||
background: var(--msger-bg);
|
||||
border: var(--border);
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--box-shadow);
|
||||
transition: background 1s;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat app container */
|
||||
.chat-app {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat app people container */
|
||||
.chat-app .people-list {
|
||||
z-index: 6;
|
||||
position: absolute;
|
||||
padding: 20px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 300px;
|
||||
height: 99%;
|
||||
background: var(--msger-bg);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat app people list container */
|
||||
.people-list {
|
||||
-moz-transition: 0.5s;
|
||||
-o-transition: 0.5s;
|
||||
-webkit-transition: 0.5s;
|
||||
transition: 0.5s;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
.people-list .chat-list li {
|
||||
padding: 10px 15px;
|
||||
list-style: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.people-list .chat-list li:hover {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.people-list .chat-list li.active {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.people-list .chat-list li .name {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.people-list .chat-list img {
|
||||
width: 45px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.people-list img {
|
||||
float: left;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.people-list .about {
|
||||
float: left;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.people-list .about-buttons {
|
||||
margin-top: 35px;
|
||||
width: auto;
|
||||
/* display: inline-flex; */
|
||||
}
|
||||
|
||||
.people-list .status {
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Chat app people list container */
|
||||
.chat-app .chat-list {
|
||||
height: auto;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat app container */
|
||||
.chat-app .chat {
|
||||
position: relative;
|
||||
margin-left: 300px;
|
||||
border-left: var(--border);
|
||||
border-radius: 10px;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat header */
|
||||
.chat .chat-header {
|
||||
padding: 15px 20px; /* top, right, bottom, left */
|
||||
border-bottom: var(--border);
|
||||
height: 70px;
|
||||
max-height: 70px;
|
||||
cursor: move;
|
||||
/* overflow-x: auto; */
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
.all-participants-img {
|
||||
border: var(--border);
|
||||
width: 40px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.all-participants-img:hover {
|
||||
background-color: lime;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.chat .chat-header img {
|
||||
float: left;
|
||||
border-radius: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.chat .chat-header .chat-about {
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.chat .chat-header .status {
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.chat .chat-header .chat-option-buttons {
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
/* Chat history */
|
||||
.chat .chat-history {
|
||||
padding: 20px;
|
||||
height: calc(100vh - 210px);
|
||||
min-height: 490px;
|
||||
max-height: 490px;
|
||||
border-bottom: var(--border);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
.chat .chat-history ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chat .chat-history ul li {
|
||||
list-style: none;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.chat .chat-history ul li:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.chat .chat-history .message-data {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.chat .chat-history .message-data img {
|
||||
border-radius: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.chat .chat-history .message-data-time {
|
||||
color: #eeeeee;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
/* chat message bubble */
|
||||
.chat .chat-history .message {
|
||||
color: #fff;
|
||||
padding: 18px 20px;
|
||||
line-height: 26px;
|
||||
font-size: 16px;
|
||||
max-width: 100%;
|
||||
border-radius: 7px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
.chat .chat-history .message:after {
|
||||
bottom: 100%;
|
||||
left: 7%;
|
||||
border: solid transparent;
|
||||
content: ' ';
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-bottom-color: grey;
|
||||
border-width: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.chat .chat-history .my-message {
|
||||
background: var(--right-msg-bg);
|
||||
}
|
||||
|
||||
.chat .chat-history .my-message:after {
|
||||
bottom: 100%;
|
||||
left: 30px;
|
||||
border: solid transparent;
|
||||
content: ' ';
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-bottom-color: #999;
|
||||
border-width: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.chat .chat-history .other-message {
|
||||
background: var(--left-msg-bg);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.chat .chat-history .other-message:after {
|
||||
border-bottom-color: grey;
|
||||
left: 93%;
|
||||
}
|
||||
|
||||
/* Chat message */
|
||||
.chat .chat-message {
|
||||
padding: 20px;
|
||||
max-height: 140px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/* border: 1px solid lime; */
|
||||
}
|
||||
|
||||
/* Chat emoji */
|
||||
.chatEmojiPicker {
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
bottom: 135px;
|
||||
}
|
||||
|
||||
/* status */
|
||||
.online,
|
||||
.offline,
|
||||
.me {
|
||||
margin-right: 2px;
|
||||
font-size: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.online {
|
||||
color: #86c541;
|
||||
}
|
||||
.offline {
|
||||
color: #e47297;
|
||||
}
|
||||
.me {
|
||||
color: #1d8ecd;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
.float-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: ' ';
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/** common **/
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* Chat search and input message */
|
||||
textarea,
|
||||
input[type='text'] {
|
||||
background: var(--msger-bg) !important;
|
||||
color: #fff !important;
|
||||
transition: height 0.5s !important;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hr {
|
||||
border: 0;
|
||||
display: block;
|
||||
height: 1px;
|
||||
background: #000000;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 10px;
|
||||
}
|
1302
MiroTalk SFU/public/css/Room.css
Normal file
47
MiroTalk SFU/public/css/Snow.css
Normal file
@ -0,0 +1,47 @@
|
||||
#snow-container {
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
transition: opacity 500ms;
|
||||
}
|
||||
|
||||
.snow {
|
||||
position: absolute;
|
||||
animation:
|
||||
fall ease-in infinite,
|
||||
sway ease-in-out infinite;
|
||||
color: skyblue;
|
||||
}
|
||||
|
||||
@keyframes fall {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 100vh;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sway {
|
||||
0% {
|
||||
margin-left: 0;
|
||||
}
|
||||
25% {
|
||||
margin-left: 50px;
|
||||
}
|
||||
50% {
|
||||
margin-left: -50px;
|
||||
}
|
||||
75% {
|
||||
margin-left: 50px;
|
||||
}
|
||||
100% {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
244
MiroTalk SFU/public/css/VideoGrid.css
Normal file
@ -0,0 +1,244 @@
|
||||
/*--------------------------------------------------------------
|
||||
# Video grid
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
#videoMediaContainer {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
/* border: 3px solid blue; */
|
||||
}
|
||||
|
||||
#videoPinMediaContainer {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 75%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
box-shadow: var(--box-shadow);
|
||||
overflow: hidden;
|
||||
/* animation: show 0.4s ease; */
|
||||
/* border: 3px solid lime; */
|
||||
}
|
||||
|
||||
.Camera {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
align-self: center;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
background: transparent;
|
||||
border-radius: 10px;
|
||||
border: var(--border);
|
||||
box-shadow: var(--box-shadow);
|
||||
animation: show 0.4s ease;
|
||||
}
|
||||
|
||||
/* .Camera:hover {
|
||||
border: 3px solid rgb(113, 157, 239);
|
||||
} */
|
||||
|
||||
#videoMediaContainer i {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0;
|
||||
color: rgb(0, 255, 71);
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
width: auto;
|
||||
height: 25px;
|
||||
border-radius: 5px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.videoAvatarImage {
|
||||
z-index: 7;
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: var(--vmi-wh);
|
||||
height: var(--vmi-wh);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.audio {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
color: #fff;
|
||||
margin: 5px;
|
||||
width: auto;
|
||||
height: 25px;
|
||||
border-radius: 5px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.username {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
width: auto;
|
||||
height: 25px;
|
||||
border-radius: 5px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.fscreen {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0px;
|
||||
color: #fff;
|
||||
margin: 5px;
|
||||
width: auto;
|
||||
height: 25px;
|
||||
border-radius: 5px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.videoMenuBar {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
display: inline;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 10px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.videoMenuBar input,
|
||||
.videoMenuBar button {
|
||||
float: right;
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
border-radius: 5px;
|
||||
display: inline;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.videoMenuBar button:hover {
|
||||
color: grey;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.expand-video-content {
|
||||
position: relative;
|
||||
display: none;
|
||||
float: right;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.expand-video:hover .expand-video-content {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#videoMediaContainer video {
|
||||
position: absolute;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.videoCircle {
|
||||
position: absolute;
|
||||
width: var(--vmi-wh);
|
||||
height: var(--vmi-wh);
|
||||
border-radius: 50%;
|
||||
/* center */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.videoDefault {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: '10px';
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: var(--videoObjFit);
|
||||
border-radius: 10px;
|
||||
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);
|
||||
}
|
||||
|
||||
.blur {
|
||||
-webkit-filter: blur(5px);
|
||||
-moz-filter: blur(5px);
|
||||
-o-filter: blur(5px);
|
||||
-ms-filter: blur(5px);
|
||||
filter: blur(5px);
|
||||
}
|
||||
|
||||
input[type='range'] {
|
||||
/* display: none; */
|
||||
color: #fff;
|
||||
width: 50px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.4) translateY(20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.username {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 500px) {
|
||||
.username {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
2031
MiroTalk SFU/public/css/landing.css
Normal file
BIN
MiroTalk SFU/public/images/AGPLv3.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
MiroTalk SFU/public/images/all.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
590
MiroTalk SFU/public/images/architecture.svg
Normal file
@ -0,0 +1,590 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1516px" height="1313px" viewBox="-0.5 -0.5 1516 1313">
|
||||
<defs>
|
||||
<linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-e3e3e3-1-9c9c9c-1-s-0">
|
||||
<stop offset="0%" style="stop-color:#E3E3E3"/>
|
||||
<stop offset="100%" style="stop-color:#9C9C9C"/>
|
||||
</linearGradient>
|
||||
<linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ffffff-1-e3e3e3-1-s-0">
|
||||
<stop offset="0%" style="stop-color:#ffffff"/>
|
||||
<stop offset="100%" style="stop-color:#E3E3E3"/>
|
||||
</linearGradient>
|
||||
<linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ea6b66-1-ff3333-1-s-0">
|
||||
<stop offset="0%" style="stop-color:#EA6B66"/>
|
||||
<stop offset="100%" style="stop-color:#FF3333"/>
|
||||
</linearGradient>
|
||||
<linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-66cc00-1-4d9900-1-s-0">
|
||||
<stop offset="0%" style="stop-color:#66CC00"/>
|
||||
<stop offset="100%" style="stop-color:#4D9900"/>
|
||||
</linearGradient>
|
||||
<linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-70a9ff-1-2e89ff-1-s-0">
|
||||
<stop offset="0%" style="stop-color:#70A9FF"/>
|
||||
<stop offset="100%" style="stop-color:#2E89FF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<rect x="275" y="21" width="980" height="1240" rx="19.6" ry="19.6" fill="url(#mx-gradient-e3e3e3-1-9c9c9c-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(743.5,1270.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="42" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; width: 42px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Host</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="21" y="21" fill="#787878" text-anchor="middle" font-size="20px" font-family="Helvetica">Host</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="325" y="71" width="883" height="640" rx="19.2" ry="19.2" fill="url(#mx-gradient-ffffff-1-e3e3e3-1-s-0)" stroke="#616161" stroke-width="2" pointer-events="none"/>
|
||||
<g transform="translate(725.5,721.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="80" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(97, 97, 97); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Worker 1</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="40" y="21" fill="#616161" text-anchor="middle" font-size="20px" font-family="Helvetica">Worker 1</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="357.5" y="121" width="150" height="150" rx="22.5" ry="22.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(369.5,278.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="125" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 125px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="63" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 508 196 L 709.76 196" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 717.76 196 L 709.76 200 L 709.76 192 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 382.5 136 L 472.5 136 L 472.5 136 L 482.5 151 L 472.5 166 L 472.5 166 L 382.5 166 L 392.5 151 Z" fill="url(#mx-gradient-ea6b66-1-ff3333-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(377.5,172.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="110" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Audio Producer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="55" y="17" fill="#FF3333" text-anchor="middle" font-size="16px" font-family="Helvetica">Audio Producer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 382.5 206 L 472.5 206 L 472.5 206 L 482.5 221 L 472.5 236 L 472.5 236 L 382.5 236 L 392.5 221 Z" fill="url(#mx-gradient-ea6b66-1-ff3333-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(377.5,242.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="110" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Producer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="55" y="17" fill="#FF3333" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Producer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 820 196 L 1004.85 172.3" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1012.78 171.28 L 1005.36 176.27 L 1004.34 168.33 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 820 196 L 1011.57 328.19" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1018.16 332.73 L 1009.3 331.48 L 1013.85 324.89 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="357.5" y="366" width="150" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(367.5,463.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="129" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 129px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PlainRtpTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="65" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PlainRtpTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 382.5 391 L 472.5 391 L 472.5 391 L 482.5 406 L 472.5 421 L 472.5 421 L 382.5 421 L 392.5 406 Z" fill="url(#mx-gradient-ea6b66-1-ff3333-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(377.5,427.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="110" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Producer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="55" y="17" fill="#FF3333" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Producer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 483 406 L 709.76 406" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 717.76 406 L 709.76 410 L 709.76 402 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<rect x="555" y="548.5" width="155" height="130" rx="19.5" ry="19.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(668.5,613.5)rotate(-90,49.5,0)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="99" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 101px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PipeTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="50" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PipeTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 582 598.5 L 672 598.5 L 672 598.5 L 682 613.5 L 672 628.5 L 672 628.5 L 582 628.5 L 592 613.5 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" transform="rotate(90,632,613.5)" pointer-events="none"/>
|
||||
<g transform="translate(602.5,604.5)rotate(-90,59.5,8.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 770 456 L 641.47 543.25" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 634.85 547.74 L 639.22 539.94 L 643.72 546.56 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 114 196 L 347.26 196" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 355.26 196 L 347.26 200 L 347.26 192 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="217" y="189" width="39" height="17" stroke-width="0"/>
|
||||
<text x="235" y="200.5">SRTP</text>
|
||||
</g>
|
||||
<path d="M 1175 171 L 1414.76 169.08" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1422.76 169.02 L 1414.8 173.08 L 1414.73 165.08 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="1280" y="163" width="39" height="17" stroke-width="0"/>
|
||||
<text x="1299" y="174.5">SRTP</text>
|
||||
</g>
|
||||
<path d="M 89.53 210.86 C 90.09 210.86 90.48 210.64 90.37 210.48 L 89.26 208.86 C 89.12 208.61 88.92 208.57 88.59 208.57 L 81.41 208.57 C 81.06 208.57 80.88 208.62 80.71 208.87 L 79.68 210.47 C 79.48 210.72 80.08 210.86 80.51 210.86 Z M 106.32 205.61 L 106.32 181.96 L 63.65 181.96 L 63.65 205.61 Z M 59 213 C 57.87 212.99 56.85 212.62 56.42 212.03 C 56 211.46 56.17 210.89 56.53 210.5 L 60.66 206.35 L 60.66 181.83 C 60.66 180.6 61.78 179 63.63 179 L 106.33 179 C 107.77 179 109.31 180.14 109.31 181.99 L 109.31 206.35 L 113.48 210.54 C 113.83 210.93 114 211.45 113.58 212.01 C 113.03 212.72 111.99 212.95 111.02 213 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(23.5,219.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="122" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br />
|
||||
(mic/webcam on)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="61" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">Participant<br>(mic/webcam on)<br></text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1443.63 187.3 L 1484.45 187.3 L 1484.45 167.14 L 1443.63 167.14 Z M 1442.65 190.29 C 1441.41 190.29 1440.08 189.41 1440.08 188.09 L 1440.08 166.3 C 1440.08 165.24 1441.14 164.15 1442.69 164.15 L 1485.4 164.15 C 1486.96 164.15 1488 165.27 1488 166.29 L 1488 188 C 1488 189.32 1486.89 190.29 1485.27 190.29 L 1469.72 190.29 C 1469.41 191.2 1469.11 192.17 1469.05 192.99 C 1468.92 194.69 1470.19 195.17 1472.47 195.44 C 1473.99 195.6 1475.34 195.63 1476.78 195.66 C 1477.66 195.66 1478.5 196.2 1478.5 197.08 C 1478.5 197.92 1477.78 198.5 1476.8 198.5 L 1451.34 198.5 C 1450.44 198.5 1449.67 197.88 1449.67 197.08 C 1449.67 196.36 1450.34 195.66 1451.34 195.66 C 1453.02 195.61 1454.73 195.61 1456.49 195.32 C 1458.19 195.05 1459.23 194.52 1459.04 192.9 C 1458.97 192.17 1458.67 191.2 1458.36 190.29 Z M 1431.21 151.46 L 1450.73 151.46 L 1450.73 149.22 L 1431.21 149.22 Z M 1425 194.77 L 1425 145.43 C 1425 143.74 1426.81 142.5 1428.4 142.5 L 1453.5 142.5 C 1455.25 142.5 1456.94 143.82 1456.94 145.43 L 1456.94 161.91 L 1442.56 161.91 C 1439.86 161.91 1437.42 164.02 1437.42 166.25 L 1437.42 179.83 L 1431.21 179.83 L 1431.21 182.07 L 1437.42 182.07 L 1437.42 186.55 L 1431.21 186.55 L 1431.21 188.79 L 1437.49 188.79 C 1438 191.15 1440.47 192.53 1442.55 192.53 L 1456.23 192.53 C 1456.23 192.71 1456.33 192.9 1456.32 193.04 C 1455.42 193.29 1453.39 193.42 1451.68 193.42 C 1450.92 193.39 1450.27 193.47 1449.61 193.7 C 1448.96 193.92 1448.39 194.28 1447.9 194.77 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1418.5,205.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="76" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br />
|
||||
(viewer)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="38" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1175 334 L 1423.76 334.44" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1431.76 334.46 L 1423.76 338.44 L 1423.77 330.44 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="1290" y="327" width="30" height="17" stroke-width="0"/>
|
||||
<text x="1304" y="338.73">RTP</text>
|
||||
</g>
|
||||
<path d="M 1461.13 335.37 C 1461.51 334.99 1461.76 334.05 1461.03 333.31 L 1447.88 320.84 C 1446.97 320.1 1445.62 319.95 1444.53 320.91 C 1443.45 322.03 1443.76 323.6 1444.56 324.37 L 1455.04 334.31 L 1444.68 343.47 C 1443.82 344.27 1443.46 345.56 1444.14 346.7 C 1445.05 348.16 1446.84 348.07 1447.82 347.23 Z M 1468.15 347.92 C 1468.97 347.92 1469.98 347.24 1469.98 346.03 C 1469.98 345.03 1469.22 344.15 1468.13 344.15 L 1457.66 344.15 C 1456.99 344.15 1455.86 344.74 1455.86 345.99 C 1455.86 347.13 1456.74 347.92 1457.69 347.92 Z M 1436.88 357 C 1435.4 357 1434 355.74 1434 354.13 L 1434 314.82 C 1434 313.19 1435.53 312 1436.79 312 L 1476.05 312 C 1477.64 312 1479 313.26 1479 314.91 L 1479 354.11 C 1479 355.9 1477.5 357 1476.21 357 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1417.5,363.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="77" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">FFmpeg<br />
|
||||
(recording)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="39" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 89.42 411.87 C 89.8 411.49 90.05 410.55 89.32 409.81 L 76.18 397.34 C 75.27 396.6 73.91 396.45 72.82 397.41 C 71.74 398.53 72.05 400.1 72.85 400.87 L 83.33 410.81 L 72.97 419.97 C 72.11 420.77 71.75 422.06 72.43 423.2 C 73.34 424.66 75.14 424.57 76.12 423.73 Z M 96.44 424.42 C 97.27 424.42 98.28 423.74 98.28 422.53 C 98.28 421.53 97.52 420.65 96.42 420.65 L 85.96 420.65 C 85.28 420.65 84.15 421.24 84.15 422.49 C 84.15 423.63 85.03 424.42 85.99 424.42 Z M 65.17 433.5 C 63.7 433.5 62.29 432.24 62.29 430.63 L 62.29 391.32 C 62.29 389.69 63.83 388.5 65.09 388.5 L 104.35 388.5 C 105.93 388.5 107.29 389.76 107.29 391.41 L 107.29 430.61 C 107.29 432.4 105.79 433.5 104.5 433.5 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(18.5,440.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="131" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">GStreamer<br />
|
||||
(mp4 broadcaster)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="66" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">GStreamer<br>(mp4 broadcaster)<br></text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 107.29 411 L 347.76 411" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 355.76 411 L 347.76 415 L 347.76 407 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="217" y="404" width="30" height="17" stroke-width="0"/>
|
||||
<text x="231.29" y="415.5">RTP</text>
|
||||
</g>
|
||||
<path d="M 780 382 L 794 382 L 794 396 L 800 396 L 800 386 L 820 406 L 800 426 L 800 416 L 794 416 L 794 430 L 780 430 L 780 436 L 790 436 L 770 456 L 750 436 L 760 436 L 760 430 L 746 430 L 746 416 L 740 416 L 740 426 L 720 406 L 740 386 L 740 396 L 746 396 L 746 382 L 760 382 L 760 376 L 750 376 L 770 356 L 790 376 L 780 376 Z" fill="url(#mx-gradient-70a9ff-1-2e89ff-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(831.5,394.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="77" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(46, 137, 255); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Router 2</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="39" y="21" fill="#2E89FF" text-anchor="middle" font-size="20px" font-family="Helvetica">Router 2</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 780 172 L 794 172 L 794 186 L 800 186 L 800 176 L 820 196 L 800 216 L 800 206 L 794 206 L 794 220 L 780 220 L 780 226 L 790 226 L 770 246 L 750 226 L 760 226 L 760 220 L 746 220 L 746 206 L 740 206 L 740 216 L 720 196 L 740 176 L 740 186 L 746 186 L 746 172 L 760 172 L 760 166 L 750 166 L 770 146 L 790 166 L 780 166 Z" fill="url(#mx-gradient-70a9ff-1-2e89ff-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(731.5,252.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="77" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(46, 137, 255); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Router 1</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="39" y="21" fill="#2E89FF" text-anchor="middle" font-size="20px" font-family="Helvetica">Router 1</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="325" y="761" width="425" height="450" rx="12.75" ry="12.75" fill="url(#mx-gradient-ffffff-1-e3e3e3-1-s-0)" stroke="#616161" stroke-width="2" pointer-events="none"/>
|
||||
<g transform="translate(496.5,1221.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="80" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(97, 97, 97); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Worker 2</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="40" y="21" fill="#616161" text-anchor="middle" font-size="20px" font-family="Helvetica">Worker 2</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="819.5" y="548.5" width="155" height="130" rx="19.5" ry="19.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(932.5,613.5)rotate(-90,49.5,0)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="99" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 101px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PipeTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="50" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PipeTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 846.5 598.5 L 936.5 598.5 L 936.5 598.5 L 946.5 613.5 L 936.5 628.5 L 936.5 628.5 L 846.5 628.5 L 856.5 613.5 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" transform="rotate(90,896.5,613.5)" pointer-events="none"/>
|
||||
<g transform="translate(866.5,604.5)rotate(-90,59.5,8.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 770 456 L 888.74 542.95" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 895.2 547.68 L 886.38 546.18 L 891.1 539.73 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 642 1022 L 656 1022 L 656 1036 L 662 1036 L 662 1026 L 682 1046 L 662 1066 L 662 1056 L 656 1056 L 656 1070 L 642 1070 L 642 1076 L 652 1076 L 632 1096 L 612 1076 L 622 1076 L 622 1070 L 608 1070 L 608 1056 L 602 1056 L 602 1066 L 582 1046 L 602 1026 L 602 1036 L 608 1036 L 608 1022 L 622 1022 L 622 1016 L 612 1016 L 632 996 L 652 1016 L 642 1016 Z" fill="url(#mx-gradient-70a9ff-1-2e89ff-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(593.5,1102.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="77" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(46, 137, 255); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Router 3</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="39" y="21" fill="#2E89FF" text-anchor="middle" font-size="20px" font-family="Helvetica">Router 3</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="554.5" y="791" width="155" height="130" rx="19.5" ry="19.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(667.5,856.5)rotate(-90,49.5,0)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="99" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 101px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PipeTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="50" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PipeTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 582 841 L 672 841 L 672 841 L 682 856 L 672 871 L 672 871 L 582 871 L 592 856 Z" fill="url(#mx-gradient-ea6b66-1-ff3333-1-s-0)" stroke="none" transform="rotate(90,632,856)" pointer-events="none"/>
|
||||
<g transform="translate(606.5,847.5)rotate(-90,55,8.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="110" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Producer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="55" y="17" fill="#FF3333" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Producer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="785" y="761" width="425" height="450" rx="12.75" ry="12.75" fill="url(#mx-gradient-ffffff-1-e3e3e3-1-s-0)" stroke="#616161" stroke-width="2" pointer-events="none"/>
|
||||
<g transform="translate(956.5,1221.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="80" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(97, 97, 97); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Worker 3</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="40" y="21" fill="#616161" text-anchor="middle" font-size="20px" font-family="Helvetica">Worker 3</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="824.5" y="791" width="150" height="130" rx="19.5" ry="19.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(932.5,856.5)rotate(-90,49.5,0)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="99" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 101px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PipeTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="50" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PipeTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 847 841 L 937 841 L 937 841 L 947 856 L 937 871 L 937 871 L 847 871 L 857 856 Z" fill="url(#mx-gradient-ea6b66-1-ff3333-1-s-0)" stroke="none" transform="rotate(90,897,856)" pointer-events="none"/>
|
||||
<g transform="translate(871.5,847.5)rotate(-90,55,8.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="110" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Producer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="55" y="17" fill="#FF3333" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Producer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 907.5 1022 L 921.5 1022 L 921.5 1036 L 927.5 1036 L 927.5 1026 L 947.5 1046 L 927.5 1066 L 927.5 1056 L 921.5 1056 L 921.5 1070 L 907.5 1070 L 907.5 1076 L 917.5 1076 L 897.5 1096 L 877.5 1076 L 887.5 1076 L 887.5 1070 L 873.5 1070 L 873.5 1056 L 867.5 1056 L 867.5 1066 L 847.5 1046 L 867.5 1026 L 867.5 1036 L 873.5 1036 L 873.5 1022 L 887.5 1022 L 887.5 1016 L 877.5 1016 L 897.5 996 L 917.5 1016 L 907.5 1016 Z" fill="url(#mx-gradient-70a9ff-1-2e89ff-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(858.5,1102.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="77" height="22" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(46, 137, 255); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Router 4</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="39" y="21" fill="#2E89FF" text-anchor="middle" font-size="20px" font-family="Helvetica">Router 4</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 633 679 L 632.09 780.76" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 632.02 788.76 L 628.09 780.73 L 636.09 780.8 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="618" y="727" width="30" height="17" stroke-width="0"/>
|
||||
<text x="631.5" y="739.5">RTP</text>
|
||||
</g>
|
||||
<path d="M 897 679 L 899.73 780.77" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 899.94 788.76 L 895.73 780.87 L 903.72 780.66 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="883" y="727" width="30" height="17" stroke-width="0"/>
|
||||
<text x="897.5" y="739.48">RTP</text>
|
||||
</g>
|
||||
<path d="M 632 921 L 632 985.76" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 632 993.76 L 628 985.76 L 636 985.76 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 900 921 L 898.27 985.77" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 898.06 993.76 L 894.27 985.66 L 902.27 985.87 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1443.63 992.8 L 1484.45 992.8 L 1484.45 972.64 L 1443.63 972.64 Z M 1442.65 995.79 C 1441.41 995.79 1440.08 994.91 1440.08 993.59 L 1440.08 971.8 C 1440.08 970.74 1441.14 969.65 1442.69 969.65 L 1485.4 969.65 C 1486.96 969.65 1488 970.77 1488 971.79 L 1488 993.5 C 1488 994.82 1486.89 995.79 1485.27 995.79 L 1469.72 995.79 C 1469.41 996.7 1469.11 997.67 1469.05 998.49 C 1468.92 1000.19 1470.19 1000.67 1472.47 1000.94 C 1473.99 1001.1 1475.34 1001.13 1476.78 1001.16 C 1477.66 1001.16 1478.5 1001.7 1478.5 1002.58 C 1478.5 1003.42 1477.78 1004 1476.8 1004 L 1451.34 1004 C 1450.44 1004 1449.67 1003.38 1449.67 1002.58 C 1449.67 1001.86 1450.34 1001.16 1451.34 1001.16 C 1453.02 1001.11 1454.73 1001.11 1456.49 1000.82 C 1458.19 1000.55 1459.23 1000.02 1459.04 998.4 C 1458.97 997.67 1458.67 996.7 1458.36 995.79 Z M 1431.21 956.96 L 1450.73 956.96 L 1450.73 954.72 L 1431.21 954.72 Z M 1425 1000.27 L 1425 950.93 C 1425 949.24 1426.81 948 1428.4 948 L 1453.5 948 C 1455.25 948 1456.94 949.32 1456.94 950.93 L 1456.94 967.41 L 1442.56 967.41 C 1439.86 967.41 1437.42 969.52 1437.42 971.75 L 1437.42 985.33 L 1431.21 985.33 L 1431.21 987.57 L 1437.42 987.57 L 1437.42 992.05 L 1431.21 992.05 L 1431.21 994.29 L 1437.49 994.29 C 1438 996.65 1440.47 998.03 1442.55 998.03 L 1456.23 998.03 C 1456.23 998.21 1456.33 998.4 1456.32 998.54 C 1455.42 998.79 1453.39 998.92 1451.68 998.92 C 1450.92 998.89 1450.27 998.97 1449.61 999.2 C 1448.96 999.42 1448.39 999.78 1447.9 1000.27 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1418.5,1010.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="76" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br />
|
||||
(viewer)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="38" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1459.2 1098.25 C 1459.4 1098.25 1459.52 1098.06 1459.52 1097.85 C 1459.52 1097.67 1459.38 1097.5 1459.21 1097.5 L 1453.89 1097.5 C 1453.7 1097.5 1453.55 1097.63 1453.55 1097.85 C 1453.56 1098.11 1453.72 1098.25 1453.87 1098.25 Z M 1458.87 1134.63 C 1459.23 1134.63 1459.52 1134.37 1459.52 1134.18 L 1459.52 1133.57 C 1459.52 1133.26 1459.17 1133.08 1458.76 1133.08 L 1454.16 1133.08 C 1453.77 1133.08 1453.48 1133.34 1453.48 1133.54 L 1453.48 1134.14 C 1453.48 1134.36 1453.76 1134.63 1454.14 1134.63 Z M 1446.68 1130.92 L 1466.33 1130.92 L 1466.33 1100.47 L 1446.68 1100.47 Z M 1444.5 1100.49 C 1444.5 1098.29 1445.73 1096.39 1447.81 1095.52 C 1451.39 1094.36 1460.92 1094 1465.33 1095.64 C 1467.28 1096.49 1468.5 1098.19 1468.5 1100.54 L 1468.5 1131.73 C 1468.5 1133.34 1467.59 1135.58 1465.47 1136.5 C 1461.54 1137.97 1450.96 1138 1447.54 1136.41 C 1445.52 1135.46 1444.58 1133.7 1444.5 1131.85 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1418.5,1144.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="76" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br style="font-size: 16px" />
|
||||
(viewer)<br style="font-size: 16px" />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="38" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1175 976 L 1414.76 976" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1422.76 976 L 1414.76 980 L 1414.76 972 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="1281" y="969" width="39" height="17" stroke-width="0"/>
|
||||
<text x="1299" y="980.5">SRTP</text>
|
||||
</g>
|
||||
<path d="M 1175 1116 L 1434.26 1116" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1442.26 1116 L 1434.26 1120 L 1434.26 1112 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="1291" y="1109" width="39" height="17" stroke-width="0"/>
|
||||
<text x="1309" y="1120.5">SRTP</text>
|
||||
</g>
|
||||
<path d="M 948 1046 L 1012.66 983.14" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1018.4 977.56 L 1015.45 986 L 1009.87 980.27 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 948 1046 L 1012.66 1108.86" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 1018.4 1114.44 L 1009.87 1111.73 L 1015.45 1106 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 582 1046 L 517.34 983.14" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 511.6 977.56 L 520.13 980.27 L 514.55 986 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 582 1046 L 517.34 1108.86" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 511.6 1114.44 L 514.55 1106 L 520.13 1111.73 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 355 976 L 124.24 976" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 116.24 976 L 124.24 972 L 124.24 980 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="215" y="969" width="39" height="17" stroke-width="0"/>
|
||||
<text x="233" y="980.5">SRTP</text>
|
||||
</g>
|
||||
<path d="M 89.53 992.17 C 90.09 992.17 90.48 991.94 90.37 991.75 L 89.26 990 C 89.12 989.73 88.92 989.67 88.59 989.67 L 81.41 989.67 C 81.06 989.67 80.88 989.74 80.71 990.01 L 79.68 991.74 C 79.48 992.02 80.08 992.17 80.51 992.17 Z M 106.32 986.46 L 106.32 960.72 L 63.65 960.72 L 63.65 986.46 Z M 59 994.5 C 57.87 994.49 56.85 994.08 56.42 993.45 C 56 992.83 56.17 992.2 56.53 991.78 L 60.66 987.26 L 60.66 960.58 C 60.66 959.24 61.78 957.5 63.63 957.5 L 106.33 957.5 C 107.77 957.5 109.31 958.74 109.31 960.75 L 109.31 987.26 L 113.48 991.82 C 113.83 992.25 114 992.82 113.58 993.43 C 113.03 994.2 111.99 994.45 111.02 994.5 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(46.5,1001.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="76" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br />
|
||||
(viewer)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="38" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="354.86" y="1071" width="155" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(369.5,1168.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="124" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 126px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="62" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 382.36 1096 L 472.36 1096 L 472.36 1096 L 482.36 1111 L 472.36 1126 L 472.36 1126 L 382.36 1126 L 392.36 1111 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" transform="translate(432.36,0)scale(-1,1)translate(-432.36,0)" pointer-events="none"/>
|
||||
<g transform="translate(372.5,1132.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="354.86" y="931" width="155" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(369.5,1028.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="124" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 126px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="62" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 382.36 956 L 472.36 956 L 472.36 956 L 482.36 971 L 472.36 986 L 472.36 986 L 382.36 986 L 392.36 971 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" transform="translate(432.36,0)scale(-1,1)translate(-432.36,0)" pointer-events="none"/>
|
||||
<g transform="translate(372.5,992.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="1019.86" y="931" width="155" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(1034.5,1028.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="124" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 126px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="62" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1047.36 956 L 1137.36 956 L 1137.36 956 L 1147.36 971 L 1137.36 986 L 1137.36 986 L 1047.36 986 L 1057.36 971 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1037.5,992.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="1019.86" y="1071" width="155" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(1034.5,1168.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="124" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 126px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="62" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1047.36 1096 L 1137.36 1096 L 1137.36 1096 L 1147.36 1111 L 1137.36 1126 L 1137.36 1126 L 1047.36 1126 L 1057.36 1111 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1037.5,1132.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 89.53 1127.17 C 90.09 1127.17 90.48 1126.94 90.37 1126.75 L 89.26 1125 C 89.12 1124.73 88.92 1124.67 88.59 1124.67 L 81.41 1124.67 C 81.06 1124.67 80.88 1124.74 80.71 1125.01 L 79.68 1126.74 C 79.48 1127.02 80.08 1127.17 80.51 1127.17 Z M 106.32 1121.46 L 106.32 1095.72 L 63.65 1095.72 L 63.65 1121.46 Z M 59 1129.5 C 57.87 1129.49 56.85 1129.08 56.42 1128.45 C 56 1127.83 56.17 1127.2 56.53 1126.78 L 60.66 1122.26 L 60.66 1095.58 C 60.66 1094.24 61.78 1092.5 63.63 1092.5 L 106.33 1092.5 C 107.77 1092.5 109.31 1093.74 109.31 1095.75 L 109.31 1122.26 L 113.48 1126.82 C 113.83 1127.25 114 1127.82 113.58 1128.43 C 113.03 1129.2 111.99 1129.45 111.02 1129.5 Z" fill="#505050" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(46.5,1136.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="76" height="36" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(120, 120, 120); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Participant<br />
|
||||
(viewer)<br />
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="38" y="26" fill="#787878" text-anchor="middle" font-size="16px" font-family="Helvetica">[Not supported by viewer]</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 355 1116 L 119.24 1114.08" fill="none" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<path d="M 111.24 1114.02 L 119.27 1110.08 L 119.2 1118.08 Z" fill="#999999" stroke="#999999" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
|
||||
<g fill="#999999" font-family="Helvetica" text-anchor="middle" font-size="14px">
|
||||
<rect fill="#ffffff" stroke="none" x="213" y="1108" width="39" height="17" stroke-width="0"/>
|
||||
<text x="231" y="1119.5">SRTP</text>
|
||||
</g>
|
||||
<rect x="1015" y="95.5" width="160" height="150" rx="22.5" ry="22.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(1031.5,253.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="125" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 125px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">WebRtcTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="63" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">WebRtcTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1045 109 L 1135 109 L 1135 109 L 1145 124 L 1135 139 L 1135 139 L 1045 139 L 1055 124 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1035.5,145.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Audio Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Audio Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1045 184 L 1135 184 L 1135 184 L 1145 199 L 1135 214 L 1135 214 L 1045 214 L 1055 199 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1035.5,220.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Video Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Video Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
<rect x="1020" y="289" width="155" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#666666" stroke-width="2" stroke-dasharray="2 4" pointer-events="none"/>
|
||||
<g transform="translate(1032.5,386.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="128" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(102, 102, 102); line-height: 1.2; vertical-align: top; width: 130px; white-space: nowrap; overflow-wrap: normal; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">PlainRtpTransport</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="64" y="17" fill="#666666" text-anchor="middle" font-size="16px" font-family="Helvetica">PlainRtpTransport</text>
|
||||
</switch>
|
||||
</g>
|
||||
<path d="M 1047.5 314 L 1137.5 314 L 1137.5 314 L 1147.5 329 L 1137.5 344 L 1137.5 344 L 1047.5 344 L 1057.5 329 Z" fill="url(#mx-gradient-66cc00-1-4d9900-1-s-0)" stroke="none" pointer-events="none"/>
|
||||
<g transform="translate(1037.5,350.5)">
|
||||
<switch>
|
||||
<foreignObject style="overflow:visible;" pointer-events="all" width="119" height="17" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(77, 153, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Audio Consumer</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="60" y="17" fill="#4D9900" text-anchor="middle" font-size="16px" font-family="Helvetica">Audio Consumer</text>
|
||||
</switch>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 55 KiB |
BIN
MiroTalk SFU/public/images/audio.gif
Normal file
After Width: | Height: | Size: 460 KiB |
BIN
MiroTalk SFU/public/images/background.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
MiroTalk SFU/public/images/broadcasting.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
MiroTalk SFU/public/images/browsers.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
MiroTalk SFU/public/images/chatgpt.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
1
MiroTalk SFU/public/images/cta-illustration.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="160" height="187" xmlns="http://www.w3.org/2000/svg"><g fill="#0270D7" fill-rule="evenodd"><path fill-opacity=".24" d="M110.211 0l49.45 89.211-89.21 49.45L21 49.452z"/><path fill-opacity=".16" d="M33.812 171.385l-18.385 15.427L0 168.427 18.385 153z"/></g></svg>
|
After Width: | Height: | Size: 273 B |
BIN
MiroTalk SFU/public/images/delete.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
MiroTalk SFU/public/images/docker.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
MiroTalk SFU/public/images/email.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
MiroTalk SFU/public/images/exit.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
1
MiroTalk SFU/public/images/feature-icon-01.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="112" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><linearGradient x1="99.316%" y1="21.974%" x2="0%" y2="69.777%" id="b"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="48.131%"/><stop stop-color="#2C3039" offset="100%"/></linearGradient><linearGradient x1="49.892%" y1=".428%" x2="24.856%" y2="100%" id="d"><stop stop-color="#3B404C" offset="0%"/><stop stop-color="#333843" offset="100%"/></linearGradient><path d="M32.833 63.264c-14.9 1.866-25.108-6.384-22.797-18.428 2.31-12.043 16.264-23.319 31.166-25.184C56.103 17.786 66.31 26.036 64 38.08c-2.311 12.043-16.264 23.319-31.167 25.184z" id="c"/></defs><g fill="none" fill-rule="evenodd"><path fill="#0270D7" d="M35.521 6.938L12.04 35.843l48.939 16.136L84.46 23.073z"/><path fill="#02CBB1" d="M20 65.494L35.822 74 36 26.506 20.176 18z"/><g transform="translate(28 31)"><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M1 0h40v40H1z"/><path d="M11.261 54.752l-9.71-18.785C.096 33.152-.389 29.783.327 26.051 2.637 14.01 16.59 2.732 31.492.867 41.776-.42 49.824 3.11 53.065 9.38l9.71 18.785c-3.242-6.27-11.29-9.8-21.573-8.514C26.3 21.518 12.347 32.793 10.036 44.837c-.716 3.732-.23 7.1 1.225 9.915" fill="url(#b)"/><use fill="url(#d)" xlink:href="#c"/></g><path fill="#00BFFB" d="M22.991 85.677l.826-6.614L7.855 84.8l-.825 6.616z"/><path fill-opacity=".32" fill="#00BFFB" d="M106.721 46.737l4.408-2.801-13.699-6.737L93.022 40z"/></g></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
MiroTalk SFU/public/images/feature-icon-02.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="108" height="100" xmlns="http://www.w3.org/2000/svg"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><linearGradient x1="17.713%" y1="0%" x2="77.754%" y2="68.424%" id="b"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="100%"/></linearGradient><linearGradient x1="49.892%" y1=".428%" x2="24.856%" y2="100%" id="c"><stop stop-color="#3B404C" offset="0%"/><stop stop-color="#333843" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path fill-opacity=".32" fill="#00BFFB" d="M31.292 84.984l1.313-5.055-14.613 4.415-1.313 5.056z"/><path d="M41.203 74.416L.222 46.516l30.541-21.314 23.908 16.277-11.69 10.84-1.706 22-.072.097z" fill="#0270D7"/><path fill="#00BFFB" d="M103.305 14.443l4.556-4.866-16.287-4.74-4.556 4.867z"/><path fill="#02CBB1" d="M56.9 77.244L54.771 92.89 94.416 77.84l2.128-15.648z"/><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M31.778 38.241h40v40h-40z" transform="translate(.222 -2.241)"/><path d="M88.023 31.352a2.962 2.962 0 0 0-1.296-1.359l-29.464-15.06a2.888 2.888 0 0 0-2.634.001L25.147 30.03a2.972 2.972 0 0 0-1.298 1.361l32.078 16.398 32.096-16.436z" fill="url(#b)" fill-rule="nonzero" transform="rotate(31 66.542 55.443)"/><path d="M43.266 11.908a3.154 3.154 0 0 0-.96.977L23.763 43.707c-.586.974-.605 2.174-.048 3.1l16.423 27.335c.228.379.543.693.917.917l20.09-33.39-17.878-29.76z" fill="#2C3039" fill-rule="nonzero"/><path d="M38.935 50.59v38.956a3.04 3.04 0 0 0 1.35-.3L70.47 74.263a2.994 2.994 0 0 0 1.67-2.697V35.608a2.98 2.98 0 0 0-.342-1.33L38.935 50.59z" fill="url(#c)" transform="rotate(31 66.143 86.153)"/></g></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
MiroTalk SFU/public/images/feature-icon-03.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="103" height="100" xmlns="http://www.w3.org/2000/svg"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><linearGradient x1="49.892%" y1=".428%" x2="24.856%" y2="100%" id="b"><stop stop-color="#3B404C" offset="0%"/><stop stop-color="#333843" offset="100%"/></linearGradient><linearGradient x1="17.713%" y1="0%" x2="77.754%" y2="68.424%" id="c"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M48.028 64.452L.086 77.076l3.95-37.033 27.97-7.364c.1 3.076.27 8.387.512 15.934l15.485 15.72.025.119z" fill="#0270D7"/><path fill="#02CBB1" d="M91.767 72.042l2.455-13.396L58.895 70.67 56.44 84.067z"/><path fill="#00BFFB" d="M40.783 98.37l6.378-1.937-11.735-12.248-6.379 1.937z"/><path fill-opacity=".32" fill="#00BFFB" d="M23.783 14.37l6.378-1.937L18.426.185l-6.379 1.937z"/><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M50 43h40v40H50z" transform="translate(-16 -12)"/><path d="M51.759 16.34a.94.94 0 0 1 .922.399l23.35 40.193c.096.151.143.35.143.545-.001.629-.481 1.21-1.067 1.292l-46.872 6.553a.909.909 0 0 1-.527-.081c-.507-.237-.688-.912-.39-1.5L50.84 16.996c.076-.134.183-.262.307-.372.19-.16.403-.255.612-.283" fill="url(#b)" transform="rotate(27 42.978 77.641)"/><path d="M25.338.52c-.01-.006-.022-.01-.033-.017a.893.893 0 0 0-.174-.066c-.01-.002-.022.001-.034-.001a.925.925 0 0 0-.346-.018 1.064 1.064 0 0 0-.315.096l-.004.001c-.06.03-.12.064-.178.105a1.172 1.172 0 0 0-.107.083l-.008.008a1.495 1.495 0 0 0-.295.368L.616 48.344a1.469 1.469 0 0 0-.064.148c-.02.057-.02.113-.033.171-.012.058-.028.116-.033.174-.007.084.002.164.012.246.007.052.006.106.02.156a.99.99 0 0 0 .103.233c.02.037.031.08.056.113a.877.877 0 0 0 .28.25l26.938 14.927a.868.868 0 0 1-.28-.252c-.024-.034-.037-.076-.057-.113-.04-.075-.08-.15-.103-.232-.013-.051-.013-.104-.02-.156-.01-.082-.02-.163-.012-.248.005-.058.021-.115.033-.173.024-.107.046-.216.097-.32L50.78 16.006c.076-.136.18-.265.304-.376.091-.08.19-.142.289-.19a.96.96 0 0 1 .662-.078.95.95 0 0 1 .24.084L25.337.52z" transform="rotate(27 42.028 77.95)" fill="url(#c)" fill-rule="nonzero"/></g></svg>
|
After Width: | Height: | Size: 2.2 KiB |
1
MiroTalk SFU/public/images/feature-icon-04.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="98" height="100" xmlns="http://www.w3.org/2000/svg"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><linearGradient x1="49.892%" y1=".428%" x2="24.856%" y2="100%" id="b"><stop stop-color="#3B404C" offset="0%"/><stop stop-color="#333843" offset="100%"/></linearGradient><linearGradient x1="17.713%" y1="0%" x2="77.754%" y2="68.424%" id="c"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M49.028 61.452L1.086 74.076l3.95-37.033 27.97-7.364c.1 3.076.27 8.387.512 15.934l15.485 15.72.025.119z" fill="#0270D7"/><path fill-opacity=".32" fill="#00BFFB" d="M23.725 84.328l-5.66 3.52 14.505 8.794 5.66-3.522z"/><path fill="#02CBB1" d="M89.345 72.466l-1.72-15.697L52.8 80.964l1.72 15.698z"/><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M44 41h40v40H44z" transform="translate(-15 -10)"/><path fill="url(#b)" d="M37.841 71.977L0 54.169 37.231 0z" transform="rotate(-36 55.277 18.264)"/><path fill="url(#c)" fill-rule="nonzero" transform="scale(-1 1) rotate(36 .538 -153.515)" d="M73.788 71.977L37.229 54 74.4 0z"/><path fill-opacity=".32" fill="#00BFFB" d="M58.57 10.221l-1.048 5.117 14.362-5.174 1.047-5.118z"/></g></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
MiroTalk SFU/public/images/feature-icon-05.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="98" height="100" xmlns="http://www.w3.org/2000/svg"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><linearGradient x1="7.786%" y1="0%" x2="90.938%" y2="49.407%" id="b"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M38 48h40v40H38z" transform="translate(-9 -17)"/><path fill="#02CBB1" d="M86.755 88.926l3.46-15.26-39.363 10.387-3.459 15.261z"/><path fill="#0270D7" d="M90.735 53.81l7.137-28.53-77.08 20.354-7.137 28.533z"/><path fill-opacity=".32" fill="#00BFFB" d="M77.35 14.62l6.442-1.712-11.3-12.65-6.443 1.713z"/><path fill="#474C59" d="M46.63 33.718L28.384 61.923l43.659 19.72 18.244-28.206z"/><path fill="#00BFFB" d="M29.746 92.298l3.792-3.59-14.732-4-3.793 3.59z"/><path fill="#2C3039" fill-rule="nonzero" d="M17.685 36.372l10.7 25.55 18.339-28.026L35.015 8.122z"/><path fill="url(#b)" fill-rule="nonzero" d="M49.401 21.254L1.988 27.601l23.588 15.653 47.412-6.346z" transform="rotate(32 52.468 75.451)"/></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
MiroTalk SFU/public/images/feature-icon-06.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="115" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter x="-90%" y="-90%" width="280%" height="280%" filterUnits="objectBoundingBox" id="a"><feGaussianBlur stdDeviation="12" in="SourceGraphic"/></filter><path id="b" d="M0 .856h63.533v59.675H0z"/><linearGradient x1="56.146%" y1="10.87%" x2="25.695%" y2="72.649%" id="c"><stop stop-color="#2C3039" offset="0%"/><stop stop-color="#8A94A7" offset="48.131%"/><stop stop-color="#2C3039" offset="100%"/></linearGradient><path id="e" d="M.062.344h40.511v44.1H.062z"/><linearGradient x1="49.892%" y1=".428%" x2="24.856%" y2="100%" id="f"><stop stop-color="#3B404C" offset="0%"/><stop stop-color="#333843" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path fill="#0270D7" d="M23.302 63.083L.112 44.995l73.273-31.416 23.19 18.091z"/><path fill="#00BFFB" d="M35.902 83.663l1.17-6.562-16.24 4.895-1.17 6.563z"/><path fill-opacity=".32" fill="#00BFFB" d="M41.972 92.478l-2.962 3.376 11.56 2.714 2.961-3.376z"/><path fill-opacity=".48" fill="#1D2026" filter="url(#a)" d="M36.056 33.707h40v40h-40z" transform="rotate(16 55.276 48.942)"/><g transform="rotate(16 -28.89 116.929)"><mask id="d" fill="#fff"><use xlink:href="#b"/></mask><path d="M32.628 40.394c.06-.485.116-.972.204-1.45.055-.295.135-.583.2-.874.096-.427.181-.856.296-1.276.084-.303.192-.596.286-.894.128-.401.246-.808.393-1.202.05-.141.113-.275.169-.414.195-.5.4-.997.624-1.483.103-.22.214-.434.322-.65a28.007 28.007 0 0 1 2.005-3.412c.07-.1.15-.192.219-.29.448-.622.922-1.222 1.418-1.801.172-.198.347-.391.523-.584.464-.508.946-.993 1.444-1.46.175-.162.343-.334.522-.493.13-.113.263-.22.392-.332a25.56 25.56 0 0 1 1.147-.91c.146-.11.291-.22.44-.325.356-.254.723-.49 1.093-.723.212-.134.42-.276.637-.402.428-.252.868-.48 1.311-.702.157-.08.307-.169.465-.244a22.326 22.326 0 0 1 1.727-.721c.162-.06.326-.111.49-.168.45-.155.905-.293 1.366-.417.178-.047.354-.097.532-.14a20.012 20.012 0 0 1 1.862-.362 18.96 18.96 0 0 1 1.675-.155c.175-.01.347-.008.52-.013.382-.008.76-.008 1.134.005a17.935 17.935 0 0 1 1.654.144c.174.022.347.042.518.07.44.071.874.161 1.301.266.075.019.154.03.229.05.508.132 1.003.29 1.49.467.143.05.28.11.42.166.347.136.691.282 1.025.44.288.135.575.268.852.419L31.118 2.89a18.16 18.16 0 0 0-.619-.319c-.075-.038-.156-.065-.233-.1-.337-.16-.68-.305-1.028-.442-.14-.055-.276-.115-.417-.165-.49-.176-.985-.335-1.493-.466l-.03-.01c-.063-.016-.13-.024-.192-.04-.43-.105-.865-.195-1.307-.267-.17-.027-.344-.047-.518-.07a17.934 17.934 0 0 0-1.654-.144 17.699 17.699 0 0 0-1.133-.004c-.174.004-.346.003-.52.012-.554.03-1.112.076-1.678.155a20.56 20.56 0 0 0-1.86.364c-.178.04-.355.09-.532.139-.46.122-.917.262-1.368.417-.162.055-.326.106-.488.168-.566.209-1.126.436-1.674.694l-.054.027c-.155.074-.304.162-.458.24a22.56 22.56 0 0 0-1.318.705c-.215.127-.421.268-.633.401-.276.174-.558.338-.826.524-.093.064-.181.135-.272.2-.148.106-.293.217-.438.325-.39.291-.77.594-1.145.91-.132.112-.264.219-.394.333-.065.058-.136.11-.2.169-.113.102-.21.22-.32.324-.5.465-.982.952-1.445 1.46-.097.106-.208.197-.303.304-.079.09-.143.19-.22.281a26.06 26.06 0 0 0-1.42 1.8c-.057.08-.125.152-.182.233-.013.018-.023.038-.036.057a26.58 26.58 0 0 0-1.459 2.366c-.047.087-.108.167-.156.253-.138.26-.26.528-.391.792-.107.217-.218.43-.32.65-.225.485-.43.98-.625 1.481-.054.14-.118.276-.17.417l-.029.07c-.135.368-.242.749-.361 1.126-.094.3-.204.594-.287.899-.119.425-.204.859-.3 1.29-.065.287-.143.57-.197.86-.09.484-.145.974-.205 1.463-.03.247-.08.488-.102.734-.07.74-.107 1.485-.108 2.233-.014 7.778 3.736 14.079 9.395 17.158L41.813 60.53c-5.66-3.08-9.41-9.38-9.395-17.156.001-.75.037-1.495.107-2.235.024-.25.072-.496.103-.746" fill="url(#c)" mask="url(#d)"/></g><g transform="rotate(16 -109.581 222.973)"><mask id="g" fill="#fff"><use xlink:href="#e"/></mask><path d="M20.358.531C31.545-1.04 40.595 7.473 40.574 19.548c-.023 12.075-9.11 23.137-20.297 24.71C9.09 45.83.04 37.316.062 25.24.084 13.166 9.172 2.103 20.358.531" fill="url(#f)" mask="url(#g)"/></g><path fill="#02CBB1" d="M114.324 47.62l-10.196-8.59-7.761 33.025 10.197 8.59z"/></g></svg>
|
After Width: | Height: | Size: 4.0 KiB |
BIN
MiroTalk SFU/public/images/feedback.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
MiroTalk SFU/public/images/forbidden.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
MiroTalk SFU/public/images/geolocation.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
MiroTalk SFU/public/images/github.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
1
MiroTalk SFU/public/images/hero-back-illustration.svg
Normal file
After Width: | Height: | Size: 10 KiB |
1
MiroTalk SFU/public/images/hero-top-illustration.svg
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
MiroTalk SFU/public/images/hide.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
MiroTalk SFU/public/images/loader.gif
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
MiroTalk SFU/public/images/loader2.gif
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
MiroTalk SFU/public/images/loading.gif
Normal file
After Width: | Height: | Size: 198 KiB |
BIN
MiroTalk SFU/public/images/lobby.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
MiroTalk SFU/public/images/locked.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
1
MiroTalk SFU/public/images/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="28" height="32" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="a"><stop stop-color="#00BFFB" offset="0%"/><stop stop-color="#0270D7" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="b"><stop stop-color="#1F232A" stop-opacity=".48" offset="0%"/><stop stop-color="#1F2329" stop-opacity="0" offset="100%"/></linearGradient><linearGradient x1="87.665%" y1="103.739%" x2="-3.169%" y2="38.807%" id="c"><stop stop-color="#FFF" stop-opacity="0" offset="0%"/><stop stop-color="#FFF" stop-opacity=".64" offset="100%"/></linearGradient><linearGradient x1="-14.104%" y1="111.262%" x2="109.871%" y2="26.355%" id="d"><stop stop-color="#0270D7" offset="0%"/><stop stop-color="#0270D7" stop-opacity="0" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path fill="url(#a)" transform="rotate(90 14 16)" d="M6 2l-8 13.999L6 30h16l8-14.001L22 2z"/><path fill="url(#b)" d="M14 0v32L0 24V8z"/><path fill="url(#c)" d="M28 24L0 8l14.001-8L28 8z"/><path fill-opacity=".48" fill="url(#d)" style="mix-blend-mode:multiply" d="M28 8L0 23.978V8l14.001-8L28 8z"/></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
MiroTalk SFU/public/images/maintenance.gif
Normal file
After Width: | Height: | Size: 608 KiB |
BIN
MiroTalk SFU/public/images/message.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
MiroTalk SFU/public/images/miroslav-pejic.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
MiroTalk SFU/public/images/mirotalk-logo.gif
Normal file
After Width: | Height: | Size: 4.9 MiB |
BIN
MiroTalk SFU/public/images/mirotalk-mc.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
MiroTalk SFU/public/images/mirotalksfu-header.gif
Normal file
After Width: | Height: | Size: 569 KiB |
BIN
MiroTalk SFU/public/images/mirotalksfu-header.png
Normal file
After Width: | Height: | Size: 425 KiB |
BIN
MiroTalk SFU/public/images/mirotalksfu-logo.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
MiroTalk SFU/public/images/mirotalksfu-qr.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
MiroTalk SFU/public/images/mirotalksfu.png
Normal file
After Width: | Height: | Size: 204 KiB |
BIN
MiroTalk SFU/public/images/mute.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
MiroTalk SFU/public/images/network.gif
Normal file
After Width: | Height: | Size: 3.9 MiB |
BIN
MiroTalk SFU/public/images/nginx.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
MiroTalk SFU/public/images/ngrok.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
MiroTalk SFU/public/images/participant.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
MiroTalk SFU/public/images/participants.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
MiroTalk SFU/public/images/pm2.png
Normal file
After Width: | Height: | Size: 17 KiB |
1
MiroTalk SFU/public/images/pricing-illustration.svg
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
MiroTalk SFU/public/images/recording.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
MiroTalk SFU/public/images/share.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
MiroTalk SFU/public/images/start.png
Normal file
After Width: | Height: | Size: 812 B |
BIN
MiroTalk SFU/public/images/stop.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
MiroTalk SFU/public/images/unhide.png
Normal file
After Width: | Height: | Size: 534 B |
BIN
MiroTalk SFU/public/images/unmute.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
MiroTalk SFU/public/images/user.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
MiroTalk SFU/public/images/video-share.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
183
MiroTalk SFU/public/js/Brand.js
Normal file
@ -0,0 +1,183 @@
|
||||
'use strict';
|
||||
|
||||
const brandDataKey = 'brandData';
|
||||
const brandData = window.sessionStorage.getItem(brandDataKey);
|
||||
|
||||
const title = document.getElementById('title');
|
||||
const icon = document.getElementById('icon');
|
||||
const appleTouchIcon = document.getElementById('appleTouchIcon');
|
||||
|
||||
const description = document.getElementById('description');
|
||||
const keywords = document.getElementById('keywords');
|
||||
|
||||
const ogType = document.getElementById('ogType');
|
||||
const ogSiteName = document.getElementById('ogSiteName');
|
||||
const ogTitle = document.getElementById('ogTitle');
|
||||
const ogDescription = document.getElementById('ogDescription');
|
||||
const ogImage = document.getElementById('ogImage');
|
||||
|
||||
const appTitle = document.getElementById('appTitle');
|
||||
const appDescription = document.getElementById('appDescription');
|
||||
|
||||
const features = document.getElementById('features');
|
||||
const teams = document.getElementById('teams');
|
||||
const tryEasier = document.getElementById('tryEasier');
|
||||
const poweredBy = document.getElementById('poweredBy');
|
||||
const sponsors = document.getElementById('sponsors');
|
||||
const advertisers = document.getElementById('advertisers');
|
||||
const footer = document.getElementById('footer');
|
||||
//...
|
||||
|
||||
// app/src/config.js - ui.brand
|
||||
let BRAND = {
|
||||
app: {
|
||||
name: 'MiroTalk SFU',
|
||||
title: 'MiroTalk SFU<br />Free browser based Real-time video calls.<br />Simple, Secure, Fast.',
|
||||
description:
|
||||
'Start your next video call with a single click. No download, plug-in, or login is required. Just get straight to talking, messaging, and sharing your screen.',
|
||||
},
|
||||
site: {
|
||||
title: 'MiroTalk SFU, Free Video Calls, Messaging and Screen Sharing',
|
||||
icon: '../images/logo.svg',
|
||||
appleTouchIcon: '../images/logo.svg',
|
||||
},
|
||||
meta: {
|
||||
description:
|
||||
'MiroTalk SFU powered by WebRTC and mediasoup, Real-time Simple Secure Fast video calls, messaging and screen sharing capabilities in the browser.',
|
||||
keywords:
|
||||
'webrtc, miro, mediasoup, mediasoup-client, self hosted, voip, sip, real-time communications, chat, messaging, meet, webrtc stun, webrtc turn, webrtc p2p, webrtc sfu, video meeting, video chat, video conference, multi video chat, multi video conference, peer to peer, p2p, sfu, rtc, alternative to, zoom, microsoft teams, google meet, jitsi, meeting',
|
||||
},
|
||||
og: {
|
||||
type: 'app-webrtc',
|
||||
siteName: 'MiroTalk SFU',
|
||||
title: 'Click the link to make a call.',
|
||||
description: 'MiroTalk SFU calling provides real-time video calls, messaging and screen sharing.',
|
||||
image: 'https://sfu.mirotalk.com/images/mirotalksfu.png',
|
||||
},
|
||||
html: {
|
||||
features: true,
|
||||
teams: true,
|
||||
tryEasier: true,
|
||||
poweredBy: true,
|
||||
sponsors: true,
|
||||
advertisers: true,
|
||||
footer: true,
|
||||
},
|
||||
//...
|
||||
};
|
||||
|
||||
async function initialize() {
|
||||
await getBrand();
|
||||
|
||||
customizeSite();
|
||||
|
||||
customizeMetaTags();
|
||||
|
||||
customizeOpenGraph();
|
||||
|
||||
customizeApp();
|
||||
|
||||
checkBrand();
|
||||
}
|
||||
|
||||
async function getBrand() {
|
||||
if (brandData) {
|
||||
setBrand(JSON.parse(brandData));
|
||||
} else {
|
||||
try {
|
||||
const response = await fetch('/brand', { timeout: 5000 });
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const data = await response.json();
|
||||
const serverBrand = data.message;
|
||||
if (serverBrand) {
|
||||
setBrand(serverBrand);
|
||||
console.log('FETCH BRAND SETTINGS', {
|
||||
serverBrand: serverBrand,
|
||||
clientBrand: BRAND,
|
||||
});
|
||||
window.sessionStorage.setItem(brandDataKey, JSON.stringify(serverBrand));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('FETCH GET BRAND ERROR', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BRAND configurations
|
||||
function setBrand(data) {
|
||||
BRAND = data;
|
||||
console.log('Set Brand done');
|
||||
}
|
||||
|
||||
// BRAND check
|
||||
function checkBrand() {
|
||||
!BRAND.html.features && elementDisplay(features, false);
|
||||
!BRAND.html.teams && elementDisplay(teams, false);
|
||||
!BRAND.html.tryEasier && elementDisplay(tryEasier, false);
|
||||
!BRAND.html.poweredBy && elementDisplay(poweredBy, false);
|
||||
!BRAND.html.sponsors && elementDisplay(sponsors, false);
|
||||
!BRAND.html.advertisers && elementDisplay(advertisers, false);
|
||||
!BRAND.html.footer && elementDisplay(footer, false);
|
||||
}
|
||||
|
||||
// ELEMENT display mode
|
||||
function elementDisplay(element, display, mode = 'block') {
|
||||
if (!element) return;
|
||||
element.style.display = display ? mode : 'none';
|
||||
}
|
||||
|
||||
// APP customize
|
||||
function customizeApp() {
|
||||
if (appTitle) {
|
||||
appTitle.innerHTML = BRAND.app.title;
|
||||
}
|
||||
if (appDescription) {
|
||||
appDescription.textContent = BRAND.app.description;
|
||||
}
|
||||
}
|
||||
|
||||
// SITE metadata
|
||||
function customizeSite() {
|
||||
if (title) {
|
||||
title.textContent = BRAND.site.title;
|
||||
}
|
||||
if (icon) {
|
||||
icon.href = BRAND.site.icon;
|
||||
}
|
||||
if (appleTouchIcon) {
|
||||
appleTouchIcon.href = BRAND.site.appleTouchIcon;
|
||||
}
|
||||
}
|
||||
|
||||
// SEO metadata
|
||||
function customizeMetaTags() {
|
||||
if (description) {
|
||||
description.content = BRAND.meta.description;
|
||||
}
|
||||
if (keywords) {
|
||||
keywords.content = BRAND.meta.keywords;
|
||||
}
|
||||
}
|
||||
|
||||
// SOCIAL MEDIA SHARING metadata
|
||||
function customizeOpenGraph() {
|
||||
if (ogType) {
|
||||
ogType.content = BRAND.og.type;
|
||||
}
|
||||
if (ogSiteName) {
|
||||
ogSiteName.content = BRAND.og.siteName;
|
||||
}
|
||||
if (ogTitle) {
|
||||
ogTitle.content = BRAND.og.title;
|
||||
}
|
||||
if (ogDescription) {
|
||||
ogDescription.content = BRAND.og.description;
|
||||
}
|
||||
if (ogImage) {
|
||||
ogImage.content = BRAND.og.image;
|
||||
}
|
||||
}
|
||||
|
||||
initialize();
|
83
MiroTalk SFU/public/js/Helpers.js
Normal file
@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
class MixedAudioRecorder {
|
||||
constructor(useGainNode = true) {
|
||||
this.useGainNode = useGainNode;
|
||||
this.gainNode = null;
|
||||
this.audioSources = [];
|
||||
this.audioDestination = null;
|
||||
this.audioContext = this.createAudioContext();
|
||||
}
|
||||
|
||||
createAudioContext() {
|
||||
if (window.AudioContext) {
|
||||
return new AudioContext();
|
||||
} else if (window.webkitAudioContext) {
|
||||
return new webkitAudioContext();
|
||||
} else if (window.mozAudioContext) {
|
||||
return new mozAudioContext();
|
||||
} else {
|
||||
throw new Error('Web Audio API is not supported in this browser');
|
||||
}
|
||||
}
|
||||
|
||||
getMixedAudioStream(audioStreams) {
|
||||
this.audioSources = [];
|
||||
|
||||
if (this.useGainNode) {
|
||||
this.gainNode = this.audioContext.createGain();
|
||||
this.gainNode.connect(this.audioContext.destination);
|
||||
this.gainNode.gain.value = 0;
|
||||
}
|
||||
|
||||
audioStreams.forEach((stream) => {
|
||||
if (!stream || !stream.getTracks().filter((t) => t.kind === 'audio').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Mixed audio tracks to add on MediaStreamAudioDestinationNode --->', stream.getTracks());
|
||||
|
||||
let audioSource = this.audioContext.createMediaStreamSource(stream);
|
||||
|
||||
if (this.useGainNode) {
|
||||
audioSource.connect(this.gainNode);
|
||||
}
|
||||
this.audioSources.push(audioSource);
|
||||
});
|
||||
|
||||
this.audioDestination = this.audioContext.createMediaStreamDestination();
|
||||
this.audioSources.forEach((audioSource) => {
|
||||
audioSource.connect(this.audioDestination);
|
||||
});
|
||||
|
||||
return this.audioDestination.stream;
|
||||
}
|
||||
|
||||
stopMixedAudioStream() {
|
||||
if (this.useGainNode) {
|
||||
this.gainNode.disconnect();
|
||||
this.gainNode = null;
|
||||
}
|
||||
if (this.audioSources.length) {
|
||||
this.audioSources.forEach((source) => {
|
||||
source.disconnect();
|
||||
});
|
||||
this.audioSources = [];
|
||||
}
|
||||
if (this.audioDestination) {
|
||||
this.audioDestination.disconnect();
|
||||
this.audioDestination = null;
|
||||
}
|
||||
if (this.audioContext) {
|
||||
this.audioContext.close();
|
||||
this.audioContext = null;
|
||||
}
|
||||
console.log('Stop Mixed Audio Stream');
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
// const audioRecorder = new MixedAudioRecorder();
|
||||
// To start recording, call audioRecorder.getMixedAudioStream(audioStreams);
|
||||
// To stop recording, call audioRecorder.stopMixedAudioStream();
|
||||
// Credits: https://github.com/muaz-khan/MultiStreamsMixer
|
163
MiroTalk SFU/public/js/LocalStorage.js
Normal file
@ -0,0 +1,163 @@
|
||||
'use-strict';
|
||||
|
||||
class LocalStorage {
|
||||
constructor() {
|
||||
this.MEDIA_TYPE = {
|
||||
audio: 'audio',
|
||||
video: 'video',
|
||||
audioVideo: 'audioVideo',
|
||||
speaker: 'speaker',
|
||||
};
|
||||
|
||||
this.INIT_CONFIG = {
|
||||
audio: true,
|
||||
video: true,
|
||||
audioVideo: true,
|
||||
};
|
||||
|
||||
this.SFU_SETTINGS = {
|
||||
share_on_join: true, // popup message on join
|
||||
show_chat_on_msg: true, // show chat on new message
|
||||
transcript_persistent_mode: false, // Prevent stop transcript in case of no-speech
|
||||
transcript_show_on_msg: true, // show transcript on new message
|
||||
speech_in_msg: false, // speech incoming message
|
||||
moderator_audio_start_muted: false, // Everyone starts muted in the room
|
||||
moderator_video_start_hidden: false, // Everyone starts hidden in the room
|
||||
moderator_audio_cant_unmute: false, // Everyone can't unmute themselves
|
||||
moderator_video_cant_unhide: false, // Everyone can't unhide themselves
|
||||
moderator_screen_cant_share: false, // Everyone can't share screen
|
||||
moderator_chat_cant_privately: false, // Everyone can't chat privately, only Public chat allowed
|
||||
moderator_chat_cant_chatgpt: false, // Everyone can't chat with ChatGPT
|
||||
moderator_disconnect_all_on_leave: false, // Disconnect all participants on leave room
|
||||
mic_auto_gain_control: false,
|
||||
mic_echo_cancellations: true,
|
||||
mic_noise_suppression: true,
|
||||
mic_sample_rate: 0, // 0: 48000 Hz 1: 44100 Hz
|
||||
mic_sample_size: 0, // 0: 16 bits 1: 32 bits
|
||||
mic_channel_count: 0, // 0: 1(mono) 1: 2 (stereo)
|
||||
mic_latency: 50, // ms
|
||||
mic_volume: 100, // %
|
||||
video_fps: 0, // default 1280x768 30fps
|
||||
screen_fps: 3, // default 5fps
|
||||
broadcasting: false, // default false (one to many a/v streaming)
|
||||
lobby: false, // default false
|
||||
pitch_bar: true, // volume indicator
|
||||
sounds: true, // room notify sounds
|
||||
host_ony_recording: false, // presenter
|
||||
rec_prioritize_h264: false, // Prioritize h.264 with AAC or h.264 with Opus codecs over VP8 with Opus or VP9 with Opus codecs
|
||||
rec_server: false, // The recording will be stored on the server rather than locally
|
||||
video_obj_fit: 2, // cover
|
||||
video_controls: 0, // off
|
||||
theme: 0, // dark
|
||||
theme_color: '#000000', // custom theme color
|
||||
theme_custom: false, // keep custom theme
|
||||
buttons_bar: 0, // vertical
|
||||
pin_grid: 0, // vertical
|
||||
};
|
||||
|
||||
this.DEVICES_COUNT = {
|
||||
audio: 0,
|
||||
speaker: 0,
|
||||
video: 0,
|
||||
};
|
||||
|
||||
this.LOCAL_STORAGE_DEVICES = {
|
||||
audio: {
|
||||
count: 0,
|
||||
index: 0,
|
||||
select: null,
|
||||
},
|
||||
speaker: {
|
||||
count: 0,
|
||||
index: 0,
|
||||
select: null,
|
||||
},
|
||||
video: {
|
||||
count: 0,
|
||||
index: 0,
|
||||
select: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// SET LOCAL STORAGE
|
||||
// ####################################################
|
||||
|
||||
setItemLocalStorage(key, value) {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
setObjectLocalStorage(name, object) {
|
||||
localStorage.setItem(name, JSON.stringify(object));
|
||||
}
|
||||
|
||||
setSettings(settings) {
|
||||
this.SFU_SETTINGS = settings;
|
||||
this.setObjectLocalStorage('SFU_SETTINGS', this.SFU_SETTINGS);
|
||||
}
|
||||
|
||||
setInitConfig(type, status) {
|
||||
switch (type) {
|
||||
case this.MEDIA_TYPE.audio:
|
||||
this.INIT_CONFIG.audio = status;
|
||||
break;
|
||||
case this.MEDIA_TYPE.video:
|
||||
this.INIT_CONFIG.video = status;
|
||||
break;
|
||||
case this.MEDIA_TYPE.audioVideo:
|
||||
this.INIT_CONFIG.audioVideo = status;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.setObjectLocalStorage('INIT_CONFIG', this.INIT_CONFIG);
|
||||
}
|
||||
|
||||
setLocalStorageDevices(type, index, select) {
|
||||
switch (type) {
|
||||
case this.MEDIA_TYPE.audio:
|
||||
this.LOCAL_STORAGE_DEVICES.audio.count = this.DEVICES_COUNT.audio;
|
||||
this.LOCAL_STORAGE_DEVICES.audio.index = index;
|
||||
this.LOCAL_STORAGE_DEVICES.audio.select = select;
|
||||
break;
|
||||
case this.MEDIA_TYPE.video:
|
||||
this.LOCAL_STORAGE_DEVICES.video.count = this.DEVICES_COUNT.video;
|
||||
this.LOCAL_STORAGE_DEVICES.video.index = index;
|
||||
this.LOCAL_STORAGE_DEVICES.video.select = select;
|
||||
break;
|
||||
case this.MEDIA_TYPE.speaker:
|
||||
this.LOCAL_STORAGE_DEVICES.speaker.count = this.DEVICES_COUNT.speaker;
|
||||
this.LOCAL_STORAGE_DEVICES.speaker.index = index;
|
||||
this.LOCAL_STORAGE_DEVICES.speaker.select = select;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.setObjectLocalStorage('LOCAL_STORAGE_DEVICES', this.LOCAL_STORAGE_DEVICES);
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// GET LOCAL STORAGE
|
||||
// ####################################################
|
||||
|
||||
getLocalStorageSettings() {
|
||||
return this.getObjectLocalStorage('SFU_SETTINGS');
|
||||
}
|
||||
|
||||
getLocalStorageInitConfig() {
|
||||
return this.getObjectLocalStorage('INIT_CONFIG');
|
||||
}
|
||||
|
||||
getLocalStorageDevices() {
|
||||
return this.getObjectLocalStorage('LOCAL_STORAGE_DEVICES');
|
||||
}
|
||||
|
||||
getItemLocalStorage(key) {
|
||||
localStorage.getItem(key);
|
||||
}
|
||||
|
||||
getObjectLocalStorage(name) {
|
||||
return JSON.parse(localStorage.getItem(name));
|
||||
}
|
||||
}
|
3910
MiroTalk SFU/public/js/Room.js
Normal file
6695
MiroTalk SFU/public/js/RoomClient.js
Normal file
242
MiroTalk SFU/public/js/Rules.js
Normal file
@ -0,0 +1,242 @@
|
||||
'use-strict';
|
||||
|
||||
let isPresenter = false;
|
||||
|
||||
// ####################################################
|
||||
// SHOW HIDE DESIRED BUTTONS BY RULES
|
||||
// ####################################################
|
||||
|
||||
const isRulesActive = true;
|
||||
|
||||
/**
|
||||
* WARNING!
|
||||
* This will be replaced by the ui.buttons specified in the server configuration file located at app/src/config.js.
|
||||
* Ensure that any changes made here are also reflected in the configuration file to maintain synchronization.
|
||||
*/
|
||||
let BUTTONS = {
|
||||
main: {
|
||||
shareButton: true, // for quest, presenter default true
|
||||
hideMeButton: true,
|
||||
startAudioButton: true,
|
||||
startVideoButton: true,
|
||||
startScreenButton: true,
|
||||
swapCameraButton: true,
|
||||
chatButton: true,
|
||||
raiseHandButton: true,
|
||||
transcriptionButton: true,
|
||||
whiteboardButton: true,
|
||||
emojiRoomButton: true,
|
||||
settingsButton: true,
|
||||
aboutButton: true, // Please keep me always visible, thank you!
|
||||
exitButton: true,
|
||||
},
|
||||
settings: {
|
||||
fileSharing: true,
|
||||
lockRoomButton: true, // presenter
|
||||
unlockRoomButton: true, // presenter
|
||||
broadcastingButton: true, // presenter
|
||||
lobbyButton: true, // presenter
|
||||
sendEmailInvitation: true, // presenter
|
||||
micOptionsButton: true, // presenter
|
||||
tabModerator: true, // presenter
|
||||
tabRecording: true,
|
||||
host_only_recording: true, // presenter
|
||||
pushToTalk: true,
|
||||
},
|
||||
producerVideo: {
|
||||
videoPictureInPicture: true,
|
||||
fullScreenButton: true,
|
||||
snapShotButton: true,
|
||||
muteAudioButton: true,
|
||||
videoPrivacyButton: true,
|
||||
},
|
||||
consumerVideo: {
|
||||
videoPictureInPicture: true,
|
||||
fullScreenButton: true,
|
||||
snapShotButton: true,
|
||||
sendMessageButton: true,
|
||||
sendFileButton: true,
|
||||
sendVideoButton: true,
|
||||
muteVideoButton: true,
|
||||
muteAudioButton: true,
|
||||
audioVolumeInput: true, // Disabled for mobile
|
||||
geolocationButton: true, // Presenter
|
||||
banButton: true, // presenter
|
||||
ejectButton: true, // presenter
|
||||
},
|
||||
videoOff: {
|
||||
sendMessageButton: true,
|
||||
sendFileButton: true,
|
||||
sendVideoButton: true,
|
||||
muteAudioButton: true,
|
||||
audioVolumeInput: true, // Disabled for mobile
|
||||
geolocationButton: true, // Presenter
|
||||
banButton: true, // presenter
|
||||
ejectButton: true, // presenter
|
||||
},
|
||||
chat: {
|
||||
chatPinButton: true,
|
||||
chatMaxButton: true,
|
||||
chatSaveButton: true,
|
||||
chatEmojiButton: true,
|
||||
chatMarkdownButton: true,
|
||||
chatSpeechStartButton: true,
|
||||
chatGPT: true,
|
||||
},
|
||||
participantsList: {
|
||||
saveInfoButton: true, // presenter
|
||||
sendFileAllButton: true, // presenter
|
||||
ejectAllButton: true, // presenter
|
||||
sendFileButton: false, // presenter & guests
|
||||
geoLocationButton: true, // presenter
|
||||
banButton: true, // presenter
|
||||
ejectButton: true, // presenter
|
||||
},
|
||||
whiteboard: {
|
||||
whiteboardLockButton: true, // presenter
|
||||
},
|
||||
//...
|
||||
};
|
||||
|
||||
function handleRules(isPresenter) {
|
||||
console.log('07.1 ----> IsPresenter: ' + isPresenter);
|
||||
if (!isRulesActive) return;
|
||||
if (!isPresenter) {
|
||||
// ##################################
|
||||
// GUEST
|
||||
// ##################################
|
||||
//BUTTONS.main.shareButton = false;
|
||||
BUTTONS.participantsList.saveInfoButton = false;
|
||||
BUTTONS.settings.lockRoomButton = false;
|
||||
BUTTONS.settings.unlockRoomButton = false;
|
||||
BUTTONS.settings.broadcastingButton = false;
|
||||
BUTTONS.settings.lobbyButton = false;
|
||||
BUTTONS.settings.sendEmailInvitation = false;
|
||||
BUTTONS.settings.micOptionsButton = false;
|
||||
BUTTONS.settings.tabModerator = false;
|
||||
BUTTONS.videoOff.muteAudioButton = false;
|
||||
BUTTONS.videoOff.geolocationButton = false;
|
||||
BUTTONS.videoOff.banButton = false;
|
||||
BUTTONS.videoOff.ejectButton = false;
|
||||
BUTTONS.consumerVideo.geolocationButton = false;
|
||||
BUTTONS.consumerVideo.banButton = false;
|
||||
BUTTONS.consumerVideo.ejectButton = false;
|
||||
//BUTTONS.consumerVideo.muteAudioButton = false;
|
||||
//BUTTONS.consumerVideo.muteVideoButton = false;
|
||||
BUTTONS.whiteboard.whiteboardLockButton = false;
|
||||
//...
|
||||
} else {
|
||||
// ##################################
|
||||
// PRESENTER
|
||||
// ##################################
|
||||
BUTTONS.main.shareButton = true;
|
||||
BUTTONS.settings.lockRoomButton = BUTTONS.settings.lockRoomButton && !isRoomLocked;
|
||||
BUTTONS.settings.unlockRoomButton = BUTTONS.settings.lockRoomButton && isRoomLocked;
|
||||
BUTTONS.settings.sendEmailInvitation = true;
|
||||
//...
|
||||
|
||||
// ##################################
|
||||
// Auto detected rules for presenter
|
||||
// ##################################
|
||||
|
||||
// Room broadcasting
|
||||
isBroadcastingEnabled = localStorageSettings.broadcasting;
|
||||
switchBroadcasting.checked = isBroadcastingEnabled;
|
||||
rc.roomAction('broadcasting', true, false);
|
||||
if (isBroadcastingEnabled) rc.toggleRoomBroadcasting();
|
||||
// Room lobby
|
||||
isLobbyEnabled = localStorageSettings.lobby;
|
||||
switchLobby.checked = isLobbyEnabled;
|
||||
rc.roomAction(isLobbyEnabled ? 'lobbyOn' : 'lobbyOff', true, false);
|
||||
// Room host-only-recording
|
||||
hostOnlyRecording = localStorageSettings.host_only_recording;
|
||||
switchHostOnlyRecording.checked = hostOnlyRecording;
|
||||
rc.roomAction(hostOnlyRecording ? 'hostOnlyRecordingOn' : 'hostOnlyRecordingOff', true, false);
|
||||
// Room moderator
|
||||
switchEveryoneMute.checked = localStorageSettings.moderator_audio_start_muted;
|
||||
switchEveryoneHidden.checked = localStorageSettings.moderator_video_start_hidden;
|
||||
switchEveryoneCantUnmute.checked = localStorageSettings.moderator_audio_cant_unmute;
|
||||
switchEveryoneCantUnhide.checked = localStorageSettings.moderator_video_cant_unhide;
|
||||
switchEveryoneCantShareScreen.checked = localStorageSettings.moderator_screen_cant_share;
|
||||
switchEveryoneCantChatPrivately.checked = localStorageSettings.moderator_chat_cant_privately;
|
||||
switchEveryoneCantChatChatGPT.checked = localStorageSettings.moderator_chat_cant_chatgpt;
|
||||
switchDisconnectAllOnLeave.checked = localStorageSettings.moderator_disconnect_all_on_leave;
|
||||
|
||||
// Update moderator settings...
|
||||
const moderatorData = {
|
||||
audio_start_muted: switchEveryoneMute.checked,
|
||||
video_start_hidden: switchEveryoneHidden.checked,
|
||||
audio_cant_unmute: switchEveryoneCantUnmute.checked,
|
||||
video_cant_unhide: switchEveryoneCantUnhide.checked,
|
||||
screen_cant_share: switchEveryoneCantShareScreen.checked,
|
||||
chat_cant_privately: switchEveryoneCantChatPrivately.checked,
|
||||
chat_cant_chatgpt: switchEveryoneCantChatChatGPT.checked,
|
||||
};
|
||||
rc.updateRoomModeratorALL(moderatorData);
|
||||
}
|
||||
// main. settings...
|
||||
BUTTONS.main.shareButton ? show(shareButton) : hide(shareButton);
|
||||
BUTTONS.settings.lockRoomButton ? show(lockRoomButton) : hide(lockRoomButton);
|
||||
BUTTONS.settings.unlockRoomButton ? show(unlockRoomButton) : hide(unlockRoomButton);
|
||||
BUTTONS.settings.broadcastingButton ? show(broadcastingButton) : hide(broadcastingButton);
|
||||
BUTTONS.settings.lobbyButton ? show(lobbyButton) : hide(lobbyButton);
|
||||
BUTTONS.settings.sendEmailInvitation ? show(sendEmailInvitation) : hide(sendEmailInvitation);
|
||||
!BUTTONS.settings.micOptionsButton && hide(micOptionsButton);
|
||||
!BUTTONS.settings.tabModerator && hide(tabModeratorBtn);
|
||||
BUTTONS.participantsList.saveInfoButton ? show(participantsSaveBtn) : hide(participantsSaveBtn);
|
||||
BUTTONS.whiteboard.whiteboardLockButton
|
||||
? elemDisplay('whiteboardLockButton', true)
|
||||
: elemDisplay('whiteboardLockButton', false, 'flex');
|
||||
//...
|
||||
}
|
||||
|
||||
function handleRulesBroadcasting() {
|
||||
console.log('07.2 ----> handleRulesBroadcasting');
|
||||
BUTTONS.main.shareButton = false;
|
||||
BUTTONS.main.hideMeButton = false;
|
||||
BUTTONS.main.startAudioButton = false;
|
||||
BUTTONS.main.startVideoButton = false;
|
||||
BUTTONS.main.startScreenButton = false;
|
||||
BUTTONS.main.swapCameraButton = false;
|
||||
//BUTTONS.main.raiseHandButton = false;
|
||||
BUTTONS.main.whiteboardButton = false;
|
||||
//BUTTONS.main.emojiRoomButton = false,
|
||||
BUTTONS.main.transcriptionButton = false;
|
||||
BUTTONS.main.settingsButton = false;
|
||||
BUTTONS.participantsList.saveInfoButton = false;
|
||||
BUTTONS.settings.lockRoomButton = false;
|
||||
BUTTONS.settings.unlockRoomButton = false;
|
||||
BUTTONS.settings.lobbyButton = false;
|
||||
BUTTONS.videoOff.muteAudioButton = false;
|
||||
BUTTONS.videoOff.geolocationButton = false;
|
||||
BUTTONS.videoOff.banButton = false;
|
||||
BUTTONS.videoOff.ejectButton = false;
|
||||
BUTTONS.consumerVideo.sendMessageButton = false;
|
||||
BUTTONS.consumerVideo.sendFileButton = false;
|
||||
BUTTONS.consumerVideo.sendVideoButton = false;
|
||||
BUTTONS.consumerVideo.geolocationButton = false;
|
||||
BUTTONS.consumerVideo.banButton = false;
|
||||
BUTTONS.consumerVideo.ejectButton = false;
|
||||
BUTTONS.consumerVideo.muteAudioButton = false;
|
||||
BUTTONS.consumerVideo.muteVideoButton = false;
|
||||
BUTTONS.whiteboard.whiteboardLockButton = false;
|
||||
//...
|
||||
elemDisplay('shareButton', false);
|
||||
elemDisplay('hideMeButton', false);
|
||||
elemDisplay('startAudioButton', false);
|
||||
elemDisplay('stopAudioButton', false);
|
||||
elemDisplay('startVideoButton', false);
|
||||
elemDisplay('stopVideoButton', false);
|
||||
elemDisplay('startScreenButton', false);
|
||||
elemDisplay('stopScreenButton', false);
|
||||
elemDisplay('swapCameraButton', false);
|
||||
//elemDisplay('raiseHandButton', false);
|
||||
elemDisplay('whiteboardButton', false);
|
||||
//elemDisplay('emojiRoomButton', false);
|
||||
elemDisplay('transcriptionButton', false);
|
||||
elemDisplay('lockRoomButton', false);
|
||||
elemDisplay('unlockRoomButton', false);
|
||||
elemDisplay('lobbyButton', false);
|
||||
elemDisplay('settingsButton', false);
|
||||
//...
|
||||
}
|
50
MiroTalk SFU/public/js/Snow.js
Normal file
@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
// https://codepen.io/tutsplus/pen/BaVqjvg
|
||||
|
||||
const snowContainer = document.getElementById('snow-container');
|
||||
|
||||
const snowContent = ['❄', '❅', '❆'];
|
||||
|
||||
const random = (num) => {
|
||||
return Math.floor(Math.random() * num);
|
||||
};
|
||||
|
||||
const getRandomStyles = () => {
|
||||
const top = random(100);
|
||||
const left = random(100);
|
||||
const dur = random(10) + 10;
|
||||
const size = random(25) + 25;
|
||||
return `
|
||||
top: -${top}%;
|
||||
left: ${left}%;
|
||||
font-size: ${size}px;
|
||||
animation-duration: ${dur}s;
|
||||
`;
|
||||
};
|
||||
|
||||
const createSnow = (num) => {
|
||||
for (let i = num; i > 0; i--) {
|
||||
let snow = document.createElement('div');
|
||||
snow.className = 'snow';
|
||||
snow.style.cssText = getRandomStyles();
|
||||
snow.innerHTML = snowContent[random(3)];
|
||||
snowContainer.append(snow);
|
||||
}
|
||||
};
|
||||
|
||||
const removeSnow = () => {
|
||||
snowContainer.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
snowContainer.remove();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
createSnow(30);
|
||||
setTimeout(removeSnow, 1000 * 60);
|
||||
});
|
||||
|
||||
window.addEventListener('click', () => {
|
||||
removeSnow();
|
||||
});
|
354
MiroTalk SFU/public/js/SpeechRec.js
Normal file
@ -0,0 +1,354 @@
|
||||
'use strict';
|
||||
|
||||
let isWebkitSpeechRecognitionSupported = false;
|
||||
let recognition;
|
||||
let isVoiceCommandsEnabled = true;
|
||||
let browserLanguage = navigator.language || navigator.userLanguage;
|
||||
let isVoiceCommandSupported = browserLanguage.includes('en-');
|
||||
|
||||
const speechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
|
||||
/**
|
||||
* Enable real-time voice recognition in the chat, allowing you to execute commands using your voice.
|
||||
* Note: Currently, it supports only the English language.
|
||||
* TODO make it multi languages...
|
||||
*/
|
||||
const commands = {
|
||||
shareRoom: 'room',
|
||||
hideMe: 'hide me',
|
||||
showMe: 'show me',
|
||||
newRoom: 'new room',
|
||||
leaveRoom: 'exit the room',
|
||||
audioOn: 'start the audio',
|
||||
audioOff: 'stop the audio',
|
||||
videoOn: 'start the video',
|
||||
videoOff: 'stop the video',
|
||||
screenOn: 'start the screen',
|
||||
screenOff: 'stop the screen',
|
||||
chatOn: 'open the chat',
|
||||
chatSend: 'send',
|
||||
chatOff: 'close the chat',
|
||||
toggleTr: 'toggle transcription',
|
||||
whiteboardOn: 'open the whiteboard',
|
||||
whiteboardOff: 'close the whiteboard',
|
||||
recordingOn: 'start the recording',
|
||||
recordingPause: 'pause the recording',
|
||||
recordingResume: 'resume the recording',
|
||||
recordingOff: 'stop the recording',
|
||||
settingsOn: 'open the settings',
|
||||
settingsOff: 'close the settings',
|
||||
participantsOn: 'show the participants',
|
||||
participantsOff: 'hide the participants',
|
||||
participantsVideoOff: 'stop the participants video',
|
||||
participantsAudioOff: 'stop the participants audio',
|
||||
participantsKickOut: 'kick out the participants',
|
||||
fileShareOn: 'open a file',
|
||||
fileShareOff: 'close a file',
|
||||
videoShareOn: 'share the video',
|
||||
videoShareOff: 'close the video',
|
||||
swapCamera: 'swap the camera',
|
||||
raiseHand: 'raise the hand',
|
||||
lowerHand: 'lower the hand',
|
||||
roomLock: 'lock the room',
|
||||
roomUnlock: 'unlock the room',
|
||||
about: 'show the about',
|
||||
email: 'open email',
|
||||
google: 'open google',
|
||||
googleTr: 'open google translate',
|
||||
youtube: 'open youtube',
|
||||
facebook: 'open facebook',
|
||||
linkedin: 'open linkedin',
|
||||
twitter: 'open twitter',
|
||||
tiktok: 'open tiktok',
|
||||
github: 'open github',
|
||||
survey: 'open survey',
|
||||
stopRecognition: 'stop the voice recognition',
|
||||
};
|
||||
|
||||
const browser = {
|
||||
newroom: '/newroom',
|
||||
email: 'mailto:?subject=&body=',
|
||||
google: 'https://www.google.com',
|
||||
googleTr: 'https://translate.google.com/',
|
||||
youtube: 'https://www.youtube.com',
|
||||
facebook: 'https://www.facebook.com',
|
||||
linkedin: 'https://www.linkedin.com',
|
||||
twitter: 'https://www.twitter.com',
|
||||
tiktok: 'https://www.tiktok.com',
|
||||
github: 'https://github.com/miroslavpejic85',
|
||||
};
|
||||
|
||||
if (speechRecognition) {
|
||||
recognition = new speechRecognition();
|
||||
|
||||
recognition.maxAlternatives = 1;
|
||||
recognition.continuous = true;
|
||||
recognition.lang = browserLanguage;
|
||||
|
||||
console.log('Speech recognition', recognition);
|
||||
|
||||
recognition.onstart = function () {
|
||||
console.log('Speech recognition started');
|
||||
hide(chatSpeechStartButton);
|
||||
show(chatSpeechStopButton);
|
||||
setColor(chatSpeechStopButton, 'lime');
|
||||
userLog('info', 'Speech recognition started', 'top-end');
|
||||
};
|
||||
|
||||
recognition.onresult = (e) => {
|
||||
let current = e.resultIndex;
|
||||
let transcript = e.results[current][0].transcript;
|
||||
if (transcript) {
|
||||
if (transcript.trim().toLowerCase() != commands.chatSend) {
|
||||
chatMessage.value = transcript;
|
||||
}
|
||||
if (isVoiceCommandsEnabled && isVoiceCommandSupported) {
|
||||
execVoiceCommands(transcript);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onerror = function (event) {
|
||||
console.error('Speech recognition error', event.error);
|
||||
userLog('error', `Speech recognition error ${event.error}`, 'top-end', 6000);
|
||||
};
|
||||
|
||||
recognition.onend = function () {
|
||||
console.log('Speech recognition stopped');
|
||||
show(chatSpeechStartButton);
|
||||
hide(chatSpeechStopButton);
|
||||
setColor(chatSpeechStopButton, 'white');
|
||||
userLog('info', 'Speech recognition stopped', 'top-end');
|
||||
};
|
||||
|
||||
isWebkitSpeechRecognitionSupported = true;
|
||||
console.info('Browser supports webkitSpeechRecognition');
|
||||
} else {
|
||||
console.warn('This browser not supports webkitSpeechRecognition');
|
||||
}
|
||||
|
||||
function startSpeech() {
|
||||
recognition.lang = browserLanguage;
|
||||
recognition.start();
|
||||
}
|
||||
|
||||
function stopSpeech() {
|
||||
recognition.stop();
|
||||
}
|
||||
|
||||
function execVoiceCommands(transcript) {
|
||||
switch (transcript.trim().toLowerCase()) {
|
||||
case commands.shareRoom:
|
||||
printCommand(commands.shareRoom);
|
||||
shareButton.click();
|
||||
break;
|
||||
case commands.hideMe:
|
||||
printCommand(commands.hideMe);
|
||||
hideMeButton.click();
|
||||
break;
|
||||
case commands.showMe:
|
||||
printCommand(commands.showMe);
|
||||
hideMeButton.click();
|
||||
break;
|
||||
case commands.newRoom:
|
||||
printCommand(commands.newRoom);
|
||||
openURL(browser.newroom);
|
||||
break;
|
||||
case commands.leaveRoom:
|
||||
printCommand(commands.leaveRoom);
|
||||
exitButton.click();
|
||||
break;
|
||||
case commands.audioOn:
|
||||
printCommand(commands.audioOn);
|
||||
startAudioButton.click();
|
||||
break;
|
||||
case commands.audioOff:
|
||||
printCommand(commands.audioOff);
|
||||
stopAudioButton.click();
|
||||
break;
|
||||
case commands.videoOn:
|
||||
printCommand(commands.videoOn);
|
||||
startVideoButton.click();
|
||||
break;
|
||||
case commands.videoOff:
|
||||
printCommand(commands.videoOff);
|
||||
stopVideoButton.click();
|
||||
break;
|
||||
case commands.screenOn:
|
||||
printCommand(commands.screenOn);
|
||||
startScreenButton.click();
|
||||
break;
|
||||
case commands.screenOff:
|
||||
printCommand(commands.screenOff);
|
||||
stopScreenButton.click();
|
||||
break;
|
||||
case commands.chatOn:
|
||||
printCommand(commands.chatOn);
|
||||
chatButton.click();
|
||||
break;
|
||||
case commands.chatSend:
|
||||
printCommand(commands.chatSend);
|
||||
chatSendButton.click();
|
||||
break;
|
||||
case commands.chatOff:
|
||||
printCommand(commands.chatOff);
|
||||
chatCloseButton.click();
|
||||
break;
|
||||
case commands.toggleTr:
|
||||
transcriptionButton.click();
|
||||
break;
|
||||
case commands.whiteboardOn:
|
||||
printCommand(commands.whiteboardOn);
|
||||
whiteboardButton.click();
|
||||
break;
|
||||
case commands.whiteboardOff:
|
||||
printCommand(commands.whiteboardOff);
|
||||
whiteboardCloseBtn.click();
|
||||
break;
|
||||
case commands.recordingOn:
|
||||
printCommand(commands.recordingOn);
|
||||
startRecButton.click();
|
||||
break;
|
||||
case commands.recordingPause:
|
||||
printCommand(commands.recordingPause);
|
||||
pauseRecButton.click();
|
||||
break;
|
||||
case commands.recordingResume:
|
||||
printCommand(commands.recordingResume);
|
||||
recordingResume.click();
|
||||
break;
|
||||
case commands.recordingOff:
|
||||
printCommand(commands.recordingOff);
|
||||
stopRecButton.click();
|
||||
break;
|
||||
case commands.settingsOn:
|
||||
printCommand(commands.settingsOn);
|
||||
settingsButton.click();
|
||||
break;
|
||||
case commands.settingsOff:
|
||||
printCommand(commands.settingsOff);
|
||||
mySettingsCloseBtn.click();
|
||||
break;
|
||||
case commands.participantsOn:
|
||||
printCommand(commands.participantsOn);
|
||||
chatButton.click();
|
||||
break;
|
||||
case commands.participantsOff:
|
||||
printCommand(commands.participantsOff);
|
||||
chatCloseButton.click();
|
||||
break;
|
||||
case commands.participantsVideoOff:
|
||||
printCommand(commands.participantsVideoOff);
|
||||
rc.peerAction('me', socket.id, 'hide', true, true);
|
||||
break;
|
||||
case commands.participantsAudioOff:
|
||||
printCommand(commands.participantsAudioOff);
|
||||
rc.peerAction('me', socket.id, 'mute', true, true);
|
||||
break;
|
||||
case commands.participantsKickOut:
|
||||
printCommand(commands.participantsKickOut);
|
||||
rc.peerAction('me', socket.id, 'eject', true, true);
|
||||
break;
|
||||
case commands.fileShareOn:
|
||||
printCommand(commands.fileShareOn);
|
||||
fileShareButton.click();
|
||||
break;
|
||||
case commands.fileShareOff:
|
||||
printCommand(commands.fileShareOff);
|
||||
sendAbortBtn.click();
|
||||
break;
|
||||
case commands.videoShareOn:
|
||||
printCommand(commands.videoShareOn);
|
||||
videoShareButton.click();
|
||||
break;
|
||||
case commands.videoShareOff:
|
||||
printCommand(commands.videoShareOff);
|
||||
videoCloseBtn.click();
|
||||
break;
|
||||
case commands.swapCamera:
|
||||
printCommand(commands.swapCamera);
|
||||
swapCameraButton.click();
|
||||
break;
|
||||
case commands.raiseHand:
|
||||
printCommand(commands.raiseHand);
|
||||
raiseHandButton.click();
|
||||
break;
|
||||
case commands.lowerHand:
|
||||
printCommand(commands.lowerHand);
|
||||
lowerHandButton.click();
|
||||
break;
|
||||
case commands.roomLock:
|
||||
printCommand(commands.roomLock);
|
||||
lockRoomButton.click();
|
||||
break;
|
||||
case commands.roomUnlock:
|
||||
printCommand(commands.roomUnlock);
|
||||
unlockRoomButton.click();
|
||||
break;
|
||||
case commands.about:
|
||||
printCommand(commands.about);
|
||||
aboutButton.click();
|
||||
break;
|
||||
case commands.email:
|
||||
printCommand(commands.email);
|
||||
openURL(browser.email, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.google:
|
||||
printCommand(commands.google);
|
||||
openURL(browser.google, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.googleTr:
|
||||
printCommand(commands.googleTr);
|
||||
openURL(browser.googleTr, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.youtube:
|
||||
printCommand(commands.youtube);
|
||||
openURL(browser.youtube, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.facebook:
|
||||
printCommand(commands.facebook);
|
||||
openURL(browser.facebook, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.linkedin:
|
||||
printCommand(commands.linkedin);
|
||||
openURL(browser.linkedin, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.twitter:
|
||||
printCommand(commands.twitter);
|
||||
openURL(browser.twitter, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.tiktok:
|
||||
printCommand(commands.tiktok);
|
||||
openURL(browser.tiktok, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.github:
|
||||
printCommand(commands.github);
|
||||
openURL(browser.github, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.survey:
|
||||
printCommand(commands.survey);
|
||||
survey.enabled && openURL(survey.url, true);
|
||||
sound('open');
|
||||
break;
|
||||
case commands.stopRecognition:
|
||||
printCommand(commands.stopRecognition);
|
||||
chatSpeechStopButton.click();
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function printCommand(command) {
|
||||
console.log('Detected', { command: command });
|
||||
}
|
429
MiroTalk SFU/public/js/Transcription.js
Normal file
@ -0,0 +1,429 @@
|
||||
'use strict';
|
||||
|
||||
class Transcription {
|
||||
constructor() {
|
||||
this.languages = [
|
||||
['Afrikaans', ['af-ZA']],
|
||||
['Bahasa Indonesia', ['id-ID']],
|
||||
['Bahasa Melayu', ['ms-MY']],
|
||||
['Català', ['ca-ES']],
|
||||
['Čeština', ['cs-CZ']],
|
||||
['Deutsch', ['de-DE']],
|
||||
[
|
||||
'English',
|
||||
['en-AU', 'Australia'],
|
||||
['en-CA', 'Canada'],
|
||||
['en-IN', 'India'],
|
||||
['en-NZ', 'New Zealand'],
|
||||
['en-ZA', 'South Africa'],
|
||||
['en-GB', 'United Kingdom'],
|
||||
['en-US', 'United States'],
|
||||
],
|
||||
[
|
||||
'Español',
|
||||
['es-AR', 'Argentina'],
|
||||
['es-BO', 'Bolivia'],
|
||||
['es-CL', 'Chile'],
|
||||
['es-CO', 'Colombia'],
|
||||
['es-CR', 'Costa Rica'],
|
||||
['es-EC', 'Ecuador'],
|
||||
['es-SV', 'El Salvador'],
|
||||
['es-ES', 'España'],
|
||||
['es-US', 'Estados Unidos'],
|
||||
['es-GT', 'Guatemala'],
|
||||
['es-HN', 'Honduras'],
|
||||
['es-MX', 'México'],
|
||||
['es-NI', 'Nicaragua'],
|
||||
['es-PA', 'Panamá'],
|
||||
['es-PY', 'Paraguay'],
|
||||
['es-PE', 'Perú'],
|
||||
['es-PR', 'Puerto Rico'],
|
||||
['es-DO', 'República Dominicana'],
|
||||
['es-UY', 'Uruguay'],
|
||||
['es-VE', 'Venezuela'],
|
||||
],
|
||||
['Euskara', ['eu-ES']],
|
||||
['Français', ['fr-FR']],
|
||||
['Galego', ['gl-ES']],
|
||||
['Hrvatski', ['hr_HR']],
|
||||
['IsiZulu', ['zu-ZA']],
|
||||
['Íslenska', ['is-IS']],
|
||||
['Italiano', ['it-IT', 'Italia'], ['it-CH', 'Svizzera']],
|
||||
['Magyar', ['hu-HU']],
|
||||
['Nederlands', ['nl-NL']],
|
||||
['Norsk bokmål', ['nb-NO']],
|
||||
['Polski', ['pl-PL']],
|
||||
['Português', ['pt-BR', 'Brasil'], ['pt-PT', 'Portugal']],
|
||||
['Română', ['ro-RO']],
|
||||
['Slovenčina', ['sk-SK']],
|
||||
['Suomi', ['fi-FI']],
|
||||
['Svenska', ['sv-SE']],
|
||||
['Türkçe', ['tr-TR']],
|
||||
['български', ['bg-BG']],
|
||||
['Pусский', ['ru-RU']],
|
||||
['Српски', ['sr-RS']],
|
||||
['한국어', ['ko-KR']],
|
||||
[
|
||||
'中文',
|
||||
['cmn-Hans-CN', '普通话 (中国大陆)'],
|
||||
['cmn-Hans-HK', '普通话 (香港)'],
|
||||
['cmn-Hant-TW', '中文 (台灣)'],
|
||||
['yue-Hant-HK', '粵語 (香港)'],
|
||||
],
|
||||
['日本語', ['ja-JP']],
|
||||
['Lingua latīna', ['la']],
|
||||
];
|
||||
this.speechTranscription = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
this.isTranscriptionSupported = false;
|
||||
this.transcriptionRunning = false;
|
||||
this.transcription;
|
||||
this.transcripts = [];
|
||||
this.isBgTransparent = false;
|
||||
this.isPinned = false;
|
||||
this.isHidden = true;
|
||||
this.isPersistentMode = false;
|
||||
this.isPersistent = false;
|
||||
this.showOnMessage = true;
|
||||
}
|
||||
|
||||
isSupported() {
|
||||
return Boolean(this.speechTranscription);
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.isSupported()) {
|
||||
this.handleLanguages();
|
||||
|
||||
this.transcription = new this.speechTranscription();
|
||||
this.transcription.maxAlternatives = 1;
|
||||
this.transcription.continuous = true;
|
||||
this.transcription.lang = transcriptionDialect.value;
|
||||
|
||||
this.transcription.onstart = function () {
|
||||
console.log('Transcription started');
|
||||
hide(transcriptionSpeechStart);
|
||||
show(transcriptionSpeechStop);
|
||||
setColor(transcriptionSpeechStatus, 'lime');
|
||||
!transcription.isPersistentMode
|
||||
? userLog('info', 'Transcription started', 'top-end')
|
||||
: (transcription.isPersistent = true);
|
||||
};
|
||||
|
||||
this.transcription.onresult = (e) => {
|
||||
const current = e.resultIndex;
|
||||
const transcript = e.results[current][0].transcript;
|
||||
const transcriptionData = {
|
||||
type: 'transcript',
|
||||
room_id: room_id,
|
||||
peer_name: peer_name,
|
||||
text_data: transcript,
|
||||
time_stamp: new Date(),
|
||||
broadcast: true,
|
||||
};
|
||||
if (transcript) {
|
||||
this.sendTranscript(transcriptionData);
|
||||
this.handleTranscript(transcriptionData);
|
||||
}
|
||||
};
|
||||
|
||||
this.transcription.onaudiostart = () => {
|
||||
console.log('Transcription start to capture your voice');
|
||||
};
|
||||
|
||||
this.transcription.onaudioend = () => {
|
||||
console.log('Transcription stop to capture your voice');
|
||||
};
|
||||
|
||||
this.transcription.onerror = function (event) {
|
||||
console.error('Transcription error', event.error);
|
||||
if (!transcription.isPersistent || !transcription.isPersistentMode)
|
||||
userLog('error', `Transcription error ${event.error}`, 'top-end', 6000);
|
||||
};
|
||||
|
||||
this.transcription.onend = function () {
|
||||
console.log('Transcription stopped');
|
||||
hide(transcriptionSpeechStop);
|
||||
show(transcriptionSpeechStart);
|
||||
setColor(transcriptionSpeechStatus, 'white');
|
||||
// Prevent stopping in the absence of speech...
|
||||
if (
|
||||
transcription.isPersistentMode &&
|
||||
transcription.isPersistent &&
|
||||
transcription.transcriptionRunning
|
||||
) {
|
||||
setTimeout(() => {
|
||||
transcription.start();
|
||||
}, 2000);
|
||||
} else {
|
||||
transcription.isPersistent = false;
|
||||
userLog('info', 'Transcription stopped', 'top-end');
|
||||
}
|
||||
};
|
||||
|
||||
this.isTranscriptionSupported = true;
|
||||
console.info('This Browser support Transcription');
|
||||
} else {
|
||||
console.warn(
|
||||
'This browser not support Transcription, check out supported browsers: https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API#browser_compatibility',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sendTranscript(transcriptionData) {
|
||||
if (rc.thereAreParticipants()) {
|
||||
//console.log('TRANSCRIPTION SEND', transcriptionData);
|
||||
rc.emitCmd(transcriptionData);
|
||||
}
|
||||
}
|
||||
|
||||
handleTranscript(transcriptionData) {
|
||||
console.log('TRANSCRIPTION TEXT', transcriptionData.text_data);
|
||||
|
||||
transcriptionData.text_data = filterXSS(transcriptionData.text_data);
|
||||
transcriptionData.peer_name = filterXSS(transcriptionData.peer_name);
|
||||
|
||||
const { peer_name, text_data } = transcriptionData;
|
||||
const time_stamp = rc.getTimeNow();
|
||||
const avatar_image = rc.isValidEmail(peer_name) ? rc.genGravatar(peer_name) : rc.genAvatarSvg(peer_name, 32);
|
||||
|
||||
if (this.isHidden) {
|
||||
if (this.showOnMessage) {
|
||||
this.toggle();
|
||||
} else {
|
||||
this.handleTranscriptionPopup(transcriptionData);
|
||||
}
|
||||
}
|
||||
|
||||
const msgHTML = `
|
||||
<div class="msg-transcription left-msg-transcription">
|
||||
<img class="msg-transcription-img" src="${avatar_image}" />
|
||||
<div class="msg-transcription-bubble">
|
||||
<div class="msg-transcription-info">
|
||||
<div class="msg-transcription-info-name">${peer_name} : ${time_stamp}</div>
|
||||
</div>
|
||||
<div class="msg-transcription-text">${text_data}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
transcriptionChat.insertAdjacentHTML('beforeend', msgHTML);
|
||||
transcriptionChat.scrollTop += 500;
|
||||
|
||||
this.transcripts.push({
|
||||
time: time_stamp,
|
||||
name: peer_name,
|
||||
caption: text_data,
|
||||
});
|
||||
rc.sound('transcript');
|
||||
}
|
||||
|
||||
handleTranscriptionPopup(transcriptionData, duration = 5000) {
|
||||
const transcriptionDisplay = document.createElement('div');
|
||||
transcriptionDisplay.className = 'animate__animated animate__fadeInUp';
|
||||
transcriptionDisplay.style.padding = '10px';
|
||||
transcriptionDisplay.style.fontSize = '1rem';
|
||||
transcriptionDisplay.style.color = '#FFF';
|
||||
transcriptionDisplay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
||||
transcriptionDisplay.style.borderRadius = '10px';
|
||||
transcriptionDisplay.innerText = `${transcriptionData.peer_name}: ${transcriptionData.text_data}`;
|
||||
transcriptionPopup.appendChild(transcriptionDisplay);
|
||||
setTimeout(() => {
|
||||
transcriptionDisplay.remove();
|
||||
}, duration);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if (this.isHidden) {
|
||||
this.center();
|
||||
transcriptionRoom.style.display = 'block';
|
||||
rc.sound('open');
|
||||
} else {
|
||||
transcriptionRoom.style.display = 'none';
|
||||
}
|
||||
this.isHidden = !this.isHidden;
|
||||
if (this.isPinned) this.unpinned();
|
||||
resizeTranscriptionRoom();
|
||||
}
|
||||
|
||||
toggleBg() {
|
||||
this.isBgTransparent = !this.isBgTransparent;
|
||||
this.isBgTransparent
|
||||
? document.documentElement.style.setProperty('--transcription-bg', 'rgba(0, 0, 0, 0.100)')
|
||||
: setTheme();
|
||||
}
|
||||
|
||||
maximize() {
|
||||
hide(transcriptionMaxBtn);
|
||||
show(transcriptionMinBtn);
|
||||
this.center();
|
||||
document.documentElement.style.setProperty('--transcription-width', '100%');
|
||||
document.documentElement.style.setProperty('--transcription-height', '100%');
|
||||
}
|
||||
|
||||
minimize() {
|
||||
hide(transcriptionMinBtn);
|
||||
show(transcriptionMaxBtn);
|
||||
if (this.isPinned) {
|
||||
this.pinned();
|
||||
} else {
|
||||
this.center();
|
||||
document.documentElement.style.setProperty('--transcription-width', '420px');
|
||||
document.documentElement.style.setProperty('--transcription-height', '680px');
|
||||
}
|
||||
}
|
||||
|
||||
center() {
|
||||
transcriptionRoom.style.position = 'fixed';
|
||||
transcriptionRoom.style.transform = 'translate(-50%, -50%)';
|
||||
transcriptionRoom.style.top = '50%';
|
||||
transcriptionRoom.style.left = '50%';
|
||||
}
|
||||
|
||||
togglePinUnpin() {
|
||||
if (rc.isChatPinned) {
|
||||
return userLog('info', 'Please unpin the chat that appears to be currently pinned', 'top-end');
|
||||
}
|
||||
this.isPinned ? this.unpinned() : this.pinned();
|
||||
rc.sound('click');
|
||||
}
|
||||
|
||||
isPin() {
|
||||
return this.isPinned;
|
||||
}
|
||||
|
||||
pinned() {
|
||||
if (!rc.isVideoPinned) {
|
||||
rc.videoMediaContainer.style.top = 0;
|
||||
rc.videoMediaContainer.style.width = '75%';
|
||||
rc.videoMediaContainer.style.height = '100%';
|
||||
}
|
||||
this.pin();
|
||||
this.isPinned = true;
|
||||
setColor(transcriptionTogglePinBtn, 'lime');
|
||||
resizeVideoMedia();
|
||||
transcriptionRoom.style.resize = 'none';
|
||||
if (!rc.isMobileDevice) rc.makeUnDraggable(transcriptionRoom, transcriptionHeader);
|
||||
}
|
||||
|
||||
pin() {
|
||||
transcriptionRoom.style.position = 'absolute';
|
||||
transcriptionRoom.style.top = 0;
|
||||
transcriptionRoom.style.right = 0;
|
||||
transcriptionRoom.style.left = null;
|
||||
transcriptionRoom.style.transform = null;
|
||||
document.documentElement.style.setProperty('--transcription-width', '25%');
|
||||
document.documentElement.style.setProperty('--transcription-height', '100%');
|
||||
}
|
||||
|
||||
unpinned() {
|
||||
if (!rc.isVideoPinned) {
|
||||
rc.videoMediaContainer.style.top = 0;
|
||||
rc.videoMediaContainer.style.right = null;
|
||||
rc.videoMediaContainer.style.width = '100%';
|
||||
rc.videoMediaContainer.style.height = '100%';
|
||||
}
|
||||
document.documentElement.style.setProperty('--transcription-width', '420px');
|
||||
document.documentElement.style.setProperty('--transcription-height', '680px');
|
||||
hide(transcriptionMinBtn);
|
||||
show(transcriptionMaxBtn);
|
||||
this.center();
|
||||
this.isPinned = false;
|
||||
setColor(transcriptionTogglePinBtn, 'white');
|
||||
resizeVideoMedia();
|
||||
resizeTranscriptionRoom();
|
||||
transcriptionRoom.style.resize = 'both';
|
||||
if (!rc.isMobileDevice) rc.makeDraggable(transcriptionRoom, transcriptionHeader);
|
||||
}
|
||||
|
||||
save() {
|
||||
if (this.transcripts.length != 0) {
|
||||
const a = document.createElement('a');
|
||||
a.href = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(this.transcripts, null, 1));
|
||||
a.download = getDataTimeString() + room_id + '-TRANSCRIPTIONS.txt';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
rc.sound('download');
|
||||
} else {
|
||||
userLog('info', "There isn't transcriptions to save", 'top-end');
|
||||
}
|
||||
}
|
||||
|
||||
delete() {
|
||||
if (this.transcripts.length != 0) {
|
||||
Swal.fire({
|
||||
background: swalBackground,
|
||||
position: 'center',
|
||||
title: 'Clean up all transcripts?',
|
||||
imageUrl: image.delete,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: `Yes`,
|
||||
denyButtonText: `No`,
|
||||
showClass: { popup: 'animate__animated animate__fadeInDown' },
|
||||
hideClass: { popup: 'animate__animated animate__fadeOutUp' },
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
let captions = transcriptionChat.firstChild;
|
||||
while (captions) {
|
||||
transcriptionChat.removeChild(captions);
|
||||
captions = transcriptionChat.firstChild;
|
||||
}
|
||||
this.transcripts = [];
|
||||
rc.sound('delete');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
userLog('info', "There isn't transcriptions to delete", 'top-end');
|
||||
}
|
||||
}
|
||||
|
||||
updateCountry() {
|
||||
for (let i = transcriptionDialect.options.length - 1; i >= 0; i--) {
|
||||
transcriptionDialect.remove(i);
|
||||
}
|
||||
let list = this.languages[transcriptionLanguage.selectedIndex];
|
||||
for (let i = 1; i < list.length; i++) {
|
||||
transcriptionDialect.options.add(new Option(list[i][1], list[i][0]));
|
||||
}
|
||||
transcriptionDialect.style.visibility = list[1].length == 1 ? 'hidden' : 'visible';
|
||||
}
|
||||
|
||||
handleLanguages() {
|
||||
for (let i = 0; i < this.languages.length; i++) {
|
||||
transcriptionLanguage.options[i] = new Option(this.languages[i][0], i);
|
||||
}
|
||||
|
||||
transcriptionLanguage.selectedIndex = 6;
|
||||
this.updateCountry();
|
||||
|
||||
transcriptionDialect.selectedIndex = 6;
|
||||
transcriptionLanguage.onchange = () => {
|
||||
this.updateCountry();
|
||||
};
|
||||
}
|
||||
|
||||
start() {
|
||||
try {
|
||||
this.transcriptionRunning = true;
|
||||
this.transcription.lang = transcriptionDialect.value;
|
||||
this.selectDisabled(true);
|
||||
this.transcription.start();
|
||||
} catch (error) {
|
||||
this.transcriptionRunning = false;
|
||||
userLog('error', `Transcription start error ${error.message}`, 'top-end', 6000);
|
||||
console.error('Transcription start error', error);
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.transcriptionRunning = false;
|
||||
this.isPersistent = false;
|
||||
this.selectDisabled(false);
|
||||
this.transcription.stop();
|
||||
}
|
||||
|
||||
selectDisabled(disabled = false) {
|
||||
transcriptionLanguage.disabled = disabled;
|
||||
transcriptionDialect.disabled = disabled;
|
||||
transcriptPersistentMode.disabled = disabled;
|
||||
}
|
||||
}
|
39
MiroTalk SFU/public/js/Umami.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
console.log('STATS', window.location);
|
||||
|
||||
const statsDataKey = 'statsData';
|
||||
const statsData = window.sessionStorage.getItem(statsDataKey);
|
||||
|
||||
const apiUrl = window.location.origin + '/stats';
|
||||
|
||||
if (statsData) {
|
||||
setStats(JSON.parse(statsData));
|
||||
} else {
|
||||
fetch(apiUrl, { timeout: 5000 })
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
setStats(data);
|
||||
window.sessionStorage.setItem(statsDataKey, JSON.stringify(data));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Stats fetch error', error);
|
||||
});
|
||||
}
|
||||
|
||||
function setStats(data) {
|
||||
console.log('STATS', data);
|
||||
const { enabled, src, id } = data;
|
||||
if (enabled) {
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('async', '');
|
||||
script.setAttribute('src', src);
|
||||
script.setAttribute('data-website-id', id);
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
}
|
218
MiroTalk SFU/public/js/VideoGrid.js
Normal file
@ -0,0 +1,218 @@
|
||||
'use strict';
|
||||
|
||||
// ####################################################
|
||||
// RESPONSIVE PARTICIPANTS VIEW
|
||||
// ####################################################
|
||||
|
||||
let customRatio = true;
|
||||
|
||||
// aspect 0 1 2 3 4
|
||||
let ratios = ['0:0', '4:3', '16:9', '1:1', '1:2'];
|
||||
let aspect = 2;
|
||||
|
||||
let ratio = getAspectRatio();
|
||||
|
||||
function getAspectRatio() {
|
||||
customRatio = aspect == 0 ? true : false;
|
||||
var ratio = ratios[aspect].split(':');
|
||||
return ratio[1] / ratio[0];
|
||||
}
|
||||
|
||||
function setAspectRatio(i) {
|
||||
aspect = i;
|
||||
ratio = getAspectRatio();
|
||||
resizeVideoMedia();
|
||||
}
|
||||
|
||||
function Area(Increment, Count, Width, Height, Margin = 10) {
|
||||
ratio = customRatio ? 0.75 : ratio;
|
||||
let i = 0;
|
||||
let w = 0;
|
||||
let h = Increment * ratio + Margin * 2;
|
||||
while (i < Count) {
|
||||
if (w + Increment > Width) {
|
||||
w = 0;
|
||||
h = h + Increment * ratio + Margin * 2;
|
||||
}
|
||||
w = w + Increment + Margin * 2;
|
||||
i++;
|
||||
}
|
||||
if (h > Height) return false;
|
||||
else return Increment;
|
||||
}
|
||||
|
||||
function resizeVideoMedia() {
|
||||
let Margin = 5;
|
||||
let videoMediaContainer = document.getElementById('videoMediaContainer');
|
||||
let Cameras = document.getElementsByClassName('Camera');
|
||||
let Width = videoMediaContainer.offsetWidth - Margin * 2;
|
||||
let Height = videoMediaContainer.offsetHeight - Margin * 2;
|
||||
let max = 0;
|
||||
let optional = isHideMeActive && videoMediaContainer.childElementCount <= 2 ? 1 : 0;
|
||||
let isOneVideoElement = videoMediaContainer.childElementCount - optional == 1 ? true : false;
|
||||
|
||||
// console.log('videoMediaContainer.childElementCount', {
|
||||
// isOneVideoElement: isOneVideoElement,
|
||||
// children: videoMediaContainer.childElementCount,
|
||||
// optional: optional,
|
||||
// });
|
||||
|
||||
// full screen mode
|
||||
let bigWidth = Width * 4;
|
||||
if (isOneVideoElement) {
|
||||
Width = Width - bigWidth;
|
||||
}
|
||||
|
||||
resetZoom();
|
||||
|
||||
// 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(Cameras, max, bigWidth, Margin, Height, isOneVideoElement);
|
||||
document.documentElement.style.setProperty('--vmi-wh', max / 3 + 'px');
|
||||
}
|
||||
|
||||
function resetZoom() {
|
||||
const videoElements = document.querySelectorAll('video');
|
||||
videoElements.forEach((video) => {
|
||||
video.style.transform = '';
|
||||
video.style.transformOrigin = 'center';
|
||||
});
|
||||
}
|
||||
|
||||
function setWidth(Cameras, width, bigWidth, margin, maxHeight, isOneVideoElement) {
|
||||
ratio = customRatio ? 0.68 : ratio;
|
||||
for (let s = 0; s < Cameras.length; s++) {
|
||||
Cameras[s].style.width = width + 'px';
|
||||
Cameras[s].style.margin = margin + 'px';
|
||||
Cameras[s].style.height = width * ratio + 'px';
|
||||
if (isOneVideoElement) {
|
||||
Cameras[s].style.width = bigWidth + 'px';
|
||||
Cameras[s].style.height = bigWidth * ratio + 'px';
|
||||
let camHeigh = Cameras[s].style.height.substring(0, Cameras[s].style.height.length - 2);
|
||||
if (camHeigh >= maxHeight) Cameras[s].style.height = maxHeight - 2 + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// BREAKPOINTS
|
||||
// ####################################################
|
||||
|
||||
const MOBILE_BREAKPOINT = 500;
|
||||
const TABLET_BREAKPOINT = 580;
|
||||
const DESKTOP_BREAKPOINT = 730;
|
||||
const CUSTOM_BREAKPOINT = 680;
|
||||
|
||||
// ####################################################
|
||||
// RESPONSIVE MAIN BUTTONS
|
||||
// ####################################################
|
||||
|
||||
const mainButtonsBar = document.querySelectorAll('#control button');
|
||||
const mainButtonsIcon = document.querySelectorAll('#control button i');
|
||||
|
||||
function resizeMainButtons() {
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
const isButtonsBarVertical = BtnsBarPosition.selectedIndex === 0;
|
||||
//console.log('Window size', { width: windowWidth, height: windowWidth});
|
||||
if (isButtonsBarVertical) {
|
||||
// Main buttons vertical align
|
||||
if (windowHeight <= MOBILE_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '0.7rem', '4px', mainButtonsIcon, '0.8rem', '40px');
|
||||
} else if (windowHeight <= TABLET_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '0.9rem', '4px', mainButtonsIcon, '1rem', '45px');
|
||||
} else if (windowHeight <= DESKTOP_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '1rem', '5px', mainButtonsIcon, '1.1rem', '50px');
|
||||
} else {
|
||||
// > DESKTOP_BREAKPOINT
|
||||
setStyles(mainButtonsBar, '1rem', '10px', mainButtonsIcon, '1.2rem', '60px');
|
||||
}
|
||||
} else {
|
||||
// Main buttons horizontal align
|
||||
if (windowWidth <= MOBILE_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '0.7rem', '4px', mainButtonsIcon, '0.8rem');
|
||||
} else if (windowWidth <= TABLET_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '0.9rem', '4px', mainButtonsIcon, '1rem');
|
||||
} else if (windowWidth <= DESKTOP_BREAKPOINT) {
|
||||
setStyles(mainButtonsBar, '1rem', '5px', mainButtonsIcon, '1.1rem');
|
||||
} else {
|
||||
// > DESKTOP_BREAKPOINT
|
||||
setStyles(mainButtonsBar, '1rem', '10px', mainButtonsIcon, '1.2rem');
|
||||
}
|
||||
}
|
||||
//
|
||||
function setStyles(elements, fontSize, padding, icons, fontSizeIcon, bWidth = null) {
|
||||
if (bWidth) document.documentElement.style.setProperty('--btns-width', bWidth);
|
||||
|
||||
elements.forEach(function (element) {
|
||||
element.style.fontSize = fontSize;
|
||||
element.style.padding = padding;
|
||||
});
|
||||
icons.forEach(function (icon) {
|
||||
icon.style.fontSize = fontSizeIcon;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// RESPONSIVE CHAT
|
||||
// ####################################################
|
||||
|
||||
function resizeChatRoom() {
|
||||
if (!rc || rc.isMobileDevice || !rc.isChatOpen || rc.isChatPinned) return;
|
||||
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
windowWidth <= DESKTOP_BREAKPOINT || windowHeight <= DESKTOP_BREAKPOINT ? rc.chatMaximize() : rc.chatMinimize();
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// RESPONSIVE TRANSCRIPTION
|
||||
// ####################################################
|
||||
|
||||
function resizeTranscriptionRoom() {
|
||||
if (
|
||||
DetectRTC.isMobileDevice ||
|
||||
!Boolean(transcription.speechTranscription) ||
|
||||
transcription.isHidden ||
|
||||
transcription.isPinned
|
||||
)
|
||||
return;
|
||||
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
windowWidth <= CUSTOM_BREAKPOINT || windowHeight <= CUSTOM_BREAKPOINT
|
||||
? transcription.maximize()
|
||||
: transcription.minimize();
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// WINDOW LOAD/RESIZE EVENT
|
||||
// ####################################################
|
||||
|
||||
window.addEventListener(
|
||||
'load',
|
||||
function (event) {
|
||||
resizeVideoMedia();
|
||||
resizeMainButtons();
|
||||
window.onresize = function () {
|
||||
resizeVideoMedia();
|
||||
resizeMainButtons();
|
||||
resizeChatRoom();
|
||||
resizeTranscriptionRoom();
|
||||
};
|
||||
},
|
||||
false,
|
||||
);
|
419
MiroTalk SFU/public/js/landing.js
Normal file
@ -0,0 +1,419 @@
|
||||
!(function () {
|
||||
window;
|
||||
const e = document.documentElement;
|
||||
if ((e.classList.remove('no-js'), e.classList.add('js'), document.body.classList.contains('has-animations'))) {
|
||||
(window.sr = ScrollReveal()).reveal('.feature, .pricing-table-inner', {
|
||||
duration: 600,
|
||||
distance: '20px',
|
||||
easing: 'cubic-bezier(0.5, -0.01, 0, 1.005)',
|
||||
origin: 'bottom',
|
||||
interval: 100,
|
||||
}),
|
||||
e.classList.add('anime-ready'),
|
||||
anime
|
||||
.timeline({ targets: '.hero-figure-box-05' })
|
||||
.add({
|
||||
duration: 400,
|
||||
easing: 'easeInOutExpo',
|
||||
scaleX: [0.05, 0.05],
|
||||
scaleY: [0, 1],
|
||||
perspective: '500px',
|
||||
delay: anime.random(0, 400),
|
||||
})
|
||||
.add({ duration: 400, easing: 'easeInOutExpo', scaleX: 1 })
|
||||
.add({
|
||||
duration: 800,
|
||||
rotateY: '-15deg',
|
||||
rotateX: '8deg',
|
||||
rotateZ: '-1deg',
|
||||
}),
|
||||
anime
|
||||
.timeline({ targets: '.hero-figure-box-06, .hero-figure-box-07' })
|
||||
.add({
|
||||
duration: 400,
|
||||
easing: 'easeInOutExpo',
|
||||
scaleX: [0.05, 0.05],
|
||||
scaleY: [0, 1],
|
||||
perspective: '500px',
|
||||
delay: anime.random(0, 400),
|
||||
})
|
||||
.add({ duration: 400, easing: 'easeInOutExpo', scaleX: 1 })
|
||||
.add({ duration: 800, rotateZ: '20deg' }),
|
||||
anime({
|
||||
targets:
|
||||
'.hero-figure-box-01, .hero-figure-box-02, .hero-figure-box-03, .hero-figure-box-04, .hero-figure-box-08, .hero-figure-box-09, .hero-figure-box-10',
|
||||
duration: anime.random(600, 800),
|
||||
delay: anime.random(600, 800),
|
||||
rotate: [
|
||||
anime.random(-360, 360),
|
||||
function (e) {
|
||||
return e.getAttribute('data-rotation');
|
||||
},
|
||||
],
|
||||
scale: [0.7, 1],
|
||||
opacity: [0, 1],
|
||||
easing: 'easeInOutExpo',
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.querySelectorAll('[class*=reveal-]');
|
||||
let t = window.innerHeight;
|
||||
|
||||
function n(e, t) {
|
||||
let n = 0;
|
||||
return function () {
|
||||
let i = new Date().getTime();
|
||||
if (!(i - n < e)) return (n = i), t.apply(void 0, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function i() {
|
||||
let n;
|
||||
for (let i = 0; i < e.length; i++) {
|
||||
let s = e[i],
|
||||
a = s.getAttribute('data-reveal-delay'),
|
||||
l = s.getAttribute('data-reveal-offset') ? s.getAttribute('data-reveal-offset') : '200',
|
||||
c = s.getAttribute('data-reveal-container') ? s.closest(s.getAttribute('data-reveal-container')) : s;
|
||||
(n = l),
|
||||
c.getBoundingClientRect().top <= t - n &&
|
||||
!s.classList.contains('is-revealed') &&
|
||||
(a && 0 !== a
|
||||
? setTimeout(function () {
|
||||
s.classList.add('is-revealed');
|
||||
}, a)
|
||||
: s.classList.add('is-revealed'));
|
||||
}
|
||||
!(function () {
|
||||
if (e.length > document.querySelectorAll('[class*=reveal-].is-revealed').length) return;
|
||||
window.removeEventListener('load', i),
|
||||
window.removeEventListener('scroll', s),
|
||||
window.removeEventListener('resize', a);
|
||||
})();
|
||||
}
|
||||
|
||||
function s() {
|
||||
n(30, i());
|
||||
}
|
||||
|
||||
function a() {
|
||||
(t = window.innerHeight), n(30, i());
|
||||
}
|
||||
|
||||
e.length > 0 &&
|
||||
document.body.classList.contains('has-animations') &&
|
||||
(window.addEventListener('load', i),
|
||||
window.addEventListener('scroll', s),
|
||||
window.addEventListener('resize', a));
|
||||
})();
|
||||
|
||||
!(function () {
|
||||
'use strict';
|
||||
const e = document.getElementsByClassName('accordion-header');
|
||||
|
||||
function t(e, t) {
|
||||
e.classList.add('is-active'), (t.style.maxHeight = t.scrollHeight + 'px');
|
||||
}
|
||||
|
||||
function n(e, t) {
|
||||
e.classList.remove('is-active'), (t.style.maxHeight = null);
|
||||
}
|
||||
|
||||
if (e.length > 0)
|
||||
for (let i = 0; i < e.length; i++) {
|
||||
const s = e[i],
|
||||
a = s.parentNode,
|
||||
l = s.nextElementSibling;
|
||||
a.classList.contains('is-active') && t(a, l),
|
||||
s.addEventListener('click', function () {
|
||||
a.classList.contains('is-active') ? n(a, l) : t(a, l);
|
||||
});
|
||||
}
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
let e = {
|
||||
touchStartX: 0,
|
||||
touchEndX: 0,
|
||||
minSwipePixels: 30,
|
||||
detectionZone: void 0,
|
||||
swipeCallback: function () {},
|
||||
init: function (t, n) {
|
||||
(e.swipeCallback = n),
|
||||
t.addEventListener(
|
||||
'touchstart',
|
||||
function (t) {
|
||||
e.touchStartX = t.changedTouches[0].screenX;
|
||||
},
|
||||
!1,
|
||||
),
|
||||
t.addEventListener(
|
||||
'touchend',
|
||||
function (t) {
|
||||
(e.touchEndX = t.changedTouches[0].screenX), e.handleSwipeGesture();
|
||||
},
|
||||
!1,
|
||||
);
|
||||
},
|
||||
handleSwipeGesture: function () {
|
||||
let t, n;
|
||||
e.touchEndX <= e.touchStartX && ((n = e.touchStartX - e.touchEndX), (t = 'left')),
|
||||
e.touchEndX >= e.touchStartX && ((n = e.touchEndX - e.touchStartX), (t = 'right')),
|
||||
n > e.minSwipePixels && 'undefined' !== t && e.swipe(t, n);
|
||||
},
|
||||
swipe: function (t, n) {
|
||||
let i = {};
|
||||
(i.direction = t), (i.movedPixels = n), e.swipeCallback(i);
|
||||
},
|
||||
};
|
||||
const t = document.getElementsByClassName('carousel-items');
|
||||
|
||||
function n(e, t) {
|
||||
void 0 === t && (t = 'next');
|
||||
let n = e.getElementsByClassName('carousel-item is-active')[0],
|
||||
i = 'next' === t ? n.nextElementSibling : n.previousElementSibling,
|
||||
s = n.getAttribute('data-carousel'),
|
||||
a = e.parentNode.getElementsByClassName('carousel-bullet')[s],
|
||||
l = 'next' === t ? a.nextElementSibling : a.previousElementSibling;
|
||||
n.classList.remove('is-active'),
|
||||
a.classList.remove('is-active'),
|
||||
i
|
||||
? (i.classList.add('is-active'), l.classList.add('is-active'))
|
||||
: 'next' === t
|
||||
? (e.firstElementChild.classList.add('is-active'),
|
||||
e.parentNode
|
||||
.getElementsByClassName('carousel-bullets')[0]
|
||||
.firstElementChild.classList.add('is-active'))
|
||||
: (e.lastElementChild.classList.add('is-active'),
|
||||
e.parentNode
|
||||
.getElementsByClassName('carousel-bullets')[0]
|
||||
.lastElementChild.classList.add('is-active'));
|
||||
}
|
||||
|
||||
function i(e, t) {
|
||||
let n,
|
||||
i = 0;
|
||||
for (let e = 0; e < t.length; e++)
|
||||
(t[0].parentNode.style.minHeight = i + 'px'),
|
||||
t[e].classList.add('is-loading'),
|
||||
(n = t[e].offsetHeight),
|
||||
t[e].classList.remove('is-loading'),
|
||||
n > i && (i = n);
|
||||
t[0].parentNode.style.minHeight = i + 'px';
|
||||
}
|
||||
|
||||
function s(e) {
|
||||
e && clearInterval(e);
|
||||
}
|
||||
|
||||
if (t.length > 0)
|
||||
for (let a = 0; a < t.length; a++) {
|
||||
let l = t[a],
|
||||
c = l.getElementsByClassName('carousel-item'),
|
||||
o = 0,
|
||||
r = l.getAttribute('data-autorotate');
|
||||
const d = document.createElement('div');
|
||||
(d.className = 'carousel-bullets'), l.parentNode.insertBefore(d, l.nextSibling);
|
||||
for (let e = 0; e < c.length; e++) {
|
||||
c[e].setAttribute('data-carousel', e), c[e].classList.contains('is-active') && (o = e);
|
||||
let t = document.createElement('button');
|
||||
(t.className = 'carousel-bullet'),
|
||||
t.setAttribute('data-bullet', e),
|
||||
l.parentNode.getElementsByClassName('carousel-bullets')[0].appendChild(t);
|
||||
}
|
||||
c[o].classList.add('is-active');
|
||||
let u = l.parentNode.getElementsByClassName('carousel-bullet');
|
||||
u[o].classList.add('is-active'),
|
||||
i(0, c),
|
||||
window.addEventListener('resize', function () {
|
||||
i(0, c);
|
||||
});
|
||||
let m = !1;
|
||||
r &&
|
||||
(m = setInterval(function () {
|
||||
n(l, 'next');
|
||||
}, r));
|
||||
for (let e = 0; e < u.length; e++) {
|
||||
let t = u[e];
|
||||
t.addEventListener('click', function (e) {
|
||||
if ((e.preventDefault(), t.classList.contains('is-active'))) return;
|
||||
for (let e = 0; e < u.length; e++) u[e].classList.remove('is-active');
|
||||
for (let e = 0; e < c.length; e++) c[e].classList.remove('is-active');
|
||||
let n = this.getAttribute('data-bullet');
|
||||
c[n].classList.add('is-active'), this.classList.add('is-active'), s(m);
|
||||
});
|
||||
}
|
||||
e.init(l, function (e) {
|
||||
'left' === e.direction ? n(l, 'next') : 'right' === e.direction && n(l, 'prev'), s(m);
|
||||
});
|
||||
}
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
document.documentElement.classList.remove('no-js'),
|
||||
document.documentElement.classList.add('js'),
|
||||
window.addEventListener('load', function () {
|
||||
document.body.classList.add('is-loaded');
|
||||
});
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.getElementById('header-nav-toggle'),
|
||||
t = document.getElementById('header-nav');
|
||||
e &&
|
||||
(e.addEventListener('click', function () {
|
||||
document.body.classList.toggle('off-nav-is-active'),
|
||||
t.classList.toggle('is-active'),
|
||||
t.style.maxHeight ? (t.style.maxHeight = null) : (t.style.maxHeight = t.scrollHeight + 'px'),
|
||||
'true' === this.getAttribute('aria-expanded')
|
||||
? this.setAttribute('aria-expanded', 'false')
|
||||
: this.setAttribute('aria-expanded', 'true');
|
||||
}),
|
||||
document.addEventListener('click', function (n) {
|
||||
n.target === t ||
|
||||
n.target === e ||
|
||||
t.contains(n.target) ||
|
||||
(document.body.classList.remove('off-nav-is-active'),
|
||||
t.classList.remove('is-active'),
|
||||
(t.style.maxHeight = null),
|
||||
e.setAttribute('aria-expanded', 'false'));
|
||||
}));
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.getElementsByClassName('modal'),
|
||||
t = document.getElementsByClassName('modal-trigger');
|
||||
|
||||
function n() {
|
||||
document.body.classList.remove('modal-is-active');
|
||||
for (let t = 0; t < e.length; t++) e[t].classList.remove('is-active');
|
||||
}
|
||||
|
||||
if (e.length > 0 && t.length > 0)
|
||||
for (let e = 0; e < t.length; e++) {
|
||||
let n = t[e],
|
||||
i = document.getElementById(n.getAttribute('aria-controls'));
|
||||
i &&
|
||||
(n.hasAttribute('data-video') &&
|
||||
(null !== i.querySelector('iframe')
|
||||
? i.querySelector('iframe').setAttribute('src', n.getAttribute('data-video'))
|
||||
: null !== i.querySelector('video') &&
|
||||
i.querySelector('video').setAttribute('src', n.getAttribute('data-video'))),
|
||||
n.addEventListener('click', function (e) {
|
||||
let t;
|
||||
e.preventDefault(),
|
||||
n.hasAttribute('aria-controls') &&
|
||||
(t = i) &&
|
||||
(document.body.classList.add('modal-is-active'), t.classList.add('is-active'));
|
||||
}));
|
||||
}
|
||||
document.addEventListener('click', function (e) {
|
||||
(e.target.classList.contains('modal') || e.target.classList.contains('modal-close-trigger')) &&
|
||||
(e.preventDefault(), n());
|
||||
}),
|
||||
document.addEventListener('keydown', function (e) {
|
||||
27 === (e || window.event).keyCode && n();
|
||||
});
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.getElementById('pricing-toggle');
|
||||
|
||||
function t() {
|
||||
const t = document.getElementsByClassName('pricing-switchable');
|
||||
if (e.checked) for (let e = 0; e < t.length; e++) t[e].innerHTML = t[e].getAttribute('data-pricing-yearly');
|
||||
else for (let e = 0; e < t.length; e++) t[e].innerHTML = t[e].getAttribute('data-pricing-monthly');
|
||||
}
|
||||
|
||||
e && (window.addEventListener('load', t), e.addEventListener('change', t));
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.querySelectorAll('[class*=reveal-]');
|
||||
let t = window.innerHeight;
|
||||
|
||||
function n(e, t) {
|
||||
let n = 0;
|
||||
return function () {
|
||||
let i = new Date().getTime();
|
||||
if (!(i - n < e)) return (n = i), t.apply(void 0, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function i() {
|
||||
let n;
|
||||
for (let i = 0; i < e.length; i++) {
|
||||
let s = e[i],
|
||||
a = s.getAttribute('data-reveal-delay'),
|
||||
l = s.getAttribute('data-reveal-offset') ? s.getAttribute('data-reveal-offset') : '200',
|
||||
c = s.getAttribute('data-reveal-container')
|
||||
? s.closest(s.getAttribute('data-reveal-container'))
|
||||
: s;
|
||||
(n = l),
|
||||
c.getBoundingClientRect().top <= t - n &&
|
||||
!s.classList.contains('is-revealed') &&
|
||||
(a && 0 !== a
|
||||
? setTimeout(function () {
|
||||
s.classList.add('is-revealed');
|
||||
}, a)
|
||||
: s.classList.add('is-revealed'));
|
||||
}
|
||||
!(function () {
|
||||
if (e.length > document.querySelectorAll('[class*=reveal-].is-revealed').length) return;
|
||||
window.removeEventListener('load', i),
|
||||
window.removeEventListener('scroll', s),
|
||||
window.removeEventListener('resize', a);
|
||||
})();
|
||||
}
|
||||
|
||||
function s() {
|
||||
n(30, i());
|
||||
}
|
||||
|
||||
function a() {
|
||||
(t = window.innerHeight), n(30, i());
|
||||
}
|
||||
|
||||
e.length > 0 &&
|
||||
document.body.classList.contains('has-animations') &&
|
||||
(window.addEventListener('load', i),
|
||||
window.addEventListener('scroll', s),
|
||||
window.addEventListener('resize', a));
|
||||
})(),
|
||||
(function () {
|
||||
'use strict';
|
||||
const e = document.getElementsByClassName('smooth-scroll'),
|
||||
t = (e, n, i, s, a) => {
|
||||
const l = n - e;
|
||||
let c = l / i;
|
||||
const o = (function (e) {
|
||||
return e < 0.5 ? 2 * e * e : (4 - 2 * e) * e - 1;
|
||||
})((c = Math.min(c, 1)));
|
||||
window.scroll(0, a + s * o),
|
||||
l < i &&
|
||||
window.requestAnimationFrame((n) => {
|
||||
const l = n || new Date().getTime();
|
||||
t(e, l, i, s, a);
|
||||
});
|
||||
};
|
||||
if (e.length > 0)
|
||||
for (let n = 0; n < e.length; n++) {
|
||||
e[n].addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const n = e.target.closest('.smooth-scroll'),
|
||||
i = n.href.split('#')[1],
|
||||
s = document.getElementById(i),
|
||||
a = n.getAttribute('data-duration') || 1e3;
|
||||
s &&
|
||||
window.requestAnimationFrame((e) => {
|
||||
const n = e || new Date().getTime(),
|
||||
i = n,
|
||||
l = window.pageYOffset,
|
||||
c = s.getBoundingClientRect().top;
|
||||
t(i, n, a, c, l);
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
155
MiroTalk SFU/public/js/newRoom.js
Normal file
@ -0,0 +1,155 @@
|
||||
'use strict';
|
||||
|
||||
const adjectives = [
|
||||
'small',
|
||||
'big',
|
||||
'large',
|
||||
'smelly',
|
||||
'new',
|
||||
'happy',
|
||||
'shiny',
|
||||
'old',
|
||||
'clean',
|
||||
'nice',
|
||||
'bad',
|
||||
'cool',
|
||||
'hot',
|
||||
'cold',
|
||||
'warm',
|
||||
'hungry',
|
||||
'slow',
|
||||
'fast',
|
||||
'red',
|
||||
'white',
|
||||
'black',
|
||||
'blue',
|
||||
'green',
|
||||
'basic',
|
||||
'strong',
|
||||
'cute',
|
||||
'poor',
|
||||
'nice',
|
||||
'huge',
|
||||
'rare',
|
||||
'lucky',
|
||||
'weak',
|
||||
'tall',
|
||||
'short',
|
||||
'tiny',
|
||||
'great',
|
||||
'long',
|
||||
'single',
|
||||
'rich',
|
||||
'young',
|
||||
'dirty',
|
||||
'fresh',
|
||||
'brown',
|
||||
'dark',
|
||||
'crazy',
|
||||
'sad',
|
||||
'loud',
|
||||
'brave',
|
||||
'calm',
|
||||
'silly',
|
||||
'smart',
|
||||
];
|
||||
|
||||
const nouns = [
|
||||
'dog',
|
||||
'bat',
|
||||
'wrench',
|
||||
'apple',
|
||||
'pear',
|
||||
'ghost',
|
||||
'cat',
|
||||
'wolf',
|
||||
'squid',
|
||||
'goat',
|
||||
'snail',
|
||||
'hat',
|
||||
'sock',
|
||||
'plum',
|
||||
'bear',
|
||||
'snake',
|
||||
'turtle',
|
||||
'horse',
|
||||
'spoon',
|
||||
'fork',
|
||||
'spider',
|
||||
'tree',
|
||||
'chair',
|
||||
'table',
|
||||
'couch',
|
||||
'towel',
|
||||
'panda',
|
||||
'bread',
|
||||
'grape',
|
||||
'cake',
|
||||
'brick',
|
||||
'rat',
|
||||
'mouse',
|
||||
'bird',
|
||||
'oven',
|
||||
'phone',
|
||||
'photo',
|
||||
'frog',
|
||||
'bear',
|
||||
'camel',
|
||||
'sheep',
|
||||
'shark',
|
||||
'tiger',
|
||||
'zebra',
|
||||
'duck',
|
||||
'eagle',
|
||||
'fish',
|
||||
'kitten',
|
||||
'lobster',
|
||||
'monkey',
|
||||
'owl',
|
||||
'puppy',
|
||||
'pig',
|
||||
'rabbit',
|
||||
'fox',
|
||||
'whale',
|
||||
'beaver',
|
||||
'gorilla',
|
||||
'lizard',
|
||||
'parrot',
|
||||
'sloth',
|
||||
'swan',
|
||||
];
|
||||
|
||||
function getRandomNumber(length) {
|
||||
let result = '';
|
||||
let characters = '0123456789';
|
||||
let charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let adjective = adjectives[Math.floor(Math.random() * adjectives.length)];
|
||||
let noun = nouns[Math.floor(Math.random() * nouns.length)];
|
||||
let num = getRandomNumber(5);
|
||||
noun = noun.charAt(0).toUpperCase() + noun.substring(1);
|
||||
adjective = adjective.charAt(0).toUpperCase() + adjective.substring(1);
|
||||
document.getElementById('roomName').value = '';
|
||||
|
||||
// ####################################################
|
||||
// TYPING EFFECT
|
||||
// ####################################################
|
||||
|
||||
let i = 0;
|
||||
let txt = num + adjective + noun;
|
||||
let speed = 100;
|
||||
|
||||
function typeWriter() {
|
||||
if (i < txt.length) {
|
||||
document.getElementById('roomName').value += txt.charAt(i);
|
||||
i++;
|
||||
setTimeout(typeWriter, speed);
|
||||
}
|
||||
}
|
||||
|
||||
typeWriter();
|
3
MiroTalk SFU/public/robots.txt
Normal file
@ -0,0 +1,3 @@
|
||||
# Allow crawling of all content
|
||||
User-agent: *
|
||||
Disallow:
|
17867
MiroTalk SFU/public/sfu/MediasoupClient.js
Normal file
2
MiroTalk SFU/public/sfu/MediasoupClientCompile.js
Normal file
@ -0,0 +1,2 @@
|
||||
const client = require('mediasoup-client');
|
||||
window.mediasoupClient = client;
|