This is impossible right now but it may be possible in the near future. You should take a look at MediaStream Image Capture Working Draft. This spec describes advance options for .applyConstraints
, initially introduced in Media Capture and Streams.
How it works according to spec? First, you need to get the capabilities by using .getCapabilities
. If the browser can manage focus, then you can set focusMode: "auto" | "manual"
and focusDistance: number
for current constraints.
Focus mode describes the focus setting of the capture device (e.g. auto or manual).
Focus distance is a numeric camera setting that controls the focus distance of the lens. The setting usually represents distance in meters to the optimal focus distance.
Unfortunately, you can't control the focus at the moment, but you can check the code that may work in the future.
Chrome issue about support for focusDistance | Chrome Platform Status | MediaCapture Image Implementation Status.
CodeSandbox Demo
navigator.mediaDevices
.getUserMedia({ video: true })
.then(gotMedia)
.catch(err => console.error("getUserMedia() failed: ", err));
function gotMedia(mediastream) {
const video = document.querySelector("video");
video.srcObject = mediastream;
const track = mediastream.getVideoTracks()[0];
const capabilities = track.getCapabilities();
// Check whether focus distance is supported or not.
if (!capabilities.focusDistance) {
return;
}
// Map focus distance to a slider element.
const input = document.querySelector('input[type="range"]');
input.min = capabilities.focusDistance.min;
input.max = capabilities.focusDistance.max;
input.step = capabilities.focusDistance.step;
input.value = track.getSettings().focusDistance;
input.oninput = function(event) {
track.applyConstraints({
advanced: [{
focusMode: "manual",
focusDistance: event.target.value
}]
});
};
input.hidden = false;
}
<video autoplay></video>
<input type="range" hidden />