[mirotalksfu] - add Video menu bar + snapshot

هذا الالتزام موجود في:
Miroslav Pejic
2022-01-23 13:07:40 +01:00
الأصل c99fdb3a0a
التزام b457724287
4 ملفات معدلة مع 131 إضافات و42 حذوفات

عرض الملف

@@ -100,7 +100,7 @@ body {
--------------------------------------------------------------*/
#control {
z-index: 2;
z-index: 3;
position: absolute;
display: flex;
padding: 5px;
@@ -663,7 +663,7 @@ progress {
--------------------------------------------------------------*/
#whiteboard {
z-index: 3;
z-index: 4;
position: absolute;
margin: auto;
padding: 10px;
@@ -811,8 +811,9 @@ progress {
/*
z-index:
- 1 videoMediaContainer
- 2 control buttons
- 3 whiteboard
- 2 Video menu bar
- 3 control buttons
- 4 whiteboard
- 5 chat
- 6 settings
- 7 participants

عرض الملف

@@ -92,6 +92,40 @@
display: none;
}
.videoMenuBar {
z-index: 2;
position: absolute;
padding: 3px;
background: var(--bg);
font-size: small;
font-weight: bold;
text-align: center;
width: 100%;
cursor: default;
/* center */
top: 18px;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
overflow: hidden;
}
.videoMenuBar button {
float: right;
margin-right: 3px;
color: white;
background: transparent;
border-radius: 5px;
display: inline;
border: none;
}
.videoMenuBar button:hover {
color: grey;
transition: all 0.3s ease-in-out;
}
#videoMediaContainer video {
position: absolute;
margin-left: auto;

عرض الملف

@@ -6,13 +6,14 @@ const cfg = {
const html = {
newline: '<br />',
audioOn: 'fas fa-microphone audio',
audioOff: 'fas fa-microphone-slash audio',
audioOn: 'fas fa-microphone',
audioOff: 'fas fa-microphone-slash',
videoOn: 'fas fa-video',
videoOff: 'fas fa-video-slash',
userName: 'fas fa-user username',
userHand: 'fas fa-hand-paper pulsate',
fullScreen: 'fas fa-expand fscreen',
fullScreen: 'fas fa-expand',
snapshot: 'fas fa-camera-retro',
};
const image = {
@@ -762,7 +763,7 @@ class RoomClient {
}
async handleProducer(id, type, stream) {
let elem, d, p, i, b, fs, pm, pb;
let elem, vb, ts, d, p, i, b, fs, pm, pb;
this.removeVideoOff(this.peer_id);
d = document.createElement('div');
d.className = 'Camera';
@@ -773,6 +774,18 @@ class RoomClient {
elem.autoplay = true;
elem.poster = image.poster;
this.isMobileDevice || type === mediaType.screen ? (elem.className = '') : (elem.className = 'mirror');
vb = document.createElement('div');
vb.setAttribute('id', this.peer_id + '__vb');
vb.className = 'videoMenuBar fadein';
fs = document.createElement('button');
fs.id = id + '__fullScreen';
fs.className = html.fullScreen;
ts = document.createElement('button');
ts.id = id + '__snapshot';
ts.className = html.snapshot;
b = document.createElement('button');
b.id = this.peer_id + '__audio';
b.className = this.peer_info.peer_audio ? html.audioOn : html.audioOff;
p = document.createElement('p');
p.id = this.peer_id + '__name';
p.className = html.userName;
@@ -780,12 +793,6 @@ class RoomClient {
i = document.createElement('i');
i.id = this.peer_id + '__hand';
i.className = html.userHand;
b = document.createElement('button');
b.id = this.peer_id + '__audio';
b.className = this.peer_info.peer_audio ? html.audioOn : html.audioOff;
fs = document.createElement('button');
fs.id = id + '__fullScreen';
fs.className = html.fullScreen;
pm = document.createElement('div');
pb = document.createElement('div');
pm.setAttribute('id', this.peer_id + '_pitchMeter');
@@ -794,21 +801,27 @@ class RoomClient {
pb.className = 'bar';
pb.style.height = '1%';
pm.appendChild(pb);
vb.appendChild(b);
vb.appendChild(ts);
vb.appendChild(fs);
d.appendChild(elem);
d.appendChild(pm);
d.appendChild(i);
d.appendChild(p);
d.appendChild(b);
d.appendChild(fs);
d.appendChild(pm);
d.appendChild(vb);
this.videoMediaContainer.appendChild(d);
this.attachMediaStream(elem, stream, type, 'Producer');
this.myVideoEl = elem;
this.handleFS(elem.id, fs.id);
this.setTippy(elem.id, 'Full Screen', 'top-end');
this.handleTS(elem.id, ts.id);
this.popupPeerInfo(p.id, this.peer_info);
this.checkPeerInfoStatus(this.peer_info);
this.sound('joined');
resizeVideoMedia();
if (!this.isMobileDevice) {
this.setTippy(elem.id, 'Full Screen', 'top-end');
this.setTippy(ts.id, 'Snapshot', 'top-end');
}
return elem;
}
@@ -974,10 +987,12 @@ class RoomClient {
}
handleConsumer(id, type, stream, peer_name, peer_info) {
let elem, d, p, i, b, fs, pb, pm;
let elem, vb, d, p, i, b, fs, ts, pb, pm;
switch (type) {
case mediaType.video:
this.removeVideoOff(peer_info.peer_id);
let remotePeerId = peer_info.peer_id;
let remotePeerAudio = peer_info.peer_audio;
this.removeVideoOff(remotePeerId);
d = document.createElement('div');
d.className = 'Camera';
d.id = id + '__d';
@@ -987,41 +1002,53 @@ class RoomClient {
elem.autoplay = true;
elem.className = '';
elem.poster = image.poster;
p = document.createElement('p');
p.id = peer_info.peer_id + '__name';
p.className = html.userName;
p.innerHTML = '&nbsp;' + peer_name;
i = document.createElement('i');
i.id = peer_info.peer_id + '__hand';
i.className = html.userHand;
b = document.createElement('button');
b.id = peer_info.peer_id + '__audio';
b.className = peer_info.peer_audio ? html.audioOn : html.audioOff;
vb = document.createElement('div');
vb.setAttribute('id', remotePeerId + '__vb');
vb.className = 'videoMenuBar fadein';
fs = document.createElement('button');
fs.id = id + '__fullScreen';
fs.className = html.fullScreen;
ts = document.createElement('button');
ts.id = id + '__snapshot';
ts.className = html.snapshot;
b = document.createElement('button');
b.id = remotePeerId + '__audio';
b.className = remotePeerAudio ? html.audioOn : html.audioOff;
i = document.createElement('i');
i.id = remotePeerId + '__hand';
i.className = html.userHand;
p = document.createElement('p');
p.id = remotePeerId + '__name';
p.className = html.userName;
p.innerHTML = '&nbsp;' + peer_name;
pm = document.createElement('div');
pb = document.createElement('div');
pm.setAttribute('id', peer_info.peer_id + '__pitchMeter');
pb.setAttribute('id', peer_info.peer_id + '__pitchBar');
pm.setAttribute('id', remotePeerId + '__pitchMeter');
pb.setAttribute('id', remotePeerId + '__pitchBar');
pm.className = 'speechbar';
pb.className = 'bar';
pb.style.height = '1%';
pm.appendChild(pb);
vb.appendChild(b);
vb.appendChild(ts);
vb.appendChild(fs);
d.appendChild(elem);
d.appendChild(p);
d.appendChild(i);
d.appendChild(b);
d.appendChild(fs);
d.appendChild(p);
d.appendChild(pm);
d.appendChild(vb);
this.videoMediaContainer.appendChild(d);
this.attachMediaStream(elem, stream, type, 'Consumer');
this.handleFS(elem.id, fs.id);
this.setTippy(elem.id, 'Full Screen', 'top-end');
this.handleTS(elem.id, ts.id);
this.popupPeerInfo(p.id, peer_info);
this.checkPeerInfoStatus(peer_info);
this.sound('joined');
resizeVideoMedia();
if (!this.isMobileDevice) {
this.setTippy(elem.id, 'Full Screen', 'top-end');
this.setTippy(ts.id, 'Snapshot', 'top-end');
}
break;
case mediaType.audio:
elem = document.createElement('audio');
@@ -1058,7 +1085,7 @@ class RoomClient {
// ####################################################
async setVideoOff(peer_info, remotePeer = false) {
let d, i, h, b, p, pm, pb;
let d, vb, i, h, b, p, pm, pb;
let peer_id = peer_info.peer_id;
let peer_name = peer_info.peer_name;
let peer_audio = peer_info.peer_audio;
@@ -1066,6 +1093,12 @@ class RoomClient {
d = document.createElement('div');
d.className = 'Camera';
d.id = peer_id + '__videoOff';
vb = document.createElement('div');
vb.setAttribute('id', this.peer_id + 'vb');
vb.className = 'videoMenuBar fadein';
b = document.createElement('button');
b.id = peer_id + '__audio';
b.className = peer_audio ? html.audioOn : html.audioOff;
i = document.createElement('img');
i.className = 'center pulsate';
i.id = peer_id + '__img';
@@ -1073,11 +1106,8 @@ class RoomClient {
p.id = peer_id + '__name';
p.className = html.userName;
p.innerHTML = '&nbsp;' + peer_name + (remotePeer ? '' : ' (me) ');
b = document.createElement('button');
b.id = peer_id + '__audio';
b.className = peer_audio ? html.audioOn : html.audioOff;
h = document.createElement('i');
h.id = peer_info.peer_id + '__hand';
h.id = peer_id + '__hand';
h.className = html.userHand;
pm = document.createElement('div');
pb = document.createElement('div');
@@ -1087,11 +1117,12 @@ class RoomClient {
pb.className = 'bar';
pb.style.height = '1%';
pm.appendChild(pb);
vb.appendChild(b);
d.appendChild(i);
d.appendChild(p);
d.appendChild(b);
d.appendChild(h);
d.appendChild(pm);
d.appendChild(vb);
this.videoMediaContainer.appendChild(d);
this.setVideoAvatarImgName(i.id, peer_name);
this.getId(i.id).style.display = 'block';
@@ -1453,6 +1484,29 @@ class RoomClient {
});
}
// ####################################################
// TAKE SNAPSHOT
// ####################################################
handleTS(elemId, tsId) {
let videoPlayer = this.getId(elemId);
let btnTs = this.getId(tsId);
btnTs.addEventListener('click', () => {
this.sound('snapshot');
let context, canvas, width, height, dataURL;
width = videoPlayer.offsetWidth;
height = videoPlayer.offsetHeight;
canvas = canvas || document.createElement('canvas');
canvas.width = width;
canvas.height = height;
context = canvas.getContext('2d');
context.drawImage(videoPlayer, 0, 0, width, height);
dataURL = canvas.toDataURL('image/png');
console.log(dataURL);
saveDataToFile(dataURL, getDataTimeString() + '-SNAPSHOT.png');
});
}
// ####################################################
// DRAGGABLE
// ####################################################

ثنائية
public/sounds/snapshot.wav Normal file

ملف ثنائي غير معروض.