比較的新しい Web API の1つである MediaDevices インターフェースを使って、HTML と JavaScript だけで(PCの)画面共有が実現できるようになりました。とりあえず使ってみるには PC のウェブブラウザ※で以下のサイトにアクセスしてみてください:
https://dotnsf.github.io/display_media_stream/

※対応ブラウザはこちら: 
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#Browser_compatibility



対応ブラウザで上記 URL にアクセスすると、画面共有のダイアログが表示されます:
2020033101


何かひとつ(下図の例では「アプリケーションウィンドウ」タブの「タスクマネージャー」)選択して、「共有」ボタンをクリックすると、、
2020033102


選択したアプリケーションのウィンドウ内画面がストリームでウェブブラウザに表示されます。最初に「全画面」を選んでいればウィンドウ全体がブラウザ内に表示されます:
2020033103


この機能を停止するには共有ダイアログの「共有を停止」ボタンをクリックしてください:
2020033104


以下、上記デモのソースコードを紹介します。コードそのものはこちらで公開しています:
https://github.com/dotnsf/display_media_stream


上記デモは実質的に index.html ファイルだけで実現しています。つまり HTML と JavaScript だけで実現しています。まず HTML 部(<body>部)は以下の通り、かなりシンプルです:
<body>
  <!-- Video element (live stream) -->
  <div>
    <video autoplay playsinline id="video" width="640" height="480"></video>
  </div>
</body>

<div> 要素の中に <video> 要素が1つだけ、autoplay 属性と playsinline 属性がついた状態で存在しています。一応初期サイズの指定もしていますが後で JavaScript で修正します。

次に肝となる JavaScript 部はこちらです:
<script>
var localVideo = null;

function gotLocalMediaStream( mediaStream ){
  localVideo.srcObject = mediaStream;
}

function handleLocalMediaStreamError( error ){
  console.log( "navigator.getUserMedia error: ", error );
}


$(function(){
  //. 画面サイズ取得
  var sw = window.parent.screen.width;
  var sh = window.parent.screen.height;
  //sw : sh = x : 480; => x = 480 * sw / sh;
  var x = Math.floor( 480 * sw / sh );
  $('#video').css( { width: x } );

  var mediaStreamConstraints = { video: true };
  localVideo = document.querySelector( "video" );
  navigator.mediaDevices.getDisplayMedia( mediaStreamConstraints ).then( gotLocalMediaStream ).catch( handleLocalMediaStreamError );
});
</script>

実質的には $(function(){ ... }); 部分が最初に実行されます。まずは window.parent.screen にアクセスして実画面のサイズを取得し、その縦横割合に合わせて上述の video 要素をリサイズ(縦は 480 に固定して、横を同割合になるようリサイズ)します。

そしてこの画面共有を実現しているのはこの1行です:
  navigator.mediaDevices.getDisplayMedia( mediaStreamConstraints ).then( gotLocalMediaStream ).catch( handleLocalMediaStreamError );

mediaDevices インターフェースの getDisplayMedia メソッドを、{ video: true } というオブジェクトを引数に実行しています。これがカメラやマイクではなくディスプレイ画面のストリームを取得するための処理で、成功すると gotLocalMediaStream 関数がコールバックされます。

その gotLocalMediaStream 関数は以下のような内容になっています:
<script>
var localVideo = null;

function gotLocalMediaStream( mediaStream ){
  localVideo.srcObject = mediaStream;
}

getDisplayMedia メソッドで取得したメディアストリームを引数にコールバックされ、その値を video 要素として取得済みの localVideo 変数の srcObject 属性に代入しています。これだけで後はディスプレイ画面の動画ストリームが video 要素の中で自動再生(autoplay)されます。


mediaDevices インターフェースや getDisplayMedia メソッドがまだ限られたブラウザ(Chrome, FireFox, Edge)の比較的新しいバージョンでしか使えず、スマホ系ブラウザでは全滅という状況ではあるのですが、ネイティブアプリを使わなくてもブラウザの JavaScript だけでここまでできるようになっていたんですね。video 要素として使えるということはスクリーンショットとかいろいろ応用できそう・・・