...
Code Block | ||||
---|---|---|---|---|
| ||||
localDisplays[id] = coreDisplay; localDisplayDiv.appendChild(coreDisplay); return coreDisplay; |
3.
...
Stop video and audio capturing
stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
const stop = function () { for (const [key, value] of Object.entries(localDisplays)) { removeLocalDisplay(value.id); } } |
...
3. Tags to display remote video creation
3.1.
...
Container div creation
createRemoteDisplay() code
ЗдесьWhere:
- создается контейнер для потоков участника
- создается контейнер для конкретного потока
- создается контейнер для кнопок переключения качестваcontainer
div
tag for participants streams is created - child container
div
tag for a certain stream is created - container
div
tag for quality switch buttons is created
Code Block | ||||
---|---|---|---|---|
| ||||
const cell = document.createElement("div"); cell.setAttribute("class", "text-center"); cell.id = id; mainDiv.appendChild(cell); const streamNameDisplay = document.createElement("div"); streamNameDisplay.innerHTML = "Published by: " + name; streamNameDisplay.setAttribute("style","width:auto; height:auto;"); streamNameDisplay.setAttribute("class","text-center"); cell.appendChild(streamNameDisplay); const qualityDisplay = document.createElement("div"); qualityDisplay.setAttribute("style","width:auto; height:auto;"); qualityDisplay.setAttribute("class","text-center"); cell.appendChild(qualityDisplay); let qualityDivs = []; const rootDisplay = document.createElement("div"); rootDisplay.setAttribute("style","width:auto; height:auto;"); rootDisplay.setAttribute("class","text-center"); cell.appendChild(rootDisplay); const streamDisplay = document.createElement("div"); streamDisplay.setAttribute("style","width:auto; height:auto;"); streamDisplay.setAttribute("class","text-center"); rootDisplay.appendChild(streamDisplay); |
3.2.
...
Video tag addition
setVideo() code
Code Block | ||||
---|---|---|---|---|
| ||||
setVideo: function(stream) { if (video) { video.remove(); } if (stream == null) { video = null; this.videoMid = undefined; qualityDivs.forEach(function(div) { div.remove(); }); qualityDivs = []; return; } video = document.createElement("video"); video.muted = true; if(Browser().isSafariWebRTC()) { video.setAttribute("playsinline", ""); video.setAttribute("webkit-playsinline", ""); } streamDisplay.appendChild(video); video.srcObject = stream; video.onloadedmetadata = function (e) { video.play().then(function() { video.muted = false; }); }; video.addEventListener("resize", function (event) { streamNameDisplay.innerHTML = "Published by: " + name + "<br/>Current resolution: " + video.videoWidth + "x" + video.videoHeight; resizeVideo(event.target); }); }, |
3.3.
...
Audio tag addition
setAudio() code
Code Block | ||||
---|---|---|---|---|
| ||||
setAudio: function(stream) { if (audio) { audio.remove(); } if (!stream) { audio = null; this.audioMid = undefined; return; } audio = document.createElement("audio"); audio.controls = "controls"; audio.muted = true; audio.autoplay = true; cell.appendChild(audio); audio.srcObject = stream; audio.onloadedmetadata = function (e) { audio.play().then(function() { audio.muted = false; }); }; }, |
3.4.
...
Setting up quality switcher
setTrackInfo() code
Code Block | ||||
---|---|---|---|---|
| ||||
setTrackInfo: function(trackInfo) { if (trackInfo && trackInfo.quality) { for (let i = 0; i < trackInfo.quality.length; i++) { const qualityDiv = document.createElement("button"); qualityDivs.push(qualityDiv); qualityDiv.innerText = trackInfo.quality[i]; qualityDiv.setAttribute("style", "display:inline-block; border: solid; border-width: 1px"); qualityDiv.style.color = "red"; qualityDiv.addEventListener('click', function(){ console.log("Clicked on quality " + trackInfo.quality[i] + " trackId " + trackInfo.id); if (qualityDiv.style.color === "red") { return; } for (let c = 0; c < qualityDivs.length; c++) { if (qualityDivs[c].style.color !== "red") { qualityDivs[c].style.color = "gray"; } } qualityDiv.style.color = "blue"; room.changeQuality(trackInfo.id, trackInfo.quality[i]); }); qualityDisplay.appendChild(qualityDiv); } } }, |
3.5.
...
Removing the container
dispose() code
Code Block | ||||
---|---|---|---|---|
| ||||
dispose: function() { cell.remove(); }, |
4.
...
Subscription to ontrack PeerConnection event
PeerConnection.ontrack(), setAudio(), setVideo() code
Здесь:
...
Where:
- video or audio tag addition function is called when track is received
Code Block | ||||
---|---|---|---|---|
| ||||
peerConnection.ontrack = ({transceiver}) => { 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 " + pTrack.id + " mid " + pTrack.mid); if (pTrack.mid === transceiver.mid) { rParticipant = participant; break; } } if (rParticipant) { break; } } if (rParticipant) { for (const display of rParticipant.displays) { if (transceiver.receiver.track.kind === "video") { if (display.videoMid === transceiver.mid) { let stream = new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setVideo(stream); break; } } else if (transceiver.receiver.track.kind === "audio") { if (display.audioMid === transceiver.mid) { let stream = new MediaStream(); stream.addTrack(transceiver.receiver.track); display.setAudio(stream); break; } } } } else { console.warn("Failed to find participant for track " + transceiver.receiver.track.id); } } |
5.
...
Playback stopping
stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
const stop = function() { for (const [nickName, participant] of Object.entries(remoteParticipants)) { participant.displays.forEach(function(display){ display.dispose(); }); delete remoteParticipants[nickName]; } } |