Last active
June 12, 2022 12:40
-
-
Save kwindla/fe22b78d0d1c15ad114a8a601a86b898 to your computer and use it in GitHub Desktop.
Daily video call API example -- low resolution input track
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>low-resolution input track</title> | |
<script src="https://unpkg.com/@daily-co/daily-js"></script> | |
</head> | |
<!-- | |
example: setting input track to low resolution | |
--> | |
<body onload="main()"> | |
<div id="local-controls"> | |
<!-- for testing, controls to switch from sfu to p2p mode and back. NOTE: we | |
don't recommend doing this in production. Instead, just let daily-js | |
make the switch automatically as peers join and leave the session. If you | |
want to change the switchover threshold, set the `sfu_switchover` domain/room | |
property --> | |
<button onclick="call.setNetworkTopology({ topology: 'sfu'})"> | |
switch to sfu mode | |
</button> | |
<hr /> | |
<button onclick="call.setNetworkTopology({ topology: 'peer'})"> | |
switch to p2p mode | |
</button> | |
<hr /> | |
</div> | |
<div id="videos"></div> | |
<script> | |
const ROOM_URL = ...REPLACE WITH A ROOM URL...; | |
async function main() { | |
window.call = DailyIframe.createCallObject({ | |
audioSource: false, | |
url: ROOM_URL, | |
dailyConfig: { | |
experimentalChromeVideoMuteLightOff: true, | |
// note: with very low-resolution video is best to just use a | |
// single simulcast layer (in other words, no simulcast) | |
camSimulcastEncodings: [{ maxBitrate: 80000, maxFramerate: 20 }], | |
}, | |
}); | |
call.on('joined-meeting', () => console.log('[JOINED MEETING]')); | |
call.on('left-meeting', () => console.log('[LEFT MEETING]')); | |
call.on('error', (e) => console.error(e)); | |
call.on('participant-joined', (e) => | |
console.log('[PARTICIPANT JOINED]', e) | |
); | |
call.on('participant-updated', (e) => | |
console.log('[PARTICIPANT UPDATED]', e) | |
); | |
call.on('participant-left', (e) => | |
console.log('[PARTICIPANT LEFT]', e) | |
); | |
call.on('track-started', displayTrack); | |
call.on('track-stopped', destroyTrack); | |
// | |
// cleanest approach -- but does "flash" the camera light when re-fetching the | |
// lower-resolution stream after join | |
// | |
await call.join(); | |
call.setBandwidth({ | |
kbs: 80, | |
trackConstraints: { width: 64, height: 64 }, | |
}); | |
// option 2 -- reach into Daily's internals to use an undocumented | |
// function that modifies the constraints used every time getUserMedia() | |
// is called internally by daily-js | |
// | |
// await call.load(); | |
// _dailyConfig.experimentalGetUserMediaConstraintsModify = (constraints) => { | |
// constraints.video = { width: 64, height: 64 }; | |
// }; | |
// await call.join(); | |
// call.setBandwidth({ kbs: 80 }); | |
} | |
// ---- | |
function displayTrack(evt) { | |
console.log('[TRACK STARTED]', evt); | |
if (evt.track.kind === 'video') { | |
displayVideo(evt); | |
} else { | |
playAudio(evt); | |
} | |
} | |
function displayVideo(evt) { | |
console.log(evt); | |
if (!(evt.track.kind === 'video')) { | |
return; | |
} | |
let videosDiv = document.getElementById('videos'); | |
let videoEl = document.createElement('video'); | |
videosDiv.appendChild(videoEl); | |
videoEl.srcObject = new MediaStream([evt.track]); | |
videoEl.play(); | |
} | |
function playAudio(evt) { | |
if (evt.participant.local) { | |
return; | |
} | |
let audioEl = document.createElement('audio'); | |
document.body.appendChild(audioEl); | |
audioEl.srcObject = new MediaStream([evt.track]); | |
audioEl.play(); | |
} | |
function destroyTrack(evt) { | |
console.log( | |
'[TRACK STOPPED]', | |
(evt.participant && evt.participant.session_id) || '[left meeting]', | |
evt.track.kind | |
); | |
let els = Array.from(document.getElementsByTagName('video')).concat( | |
Array.from(document.getElementsByTagName('audio')) | |
); | |
for (let el of els) { | |
if (el.srcObject && el.srcObject.getTracks()[0] === evt.track) { | |
el.remove(); | |
} | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment