Date: Fri, 29 Mar 2024 09:03:54 +0100 (CET) Message-ID: <1847573162.47419.1711699434278@docs.flashphoner.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_47418_253950560.1711699434278" ------=_Part_47418_253950560.1711699434278 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
=D0=94=D0=B0=D0=BD=D0=BD=D1=8B=D0=B9 =D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1= =8C =D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D1=82 =D0=BA=D0=BE=D0=B4 =D0= =B4=D0=BB=D1=8F =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0= =B8=D1=8F =D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE =D0= =B8 =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE =D0= =B2=D0=B8=D0=B4=D0=B5=D0=BE =D0=B8 =D0=B0=D1=83=D0=B4=D0=B8=D0=BE. =D0=9A= =D0=BE=D0=B4 =D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD =D0=BD=D0=B0 = =D0=B4=D0=B2=D0=B5 =D0=BE=D0=B1=D0=BB=D0=B0=D1=81=D1=82=D0=B8 - =D0=B4=D0= =BB=D1=8F =D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE =D0= =BC=D0=B5=D0=B4=D0=B8=D0=B0 =D0=B8 =D0=B4=D0=BB=D1=8F =D0=BF=D0=BE=D0=BB=D1= =83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE =D0=BC=D0=B5=D0=B4=D0=B8=D0= =B0.
initLocalDisplay() code
=D0=9E=D0=B1=D0=B5=D1=80=D1=82=D0=BA=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BA=D0= =BE=D0=B4=D0=B0 =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0= =B8=D1=8F =D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE =D0= =BC=D0=B5=D0=B4=D0=B8=D0=B0
const initLocalDisp= lay =3D function(localDisplayElement){=20
=D0=9E=D0=B1=D1=8A=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BB=D0= =BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 =D0=BF=D0=B5=D1=80=D0=B5=D0= =BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85
const localDisplayD= iv =3D localDisplayElement; const localDisplays =3D {};=20
removeLocalDisplay() code
=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BB=D0=BE=D0=BA=D0= =B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE =D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0= =BD=D1=82=D0=B0 =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0= =B8=D1=8F =D0=BF=D1=80=D0=B8 =D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88=D0=B5=D0= =BD=D0=B8=D0=B8 =D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0= =B8 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8
const removeLocalDi= splay =3D function(id) { delete localDisplays[id]; $('#' + id).remove(); reassembleLocalLayout(); }=20
getAudioContainer() code
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D0=B2=D0=B8=D0=B4=D0=B5=D0=BE =D1=8D=D0= =BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0 =D0=B1=D0=B5=D0=B7 =D0=B0=D1=83=D0= =B4=D0=B8=D0=BE =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8
const getAudioConta= iner =3D function() { for (const [key, value] of Object.entries(localDisplays)) { let video =3D value.getElementsByTagName("video"); if (video && video[0]) { let audioStateButton =3D value.getElementsByTagName("button"); let audioTracks =3D video[0].srcObject.getAudioTracks(); if (!audioTracks || audioTracks.length =3D=3D=3D 0) { return { id: value.id, video: video[0], audioStateDisplay: audioStateButton[0] } } } } };=20
add() code
=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F =D0=B4=D0=BE=D0=B1=D0=B0=D0= =B2=D0=BB=D1=8F=D0=B5=D1=82 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D1=83 =D0= =B4=D0=BB=D1=8F =D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0= =BE =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F
const add =3D funct= ion(id, name, stream) { if (stream.getAudioTracks().length > 0) { let videoElement =3D getAudioContainer(); if (videoElement) { let track =3D stream.getAudioTracks()[0]; videoElement.video.srcObject.addTrack(track); videoElement.audioStateDisplay.innerHTML =3D "Audio state: " + = stream.getAudioTracks()[0].enabled; track.addEventListener("ended", function() { videoElement.video.srcObject.removeTrack(track); videoElement.audioStateDisplay.innerHTML =3D "Audio state: = " + false; //check video element has no tracks left for (const [key, vTrack] of Object.entries(videoElement.vid= eo.srcObject.getTracks())) { if (vTrack.readyState !=3D=3D "ended") { return; } } removeLocalDisplay(videoElement.id); }); return; } } const coreDisplay =3D document.createElement('div'); coreDisplay.setAttribute("style","width:200px; height:auto; border: sol= id; border-width: 1px"); coreDisplay.id =3D stream.id; const streamNameDisplay =3D document.createElement("div"); streamNameDisplay.innerHTML =3D "Name: " + name; streamNameDisplay.setAttribute("style","width:auto; height:30px"); coreDisplay.appendChild(streamNameDisplay); const audioStateDisplay =3D document.createElement("button"); audioStateDisplay.setAttribute("style","width:auto; height:30px"); audioStateDisplay.innerHTML =3D "Audio state: " + (stream.getAudioTrack= s().length > 0 ? stream.getAudioTracks()[0].enabled : false); audioStateDisplay.addEventListener('click', function(){ if (stream.getAudioTracks().length > 0) { stream.getAudioTracks()[0].enabled =3D !(stream.getAudioTracks(= )[0].enabled); audioStateDisplay.innerHTML =3D "Audio state: " + stream.getAud= ioTracks()[0].enabled; } }); coreDisplay.appendChild(audioStateDisplay); const streamDisplay =3D document.createElement('div'); streamDisplay.id =3D id; streamDisplay.setAttribute("style","width:auto; height:auto"); coreDisplay.appendChild(streamDisplay); const video =3D document.createElement("video"); streamDisplay.appendChild(video); video.srcObject =3D stream; video.muted =3D true; video.onloadedmetadata =3D function (e) { video.play(); }; stream.getTracks().forEach(function(track){ track.addEventListener("ended", function() { video.srcObject.removeTrack(track); //check video element has no tracks left for (const [key, vTrack] of Object.entries(video.srcObject.getT= racks())) { if (vTrack.readyState !=3D=3D "ended") { return; } } removeLocalDisplay(id); }); }); video.addEventListener('resize', function (event) { streamNameDisplay.innerHTML =3D "Name: " + name + " " + video.video= Width + "x" + video.videoHeight; resizeVideo(event.target); }); localDisplays[id] =3D coreDisplay; reassembleLocalLayout(); return coreDisplay; }=20
=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0, =D0=BA=D0=B0=D0=BA=D0= =B0=D1=8F =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B0 =D0=B4=D0=BE=D0=B1=D0= =B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82=D1=81=D1=8F. =D0=95=D1=81=D0=BB=D0=B8 =D0= =B0=D1=83=D0=B4=D0=B8=D0=BE, =D0=BF=D0=BE=D0=B8=D1=81=D0=BA =D0=B1=D0=BB=D0= =B8=D0=B6=D0=B0=D0=B9=D1=88=D0=B5=D0=B3=D0=BE =D0=B2=D0=B8=D0=B4=D0=B5=D0= =BE =D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0 =D0=B1=D0=B5=D0=B7 =D0= =B0=D1=83=D0=B4=D0=B8=D0=BE, =D0=B8 =D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0= =B5=D0=BD=D0=B8=D0=B5 =D0=B0=D1=83=D0=B4=D0=B8=D0=BE =D0=B4=D0=BE=D1=80=D0= =BE=D0=B6=D0=BA=D0=B8 =D0=BA =D0=BD=D0=B5=D0=BC=D1=83
if (stream.getAudio= Tracks().length > 0) { let videoElement =3D getAudioContainer(); if (videoElement) { let track =3D stream.getAudioTracks()[0]; videoElement.video.srcObject.addTrack(track); videoElement.audioStateDisplay.innerHTML =3D "Audio state: " + stre= am.getAudioTracks()[0].enabled; track.addEventListener("ended", function() { videoElement.video.srcObject.removeTrack(track); videoElement.audioStateDisplay.innerHTML =3D "Audio state: " + = false; //check video element has no tracks left for (const [key, vTrack] of Object.entries(videoElement.video.s= rcObject.getTracks())) { if (vTrack.readyState !=3D=3D "ended") { return; } } removeLocalDisplay(videoElement.id); }); return; } }=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=BD=D0=BE=D0=B2=D0= =BE=D0=B3=D0=BE =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0= =B0 =D0=B4=D0=BB=D1=8F =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0= =BD=D0=B8=D1=8F
const coreDisplay = =3D document.createElement('div'); coreDisplay.setAttribute("style","width:200px; height:auto; border: solid; = border-width: 1px"); coreDisplay.id =3D stream.id;=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1= =82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BE=D1=82=D0= =BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8=D0=BC=D0=B5=D0= =BD=D0=B8
const streamNameDis= play =3D document.createElement("div"); streamNameDisplay.innerHTML =3D "Name: " + name; streamNameDisplay.setAttribute("style","width:auto; height:30px"); coreDisplay.appendChild(streamNameDisplay);=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D1=8D=D0=BB=D0=B5=D0= =BC=D0=B5=D0=BD=D1=82=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BE=D1=82=D0=BE=D0=B1=D1= =80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D1=81=D0=BE=D1=81=D1=82=D0=BE=D1= =8F=D0=BD=D0=B8=D1=8F =D0=B0=D1=83=D0=B4=D0=B8=D0=BE. =D0=9F=D0=BE=D0=B4=D0= =BF=D0=B8=D1=81=D0=BA=D0=B0 =D0=BD=D0=B0 =D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0= =B8=D0=B5 "click" =D0=B4=D0=BB=D1=8F =D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87= =D0=B5=D0=BD=D0=B8=D1=8F/=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8= =D1=8F =D0=B0=D1=83=D0=B4=D0=B8=D0=BE.
const audioStateDis= play =3D document.createElement("button"); audioStateDisplay.setAttribute("style","width:auto; height:30px"); audioStateDisplay.innerHTML =3D "Audio state: " + (stream.getAudioTracks().= length > 0 ? stream.getAudioTracks()[0].enabled : false); audioStateDisplay.addEventListener('click', function(){ if (stream.getAudioTracks().length > 0) { stream.getAudioTracks()[0].enabled =3D !(stream.getAudioTracks()[0]= .enabled); audioStateDisplay.innerHTML =3D "Audio state: " + stream.getAudioTr= acks()[0].enabled; } }); coreDisplay.appendChild(audioStateDisplay);=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1= =82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BE=D1=82=D0= =BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2=D0=B8=D0=B4=D0= =B5=D0=BE =D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=B0
const streamDisplay= =3D document.createElement('div'); streamDisplay.id =3D id; streamDisplay.setAttribute("style","width:auto; height:auto"); coreDisplay.appendChild(streamDisplay);=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=B2=D0=B8=D0=B4=D0= =B5=D0=BE =D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0 =D0=B8 =D0=B4=D0= =BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B5=D0=B3=D0=BE =D0= =B2 =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80
const video =3D doc= ument.createElement("video"); streamDisplay.appendChild(video); video.srcObject =3D stream; video.muted =3D true; video.onloadedmetadata =3D function (e) { video.play(); };=20
=D0=9F=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=BA=D0=B0 =D0=BD=D0=B0 =D1=81=D0= =BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B5 "ended" =D0=B4=D0=BB=D1=8F =D0=B4=D0=BE= =D1=80=D0=BE=D0=B6=D0=BA=D0=B8. =D0=95=D1=81=D0=BB=D0=B8 =D0=B4=D0=BE=D1=80= =D0=BE=D0=B6=D0=BA=D0=B0 =D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88=D0=B8=D0=BB= =D0=B0=D1=81=D1=8C, =D0=B8 =D0=BD=D0=B5 =D0=BE=D1=81=D1=82=D0=B0=D0=BB=D0= =BE=D1=81=D1=8C =D0=BD=D0=B8 =D0=BE=D0=B4=D0=BD=D0=BE=D0=B9 =D0=B0=D0=BA=D1= =82=D0=B8=D0=B2=D0=BD=D0=BE=D0=B9 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0= =B8, =D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1= =82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0
stream.getTracks().= forEach(function(track){ track.addEventListener("ended", function() { video.srcObject.removeTrack(track); //check video element has no tracks left for (const [key, vTrack] of Object.entries(video.srcObject.getTrack= s())) { if (vTrack.readyState !=3D=3D "ended") { return; } } removeLocalDisplay(id); }); });=20
=D0=9F=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=BA=D0=B0 =D0=BD=D0=B0 =D1=81=D0= =BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B5 'resize', =D1=87=D1=82=D0=BE=D0=B1=D1=8B = =D0=BC=D0=B0=D1=81=D1=88=D1=82=D0=B0=D0=B1=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1= =82=D1=8C =D0=B2=D0=B8=D0=B4=D0=B5=D0=BE =D0=BF=D0=BE=D0=B4 =D1=80=D0=B0=D0= =B7=D0=BC=D0=B5=D1=80=D1=8B =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0= =B5=D1=80=D0=B0.
video.addEventListe= ner('resize', function (event) { streamNameDisplay.innerHTML =3D "Name: " + name + " " + video.videoWidt= h + "x" + video.videoHeight; resizeVideo(event.target); });=20
=D0=A1=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA=D0= =BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0, =D0=BE=D0=B1=D0=BD=D0= =BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0= =B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8 =D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0= =B0=D1=82 =D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=BA=D0=BE=D0=BD=D1=82=D0= =B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0.
localDisplays[id] = =3D coreDisplay; reassembleLocalLayout(); return coreDisplay;=20
reassembleLocalLayout() code
=D0=92=D1=81=D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D1=82=D0=B5=D0=BB=D1=8C= =D0=BD=D0=B0=D1=8F =D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F =D0=BF=D0=B5= =D1=80=D0=B5=D1=81=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D0=B5=D1=82 =D1=81= =D0=B5=D1=82=D0=BA=D1=83 =D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B= =D1=85 =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=BE=D0=B2 = =D0=B8 =D0=BF=D0=B5=D1=80=D0=B5=D1=80=D0=B8=D1=81=D0=BE=D0=B2=D1=8B=D0=B2= =D0=B0=D0=B5=D1=82 =D0=B8=D1=85 =D0=BD=D0=B0 =D1=81=D1=82=D1=80=D0=B0=D0=BD= =D0=B8=D1=86=D0=B5
const reassembleLoc= alLayout =3D function() { let gridWidth =3D gridSize(Object.keys(localDisplays).length).x; let container =3D document.createElement('div'); let row; let rowI =3D 1; let colI =3D 0; for (const [key, value] of Object.entries(localDisplays)) { if (row) { if (colI >=3D gridWidth) { row =3D createRow(container); rowI++; colI =3D 0; } } else { row =3D createRow(container); } $("#" + key).detach(); let col =3D createCol(row); col.appendChild(value); colI++; } $(localDisplayDiv).empty(); localDisplayDiv.appendChild(container); }=20
return { add: add }=20
initRemoteDisplay() code
=D0=9E=D0=B1=D0=B5=D1=80=D1=82=D0=BA=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BA=D0= =BE=D0=B4=D0=B0 =D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0= =B8=D1=8F =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0= =BE =D0=BC=D0=B5=D0=B4=D0=B8=D0=B0
const initRemoteDis= play =3D function(room, mainDiv, peerConnection) {=20
=D0=9E=D0=B1=D1=8A=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BB=D0= =BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 =D0=BF=D0=B5=D1=80=D0=B5=D0= =BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85
const constants =3D= SFU.constants; const remoteParticipants =3D {};=20
=D0=9F=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=BA=D0=B0 =D0=BD=D0=B0 =D0=BD=D0= =B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D0=B5 =D1=81=D0=BE=D0= =B1=D1=8B=D1=82=D0=B8=D1=8F =D0=BA=D0=BE=D0=BC=D0=BD=D0=B0=D1=82=D1=8B
room.on(constan= ts.SFU_ROOM_EVENT.ADD_TRACKS, function(e) { let participant =3D remoteParticipants[e.info.nickName]; if (!participant) { participant =3D {}; participant.nickName =3D e.info.nickName; participant.tracks =3D []; participant.displays =3D []; remoteParticipants[participant.nickName] =3D participant; } participant.tracks.push.apply(participant.tracks, e.info.info); for (const pTrack of e.info.info) { let createDisplay =3D true; for (let i =3D 0; i < participant.displays.length; i++) { let display =3D participant.displays[i]; if (pTrack.type =3D=3D=3D "VIDEO") { if (display.hasVideo()) { continue; } display.videoMid =3D pTrack.mid; display.setTrackInfo(pTrack); createDisplay =3D false; break; } else if (pTrack.type =3D=3D=3D "AUDIO") { if (display.hasAudio()) { continue; } display.audioMid =3D pTrack.mid; createDisplay =3D false; break; } } if (!createDisplay) { continue; } let display =3D createRemoteDisplay(participant.nickName, parti= cipant.nickName, mainDiv); participant.displays.push(display); if (pTrack.type =3D=3D=3D "VIDEO") { display.videoMid =3D pTrack.mid; display.setTrackInfo(pTrack); } else if (pTrack.type =3D=3D=3D "AUDIO") { display.audioMid =3D pTrack.mid; } } }).on(constants.SFU_ROOM_EVENT.REMOVE_TRACKS, function(e) { const participant =3D remoteParticipants[e.info.nickName]; if (!participant) { return; } for (const rTrack of e.info.info) { for (let i =3D 0; i < participant.tracks.length; i++) { if (rTrack.mid =3D=3D=3D participant.tracks[i].mid) { participant.tracks.splice(i, 1); break; } } for (let i =3D 0; i < participant.displays.length; i++) { let found =3D false; const display =3D participant.displays[i]; if (display.audioMid =3D=3D=3D rTrack.mid) { display.setAudio(null); found =3D true; } else if (display.videoMid =3D=3D=3D rTrack.mid) { display.setVideo(null); found =3D true; } if (found) { if (!display.hasAudio() && !display.hasVideo())= { display.dispose(); participant.displays.splice(i, 1); } break; } } } }).on(constants.SFU_ROOM_EVENT.LEFT, function(e) { let participant =3D remoteParticipants[e.name]; if (!participant) { return; } participant.displays.forEach(function(display){ display.dispose(); }) delete remoteParticipants[e.name]; }).on(constants.SFU_ROOM_EVENT.TRACK_QUALITY_STATE, function(e){ console.log("Received track quality state"); const participant =3D remoteParticipants[e.info.nickName]; if (!participant) { return; } for (const rTrack of e.info.tracks) { const mid =3D rTrack.mid; for (let i =3D 0; i < participant.displays.length; i++) { const display =3D participant.displays[i]; if (display.videoMid =3D=3D=3D mid) { display.updateQualityInfo(rTrack.quality); break; } } } });=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0= =B8=D0=BA=D0=B0. =D0=95=D1=81=D0=BB=D0=B8 =D0=BD=D0=B5 =D0=BD=D0=B0=D0=B9= =D0=B4=D0=B5=D0=BD, =D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=BD= =D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8= =D0=BA=D0=B0
let participant =3D= remoteParticipants[e.info.nickName]; if (!participant) { participant =3D {}; participant.nickName =3D e.info.nickName; participant.tracks =3D []; participant.displays =3D []; remoteParticipants[participant.nickName] =3D participant; }=20
=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BD=D0= =BE=D0=B2=D1=8B=D1=85 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=B5=D0=BA =D0=B4=D0= =BB=D1=8F =D1=8D=D1=82=D0=BE=D0=B3=D0=BE =D1=83=D1=87=D0=B0=D1=81=D1=82=D0= =BD=D0=B8=D0=BA=D0=B0
participant.tracks.= push.apply(participant.tracks, e.info.info);=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1= =82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0 =D0=B4=D0=BB=D1=8F =D0=BA=D0=B0=D0= =B6=D0=B4=D0=BE=D0=B9 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8
for (const = pTrack of e.info.info) { let createDisplay =3D true; for (let i =3D 0; i < participant.displays.length; i++) { let display =3D participant.displays[i]; if (pTrack.type =3D=3D=3D "VIDEO") { if (display.hasVideo()) { continue; } display.videoMid =3D pTrack.mid; display.setTrackInfo(pTrack); createDisplay =3D false; break; } else if (pTrack.type =3D=3D=3D "AUDIO") { if (display.hasAudio()) { continue; } display.audioMid =3D pTrack.mid; createDisplay =3D false; break; } } if (!createDisplay) { continue; } let display =3D createRemoteDisplay(participant.nickName, parti= cipant.nickName, mainDiv); participant.displays.push(display); if (pTrack.type =3D=3D=3D "VIDEO") { display.videoMid =3D pTrack.mid; display.setTrackInfo(pTrack); } else if (pTrack.type =3D=3D=3D "AUDIO") { display.audioMid =3D pTrack.mid; } } }=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0= =B8=D0=BA=D0=B0. =D0=95=D1=81=D0=BB=D0=B8 =D0=BD=D0=B5 =D0=BD=D0=B0=D0=B9= =D0=B4=D0=B5=D0=BD, =D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82
const participant = =3D remoteParticipants[e.info.nickName]; if (!participant) { return; }=20
=D0=9F=D0=B5=D1=80=D0=B5=D0=B1=D0=BE=D1=80 =D0=B4=D0=BE=D1=80=D0=BE=D0= =B6=D0=B5=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0
for (const rTrack o= f e.info.info) {=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D0=B8 =D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0= =BD=D0=B8=D0=B5 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8 =D1=81 =D1=82=D0= =B0=D0=BA=D0=B8=D0=BC =D0=B6=D0=B5 mid, =D0=BA=D0=B0=D0=BA=D0=BE=D0=B9 =D0= =B1=D1=8B=D0=BB =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD =D0=B2 =D1=81=D0= =BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B8
for (let i =3D 0; i= < participant.tracks.length; i++) { if (rTrack.mid =3D=3D=3D participant.tracks[i].mid) { participant.tracks.splice(i, 1); break; } }=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0= =BD=D0=B5=D1=80=D0=B0, =D0=B2 =D0=BA=D0=BE=D1=82=D0=BE=D1=80=D0=BE=D0=BC = =D0=BF=D1=80=D0=BE=D0=B8=D0=B3=D1=80=D1=8B=D0=B2=D0=B0=D0=B5=D1=82=D1=81=D1= =8F =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B0, =D0=B8 =D1=83=D0=B4=D0=B0= =D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8. = =D0=95=D1=81=D0=BB=D0=B8 =D0=B2 =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD= =D0=B5=D1=80=D0=B5 =D0=BD=D0=B5 =D0=BE=D1=81=D1=82=D0=B0=D0=BB=D0=BE=D1=81= =D1=8C =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=B5=D0=BA, =D0=BE=D0=BD =D1=82=D0= =B0=D0=BA=D0=B6=D0=B5 =D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D0=B5=D1=82=D1=81=D1= =8F
for (le= t i =3D 0; i < participant.displays.length; i++) { let found =3D false; const display =3D participant.displays[i]; if (display.audioMid =3D=3D=3D rTrack.mid) { display.setAudio(null); found =3D true; } else if (display.videoMid =3D=3D=3D rTrack.mid) { display.setVideo(null); found =3D true; } if (found) { if (!display.hasAudio() && !display.hasVideo())= { display.dispose(); participant.displays.splice(i, 1); } break; } }=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D0=B8 =D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0= =BD=D0=B8=D0=B5 =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0
let partici= pant =3D remoteParticipants[e.name]; if (!participant) { return; } participant.displays.forEach(function(display){ display.dispose(); }) delete remoteParticipants[e.name];=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0= =B8=D0=BA=D0=B0. =D0=95=D1=81=D0=BB=D0=B8 =D0=BD=D0=B5 =D0=BD=D0=B0=D0=B9= =D0=B4=D0=B5=D0=BD, =D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82
console.log("Receiv= ed track quality state"); const participant =3D remoteParticipants[e.info.nickName]; if (!participant) { return; }=20
=D0=9F=D0=B5=D1=80=D0=B5=D0=B1=D0=BE=D1=80 =D0=B4=D0=BE=D1=80=D0=BE=D0= =B6=D0=B5=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0
for (const rTrack o= f e.info.tracks) {=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1= =82=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B3=D0=BE =D0=BA=D0=BE=D0= =BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0 =D0=B8 =D0=BE=D0=B1=D0=BD=D0= =BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA=D0=B0=D1=87=D0=B5=D1=81=D1= =82=D0=B2=D0=B0
const m= id =3D rTrack.mid; for (let i =3D 0; i < participant.displays.length; i++) { const display =3D participant.displays[i]; if (display.videoMid =3D=3D=3D mid) { display.updateQualityInfo(rTrack.quality); break; } }=20
createRemoteDisplay() code
=D0=92=D1=81=D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D1=82=D0=B5=D0=BB=D1=8C= =D0=BD=D0=B0=D1=8F =D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F =D1=81=D0=BE= =D0=B7=D0=B4=D0=B0=D0=B5=D1=82 =D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD= =D0=B5=D1=80 =D0=BD=D0=B0 =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B5 =D0=B4=D0=B0= =D0=BD=D0=BD=D1=8B=D1=85 =D0=BE =D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=B5 =D0=B8= =D0=B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B0=D1=85
const createRem= oteDisplay =3D function(id, name, mainDiv) { const cell =3D document.createElement("div"); cell.setAttribute("class", "grid-item"); cell.id =3D id; mainDiv.appendChild(cell); const streamNameDisplay =3D document.createElement("div"); streamNameDisplay.innerHTML =3D "Name: " + name; streamNameDisplay.setAttribute("style","width:auto; height:20px"); cell.appendChild(streamNameDisplay); const qualityDisplay =3D document.createElement("div"); qualityDisplay.setAttribute("style","width:auto; height:20px"); cell.appendChild(qualityDisplay); const tidDisplay =3D document.createElement("div"); tidDisplay.setAttribute("style","width:auto; height:20px"); cell.appendChild(tidDisplay); let qualityDivs =3D []; let tidDivs =3D []; const rootDisplay =3D document.createElement("div"); rootDisplay.setAttribute("style","width:auto; height:auto"); cell.appendChild(rootDisplay); const streamDisplay =3D document.createElement("div"); streamDisplay.setAttribute("style","width:auto; height:auto"); rootDisplay.appendChild(streamDisplay); let audio =3D null; let video =3D null; return { dispose: function() { cell.remove(); }, hide: function(value) { if (value) { cell.style.display =3D "none"; } else { cell.style.display =3D "block"; } }, setAudio: function(stream) { if (audio) { audio.remove(); } if (!stream) { audio =3D null; this.audioMid =3D undefined; return; } audio =3D document.createElement("audio"); audio.controls =3D "controls"; cell.appendChild(audio); audio.srcObject =3D stream; audio.play(); }, hasAudio: function() { return audio !=3D=3D null || this.audioMid !=3D=3D undefine= d; }, setVideo: function(stream) { if (video) { video.remove(); } if (stream =3D=3D null) { video =3D null; this.videoMid =3D undefined; qualityDivs.forEach(function(div) { div.remove(); }); qualityDivs =3D []; tidDivs.forEach(function(div) { div.remove(); }); tidDivs =3D []; return; } video =3D document.createElement("video"); streamDisplay.appendChild(video); video.srcObject =3D stream; video.onloadedmetadata =3D function (e) { video.play(); }; video.addEventListener("resize", function (event) { streamNameDisplay.innerHTML =3D "Name: " + name + " " += video.videoWidth + "x" + video.videoHeight; resizeVideo(event.target); }); }, setTrackInfo: function(trackInfo) { if (trackInfo && trackInfo.quality) { for (let i =3D 0; i < trackInfo.quality.length; i++)= { const qualityDiv =3D document.createElement("button= "); qualityDivs.push(qualityDiv); qualityDiv.innerText =3D trackInfo.quality[i]; qualityDiv.setAttribute("style", "display:inline-bl= ock; border: solid; border-width: 1px"); qualityDiv.style.color =3D "red"; qualityDiv.addEventListener('click', function(){ console.log("Clicked on quality " + trackInfo.q= uality[i] + " trackId " + trackInfo.id); if (qualityDiv.style.color =3D=3D=3D "red") { return; } for (let c =3D 0; c < qualityDivs.length; c+= +) { if (qualityDivs[c].style.color !=3D=3D "red= ") { qualityDivs[c].style.color =3D "gray"; } } qualityDiv.style.color =3D "blue"; room.changeQuality(trackInfo.id, trackInfo.qual= ity[i]); }); qualityDisplay.appendChild(qualityDiv); } for (let i =3D 0; i < 3; i++) { const tidDiv =3D document.createElement("button"); tidDivs.push(tidDiv); tidDiv.innerText =3D "TID"+i; tidDiv.setAttribute("style", "display:inline-block;= border: solid; border-width: 1px"); tidDiv.style.color =3D "gray"; tidDiv.addEventListener('click', function(){ console.log("Clicked on TID " + i + " trackId "= + trackInfo.id); for (let c =3D 0; c < tidDivs.length; c++) { tidDivs[c].style.color =3D "gray"; } tidDiv.style.color =3D "blue"; room.changeQuality(trackInfo.id, null, i); }); tidDisplay.appendChild(tidDiv); } } }, updateQualityInfo: function(videoQuality) { for (const qualityInfo of videoQuality) { for (const qualityDiv of qualityDivs) { if (qualityDiv.innerText =3D=3D=3D qualityInfo.qual= ity){ if (qualityInfo.available =3D=3D=3D true) { qualityDiv.style.color =3D "gray"; } else { qualityDiv.style.color =3D "red"; } break; } } } }, hasVideo: function() { return video !=3D=3D null || this.videoMid !=3D=3D undefine= d; }, audioMid: undefined, videoMid: undefined }; };=20
=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1= =82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0
dispose() code
dispose= : function() { cell.remove(); }=20
=D0=A1=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D0=B5 =D0=BA=D0=BE=D0=BD=D1=82=D0= =B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0
hide() code
hide: f= unction(value) { if (value) { cell.style.display =3D "none"; } else { cell.style.display =3D "block"; } }=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=B0=D1=83=D0=B4=D0= =B8=D0=BE =D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0
setAudio() code
setAudi= o: function(stream) { if (audio) { audio.remove(); } if (!stream) { audio =3D null; this.audioMid =3D undefined; return; } audio =3D document.createElement("audio"); audio.controls =3D "controls"; cell.appendChild(audio); audio.srcObject =3D stream; audio.play(); }=20
=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5 =D0=B2=D0=B8=D0=B4=D0= =B5=D0=BE =D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0
setVideo() code
setVide= o: function(stream) { if (video) { video.remove(); } if (stream =3D=3D null) { video =3D null; this.videoMid =3D undefined; qualityDivs.forEach(function(div) { div.remove(); }); qualityDivs =3D []; tidDivs.forEach(function(div) { div.remove(); }); tidDivs =3D []; return; } video =3D document.createElement("video"); streamDisplay.appendChild(video); video.srcObject =3D stream; video.onloadedmetadata =3D function (e) { video.play(); }; video.addEventListener("resize", function (event) { streamNameDisplay.innerHTML =3D "Name: " + name + " " += video.videoWidth + "x" + video.videoHeight; resizeVideo(event.target); }); }=20
=D0=9E=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 =D0= =B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE =D0=BA=D0= =B0=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5
setTrackInfo() code
setTrac= kInfo: function(trackInfo) { if (trackInfo && trackInfo.quality) { for (let i =3D 0; i < trackInfo.quality.length; i++)= { const qualityDiv =3D document.createElement("button= "); qualityDivs.push(qualityDiv); qualityDiv.innerText =3D trackInfo.quality[i]; qualityDiv.setAttribute("style", "display:inline-bl= ock; border: solid; border-width: 1px"); qualityDiv.style.color =3D "red"; qualityDiv.addEventListener('click', function(){ console.log("Clicked on quality " + trackInfo.q= uality[i] + " trackId " + trackInfo.id); if (qualityDiv.style.color =3D=3D=3D "red") { return; } for (let c =3D 0; c < qualityDivs.length; c+= +) { if (qualityDivs[c].style.color !=3D=3D "red= ") { qualityDivs[c].style.color =3D "gray"; } } qualityDiv.style.color =3D "blue"; room.changeQuality(trackInfo.id, trackInfo.qual= ity[i]); }); qualityDisplay.appendChild(qualityDiv); } for (let i =3D 0; i < 3; i++) { const tidDiv =3D document.createElement("button"); tidDivs.push(tidDiv); tidDiv.innerText =3D "TID"+i; tidDiv.setAttribute("style", "display:inline-block;= border: solid; border-width: 1px"); tidDiv.style.color =3D "gray"; tidDiv.addEventListener('click', function(){ console.log("Clicked on TID " + i + " trackId "= + trackInfo.id); for (let c =3D 0; c < tidDivs.length; c++) { tidDivs[c].style.color =3D "gray"; } tidDiv.style.color =3D "blue"; room.changeQuality(trackInfo.id, null, i); }); tidDisplay.appendChild(tidDiv); } } }=20
=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA=D0= =B0=D1=87=D0=B5=D1=82=D1=81=D0=B2=D0=B0
updateQualityInfo() code
updateQ= ualityInfo: function(videoQuality) { for (const qualityInfo of videoQuality) { for (const qualityDiv of qualityDivs) { if (qualityDiv.innerText =3D=3D=3D qualityInfo.qual= ity){ if (qualityInfo.available =3D=3D=3D true) { qualityDiv.style.color =3D "gray"; } else { qualityDiv.style.color =3D "red"; } break; } } } }=20
=D0=9F=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=BA=D0=B0 =D0=BD=D0=B0 =D1=81=D0= =BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B5 PeerConnection "ontrack".
peerConnection.= ontrack =3D ({transceiver}) =3D> { let rParticipant; console.log("Attach remote track " + transceiver.receiver.track.id = + " kind " + transceiver.receiver.track.kind + " mid " + transceiver.mid); for (const [nickName, participant] of Object.entries(remoteParticip= ants)) { for (const pTrack of participant.tracks) { console.log("Participant " + participant.nickName + " track= " + pTrack.id + " mid " + pTrack.mid); if (pTrack.mid =3D=3D=3D transceiver.mid) { rParticipant =3D participant; break; } } if (rParticipant) { break; } } if (rParticipant) { for (const display of rParticipant.displays) { if (transceiver.receiver.track.kind =3D=3D=3D "video") { if (display.videoMid =3D=3D=3D transceiver.mid) { let stream =3D new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setVideo(stream); break; } } else if (transceiver.receiver.track.kind =3D=3D=3D "audio= ") { if (display.audioMid =3D=3D=3D transceiver.mid) { let stream =3D new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setAudio(stream); break; } } } } else { console.warn("Failed to find participant for track " + transcei= ver.receiver.track.id); } }=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0= =B8=D0=BA=D0=B0 =D0=BD=D0=B0 =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B5 mid =D0= =B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8
let rParticipant; console.log("Attach remote track " + transceiver.receiver.track.id + " kind= " + transceiver.receiver.track.kind + " mid " + transceiver.mid); for (const [nickName, participant] of Object.entries(remoteParticipants)) { for (const pTrack of participant.tracks) { console.log("Participant " + participant.nickName + " track " + pTr= ack.id + " mid " + pTrack.mid); if (pTrack.mid =3D=3D=3D transceiver.mid) { rParticipant =3D participant; break; } } if (rParticipant) { break; } }=20
=D0=9F=D0=BE=D0=B8=D1=81=D0=BA =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1= =82=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B5=D0=B3=D0=BE =D0=BA=D0=BE=D0= =BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0 =D0=B8 =D0=B4=D0=BE=D0=B1=D0= =B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BA =D0=BD=D0=B5=D0=BC=D1=83 =D0= =B4=D0=BE=D1=80=D0=BE=D0=B6=D0=BA=D0=B8
for (co= nst display of rParticipant.displays) { if (transceiver.receiver.track.kind =3D=3D=3D "video") { if (display.videoMid =3D=3D=3D transceiver.mid) { let stream =3D new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setVideo(stream); break; } } else if (transceiver.receiver.track.kind =3D=3D=3D "audio= ") { if (display.audioMid =3D=3D=3D transceiver.mid) { let stream =3D new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setAudio(stream); break; } } }=20