async applyConstraints gdm

Test

by jib1

HTML

Height <input id="number" type="number" min="2" max="2160" value="480">
<input id="range" type="range" min="0" max="2160" value="480">
<div id="div2"><p>0 x 0 x 0.0</p></div>
<div id="div"></div>
<video id="video" autoplay></video><br>
<button id="button">Start</button>

JavaScript

const console = {log: msg => div.innerHTML += `${msg}<br>`};
const update = msg => div2.innerHTML = `<p>${msg}</p>`;
const wait = ms => new Promise(r => setTimeout(r, ms));
const frames = v => v.mozPaintedFrames || v.webkitDecodedFrameCount || 0;

range.oninput = () => apply(number.value = range.value);
number.oninput = () => apply(range.value = number.value);

let track, applying = false, height = 0;

async function apply(h) {
  height = h;
  if (applying) return;
  try {
    applying = true;
    do {
      h = height;
      await track.applyConstraints({height});
    } while (h != height);
  } catch (e) {
    console.log(e);
  } finally {
    applying = false;
  }
}

button.onclick = async () => {
  try {
    video.srcObject = await navigator.mediaDevices.getDisplayMedia();
    track = video.srcObject.getVideoTracks()[0];
    await new Promise(r => video.onloadedmetadata = r);
    number.value = range.value = track.getSettings().height;
    let t1 = 0, t2 = 1, f1 = 0, f2 = 0;
    while (true) {
      await wait(500);
      t2 = video.currentTime; f2 = frames(video);
      const hz = (f2 - f1) / (t2 - t1);
      update(`${video.videoWidth} x ${video.videoHeight} x ${hz.toFixed(2)}`);
      t1 = t2; f1 = f2;
    }
  } catch(e) {
    console.log(e);
  }
};