Skip to content

Commit

Permalink
Merge branch 'gh-pages' into too-verbose-logging
Browse files Browse the repository at this point in the history
  • Loading branch information
fippo authored Apr 7, 2022
2 parents 527ac04 + 69da7b7 commit 49d519f
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 21 deletions.
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ <h2 id="getusermedia"><a href="https://developer.mozilla.org/en-US/docs/Web/API/
<li><a href="src/content/getusermedia/getdisplaymedia/">Screensharing with getDisplayMedia</a></li>

<li><a href="src/content/getusermedia/pan-tilt-zoom/">Control camera pan, tilt, and zoom</a></li>

<li><a href="src/content/getusermedia/exposure/">Control exposure</a></li>
</ul>
<h2 id="devices">Devices:</h2>
<p class="description">Query media devices</p>
Expand Down
95 changes: 95 additions & 0 deletions src/content/getusermedia/exposure/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<!--
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
-->
<html>
<head>

<meta charset="utf-8">
<meta name="description" content="WebRTC code samples">
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1">
<meta itemprop="description" content="Client-side WebRTC code samples">
<meta itemprop="image" content="../../../images/webrtc-icon-192x192.png">
<meta itemprop="name" content="WebRTC code samples">
<meta name="mobile-web-app-capable" content="yes">
<meta id="theme-color" name="theme-color" content="#ffffff">

<base target="_blank">

<title>Control Exposure</title>

<link rel="icon" sizes="192x192" href="../../../images/webrtc-icon-192x192.png">
<link href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="../../../css/main.css">

<style>
div.label {
display: inline-block;
font-weight: 400;
margin: 0 0.5em 0 0;
width: 10em;
}
</style>
</head>

<body>

<div id="container">
<h1><a href="//webrtc.github.io/samples/" title="WebRTC samples homepage">WebRTC samples</a>
<span>Control Exposure</span></h1>

<video id="gum-local" autoplay playsinline></video>
<button id="showVideo">Open camera</button>

<div>
<div class="label">Exposure Mode:</div>
<select name="exposureMode" id="exposureMode" disabled>
</select>
</div>

<div>
<div class="label">Exposure Time:</div>
<input name="exposureTime" type="range" disabled>
</div>

<div>
<div class="label">Exposure Compensation:</div>
<input name="exposureCompensation" type="range" disabled>
</div>

<div>
<div class="label">Brightness:</div>
<input name="brightness" type="range" disabled>
</div>

<div>
<div class="label">White Balance Mode:</div>
<select name="whiteBalanceMode" id="whiteBalanceMode" disabled>
</select>
</div>

<button id="refreshControls" onClick="loadProperties(true)" disabled>Refresh Controls</button>

<div id="errorMsg"></div>

<p>Display the video stream from <code>getUserMedia()</code> in a video
element and control exposureMode, exposureTime and exposureCompensation if camera supports it.</p>

<p>The <code>MediaStreamTrack</code> object <code>track</code> is in
global scope, so you can inspect it from the console.</p>

<a href="https://github.com/webrtc/samples/tree/gh-pages/src/content/getusermedia/exposure"
title="View source for this page on GitHub" id="viewSource">View source on GitHub</a>
</div>

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>

<script src="../../../js/lib/ga.js"></script>

</body>
</html>
109 changes: 109 additions & 0 deletions src/content/getusermedia/exposure/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
'use strict';

// Put variables in global scope to make them available to the browser console.
const constraints = window.constraints = {
audio: false,
video: true
};

function handleSuccess(stream) {
const video = document.querySelector('video');
const videoTracks = stream.getVideoTracks();
console.log('Got stream with constraints:', constraints);
console.log(`Using video device: ${videoTracks[0].label}`);
video.srcObject = stream;

// make track variable available to browser console.
[window.track] = stream.getVideoTracks();

loadProperties();

document.querySelector(`button[id=refreshControls]`).disabled = false;
}

