WebRTC-Experiment icon indicating copy to clipboard operation
WebRTC-Experiment copied to clipboard

Cleanup of getDisplayMedia demo

Open jabcreations opened this issue 1 year ago • 1 comments

I'm not doing forks and all of this other nonsense. Here are just some of the things I did to clean up the demo file:

  • Used XML parser instead of HTML to discriminate against low quality code.
  • Moved all JavaScript in to proper named JavaScript functions.
  • Moved the script element to the head element where it belongs.
  • Implemented object detection to nullify older and non-supportive browsers triggering errors.
  • Removed irresponsible camelCase that should explicitly only be utilized by standards with proper underscore_lowercase naming conventions.
  • Fixed the script element to have the proper application/javascript mime.
  • Cleaned up CSS to make it more professional looking.
  • Replaced AW!-I'M-BLIND!-mode with dark-mode.
  • Fixed head-shaker style curly brackets so people learning will not break their necks.
  • Fixed white-space to not require 16K worth of horizontal whitespace indentation.
  • Numerous other tweaks to make the code readable.

Save the following as index.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>getDisplayMedia demo</title>
<style>
* {border: 0; margin: 0; padding: 0;}
a {color: #fff; text-decoration: none;}
a:focus, a:hover {text-decoration: underline;}
body, html {background-color: #000; color: #ccc; font-size: 1em; text-align: center;}
button, input, select, textarea {background-color: #000; border: 1px solid #777; color: #ccc; padding: 0 2px;}
button:focus, button:hover, input:focus, input:hover, select:focus, select:hover, textarea:focus, textarea:hover {border-color: #fff;}
label {border: 1px dotted #777; padding: 0 2px; margin-left: 4px;}
label:hover {border-style: solid;}
p {margin: 16px;}
video {border: 1px solid #777; border-radius: 4px; width: 40%;}
.flex {align-content: center; display: flex; justify-content: center;}
</style>
<script type="application/javascript">
//<![CDATA[
function id_(id) {return ((document.getElementById(id)) ? document.getElementById(id) : false);}

function get_display_media_init()
{
 var button = id_('btn-test-getDisplayMedia'),
 video = document.querySelector('video');


 button.setAttribute('disabled', 'true');
 
 get_display_media_invoke(function(screen)
 {
  add_stream_stop_listener(screen, function() {location.reload();});
  
  video.srcObject = screen;

  if (typeof screen.getTracks == 'function' && screen.getTracks.length > 0 && typeof screen.getTracks()[0].getCapabilities == 'function')
  {
   var _capabilities = screen.getTracks()[0].getCapabilities();
   id_('capabilities').value = 'capabilities:\n\n' + JSON.stringify(_capabilities, null, '\t');
   id_('capabilities').style.display = '';

   var _settings = screen.getTracks()[0].getSettings();
   id_('settings').value = 'settings:\n\n' + JSON.stringify(_settings, null, '\t');
   id_('settings').style.display = '';
  }
 },


 function(e)
 {
  button.disabled = false;

  var error = {
   name: e.name || 'UnKnown',
   message: e.message || 'UnKnown',
   stack: e.stack || 'UnKnown'
  };

  if (error.name === 'PermissionDeniedError')
  {
   if (location.protocol !== 'https:')
   {
    error.message = 'Please use HTTPs.';
    error.stack   = 'HTTPs is required.';
   }
  }

  console.error(error.name);
  console.error(error.message);
  console.error(error.stack);

  alert('Unable to capture your screen.\n\n' + error.name + '\n\n' + error.message + '\n\n' + error.stack);
 });
}


function get_display_media_invoke(success, error)
{
 var video_constraints = {};

 if (id_('aspect_ratio').value !== 'default') {video_constraints.aspect_ratio = id_('aspect_ratio').value;}
 if (id_('frame_rate').value !== 'default') {video_constraints.frame_rate = id_('frame_rate').value;}
 if (id_('cursor').value !== 'default') {video_constraints.cursor = id_('cursor').value;}
 if (id_('display_surface').value !== 'default') {video_constraints.display_surface = id_('display_surface').value;}
 if (id_('logical_surface').value !== 'default') {video_constraints.logical_surface = true;}
 if (id_('resolutions').value !== 'default')
 {
  if (id_('resolutions').value === 'fit-screen')
  {
   video_constraints.width = screen.width;
   video_constraints.height = screen.height;
  }

  if (id_('resolutions').value === '4K')
  {
   video_constraints.width = 3840;
   video_constraints.height = 2160;
  }

  if (id_('resolutions').value === '1080p')
  {
   video_constraints.width = 1920;
   video_constraints.height = 1080;
  }

  if (id_('resolutions').value === '720p')
  {
   video_constraints.width = 1280;
   video_constraints.height = 720;
  }

  if (id_('resolutions').value === '480p')
  {
   video_constraints.width = 853;
   video_constraints.height = 480;
  }

  if (id_('resolutions').value === '360p')
  {
   video_constraints.width = 640;
   video_constraints.height = 360;
  }
 }

 if (!Object.keys(video_constraints).length) {video_constraints = true;}

 var display_media_stream_constraints = {video: video_constraints};

 if (navigator.mediaDevices.getDisplayMedia) {navigator.mediaDevices.getDisplayMedia(display_media_stream_constraints).then(success).catch(error);}
 else {navigator.getDisplayMedia(display_media_stream_constraints).then(success).catch(error);}
}


function add_stream_stop_listener(stream, callback)
{
 stream.addEventListener('ended', function() {callback(); callback = function() {};}, false);
 stream.addEventListener('inactive', function() {callback(); callback = function() {};}, false);
 stream.getTracks().forEach(function(track) {track.addEventListener('ended', function() {callback(); callback = function() {};}, false);
 track.addEventListener('inactive', function() {callback(); callback = function() {};}, false);});
}


window.onload = function(event)
{
 if (!navigator.getDisplayMedia && !navigator.mediaDevices.getDisplayMedia)
 {
  var error = 'Your browser does NOT supports getDisplayMedia API.';
  document.querySelector('h1').textContent = error;
  document.querySelector('h1').style.color = '#f00';
 }
}
//]]>
</script>
</head>
<body>

<h1>getDisplayMedia demo</h1>
<p>Purpose of this demo is to test all getDisplayMedia API functionalities.</p>

<br />

<div class="flex">
<label for="aspect_ratio">Aspect Ratio:</label><select id="aspect_ratio">
 <option value="default">Default</option>
 <option value="1.77">16:9</option>
 <option value="1.33">4:3</option>
 <option value="2.35">21:9</option>
 <option value="1.4">14:10</option>
 <option value="1.9">19:10</option>
</select>

<label for="frame_rate">Frame Rate:</label><select id="frame_rate">
 <option value="default">Default</option>
 <option>30</option>
 <option>25</option>
 <option>15</option>
 <option>5</option>
</select>

<label for="resolutions">Resolutions:</label><select id="resolutions">
 <option value="default">Default</option>
 <option value="fit-screen">Fit Screen</option>
 <option>4K</option>
 <option>1080p</option>
 <option>720p</option>
</select>

<label for="cursor">Cursor:</label><select id="cursor">
 <option value="default">Default</option>
 <option>always</option>
 <option>never</option>
 <option>motion</option>
</select>

<label for="display_surface">Display Surface:</label><select id="display_surface">
 <option value="default">Default</option>
 <option>monitor</option>
 <option>window</option>
 <option>application</option>
 <option>browser</option>
</select>

<label for="logical_surface">Logical Surface:</label><select id="logical_surface">
 <option value="default">Default</option>
 <option>true</option>
</select>
</div>

<br /><br />

<button id="btn-test-getDisplayMedia" onclick="get_display_media_init();">Test getDisplayMedia API</button>

<hr />
<video autoplay="true" controls="true" disablepictureinpicture="true" playsinline="" muted="false" volume="0"></video>
<!-- disablePictureInPicture -->
<br />

<textarea id="settings" style="width: 100%; height: 218px; display: none;"></textarea>

<br />

<textarea id="capabilities" style="width: 100%; height: 354px; display: none;"></textarea>

<br />

<footer style="margin-top: 20px; text-align: left;">

<h2>Browser Support</h2>
<p>Edge and Chrome &#62;= 71 <small>and possibly Safari latest preview.</small></p>

<h2>Usage</h2>
<pre style="padding: 5px 10px;">var display_media_stream_constraints = {
 video: true // or pass HINTS
};

if (navigator.mediaDevices.getDisplayMedia) {
 navigator.mediaDevices.getDisplayMedia(display_media_stream_constraints).then(success).catch(error);
} else {
 navigator.getDisplayMedia(display_media_stream_constraints).then(success).catch(error);
}
</pre>

<p style="padding: 5px 10px;">Spec: <a href="https://w3c.github.io/mediacapture-screen-share/" target="_blank">https://w3c.github.io/mediacapture-screen-share/</a></p>

</footer>

</body>
</html>

jabcreations avatar Jun 30 '23 23:06 jabcreations