WebCodecs Screen Content

by fippo

HTML

<script src="https://code.highcharts.com/highcharts.js"></script>
<video id="localVideo" autoplay muted></video>
<div id="graph"></div>
<div id="total"></div>

CSS

video {
  width: 320px;
}

JavaScript

const frameRate = 5;
async function run() {
  const stream = await navigator.mediaDevices.getDisplayMedia({video: {frameRate}});
  document.getElementById('localVideo').srcObject = stream;
  
  const processor = new MediaStreamTrackProcessor(stream.getTracks()[0]);
  const inputStream = processor.readable;
  let bytes = {normal: 0, screen: 0};
  const series = {normal: [], screen: []};
  const encoder = new VideoEncoder({
    output: (encodedFrame, metadata) => {
    	console.log('NORMAL', encodedFrame.byteLength);
      bytes.normal += encodedFrame.byteLength;
      series.normal.push([Date.now(), encodedFrame.byteLength]);
    },
    error: (e) => console.error('enc err', e.message),
  });  
  encoder.configure({
    codec: 'av01.0.04M.08',
    width: 1920,
    height: 1080,
    bitrate: 2_000_000,
    framerate: frameRate,
  });
  
  const encoderScreen = new VideoEncoder({
    output: (encodedFrame, metadata) => {
    	console.log('SCREEN', encodedFrame.byteLength);
      bytes.screen += encodedFrame.byteLength;
      series.screen.push([Date.now(), encodedFrame.byteLength]);
    },
    error: (e) => console.error('enc err', e.message),
  });  
  encoderScreen.configure({
    codec: 'av01.0.04M.08',
    width: 1920,
    height: 1080,
    bitrate: 2_000_000,
    framerate: frameRate,
    contentHint: 'detail',
  });
  
  graph.addSeries({
    name: 'normal',
    data: [],
    type: 'scatter',
  }, true);
  graph.addSeries({
    name: 'screen',
    data: [],
    type: 'scatter',
  }, true);
  setInterval(() => {
  	for (let i = 0; i < series.normal.length; i++) {
      graph.series[0].addPoint(series.normal[i], i === series.normal.length - 1);
    }
    series.normal = [];
   	for (let i = 0; i < series.screen.length; i++) {
      graph.series[1].addPoint(series.screen[i], i === series.screen.length - 1);
    }
    series.screen = [];
    document.getElementById('total').innerText = 'Normal: ' + bytes.normal +
    	', screen: ' + bytes.screen + 
      ', ratio...