function loadProperties(refreshValuesOnly) {
const track = window.track;
const capabilities = track.getCapabilities();
const settings = track.getSettings();
console.log('Capabilities: ', capabilities);
console.log('Settings: ', settings);

for (const property of ['exposureMode', 'exposureTime', 'exposureCompensation', 'brightness', 'whiteBalanceMode']) {
// Check whether camera supports exposure.
if (!(property in settings)) {
errorMsg(`Camera does not support ${property}.`);
continue;
}

let element;

if (Array.isArray(capabilities[property])) {
// Map it to a select element.
const select = document.querySelector(`select[name=${property}]`);
element = select;
if (capabilities[property] && !refreshValuesOnly) {
for (const mode of capabilities[property]) {
select.insertAdjacentHTML('afterbegin', `<option value="${mode}">${mode}</option>`);
}
}
} else {
// Map it to a slider element.
const input = document.querySelector(`input[name=${property}]`);
element = input;
input.min = capabilities[property].min;
input.max = capabilities[property].max;
input.step = capabilities[property].step;
}

element.value = settings[property];
element.disabled = false;
if (!refreshValuesOnly) {
element.oninput = async event => {
try {
const constraints = {advanced: [{[property]: element.value}]};
await track.applyConstraints(constraints);
console.log('Did successfully apply new constraints: ', constraints);
console.log('New camera settings: ', track.getSettings());
} catch (err) {
console.error('applyConstraints() failed: ', err);
}
};
}
}
}

function handleError(error) {
if (error.name === 'NotAllowedError') {
errorMsg('Permissions have not been granted to use your camera, ' +
'you need to allow the page access to your devices in ' +
'order for the demo to work.');
}
errorMsg(`getUserMedia error: ${error.name}`, error);
}

function errorMsg(msg, error) {
const errorElement = document.querySelector('#errorMsg');
errorElement.innerHTML += `<p>${msg}</p>`;
if (typeof error !== 'undefined') {
console.error(error);
}
}

async function init(e) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
handleSuccess(stream);
e.target.disabled = true;
} catch (e) {
handleError(e);
}
}

document.querySelector('#showVideo').addEventListener('click', e => init(e));
38 changes: 17 additions & 21 deletions src/content/peerconnection/trickle-ice/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function selectServer(event) {

function addServer() {
const scheme = urlInput.value.split(':')[0];
if (scheme !== 'stun' && scheme !== 'turn' && scheme !== 'turns') {
if (!['stun', 'stuns', 'turn', 'turns'].includes(scheme)) {
alert(`URI scheme ${scheme} is not valid`);
return;
}
Expand Down Expand Up @@ -155,32 +155,28 @@ async function start() {
// Whether we only gather a single set of candidates for RTP and RTCP.

console.log(`Creating new PeerConnection with config=${JSON.stringify(config)}`);
document.getElementById('error').innerText = '';
pc = new RTCPeerConnection(config);
pc.onicecandidate = iceCallback;
pc.onicegatheringstatechange = gatheringStateChange;
pc.onicecandidateerror = iceCandidateError;
if (stream) {
stream.getTracks().forEach(track => pc.addTrack(track, stream));
const errDiv = document.getElementById('error');
errDiv.innerText = '';
let desc;
try {
pc = new RTCPeerConnection(config);
pc.onicecandidate = iceCallback;
pc.onicegatheringstatechange = gatheringStateChange;
pc.onicecandidateerror = iceCandidateError;
if (stream) {
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}
desc = await pc.createOffer(offerOptions);
} catch (err) {
errDiv.innerText = `Error creating offer: ${err}`;
gatherButton.disabled = false;
return;
}
pc.createOffer(
offerOptions
).then(
gotDescription,
noDescription
);
}

function gotDescription(desc) {
begin = window.performance.now();
candidates = [];
pc.setLocalDescription(desc);
}

function noDescription(error) {
console.log('Error creating offer: ', error);
}

// Parse the uint32 PRIORITY field into its constituent parts from RFC 5245,
// type preference, local preference, and (256 - component ID).
// ex: 126 | 32252 | 255 (126 is host preference, 255 is component ID 1)
Expand Down

0 comments on commit 49d519f

Please sign in to comment.