Как включить фотографирование прямо на HTML-странице (а не открывать приложение камеры)? - PullRequest
0 голосов
/ 20 октября 2019

Мне известен метод

<input type="file" accept="image/*" capture>

, позволяющий пользователю делать снимок (и другие подобные примеры здесь с accept="video/*" и т. Д.), И при использовании этого, нажатие на <input> обычно открывает приложение камеры телефона , позволяет пользователю сделать фотографию, а затем возвращается на исходную страницу.

Но как с помощью Javascriptпредварительный просмотр камеры непосредственно на HTML-странице, с помощью <div> и кнопки «Сделать фотографию», т. е. не нужно открывать приложение камеры телефона?

(Конечно,пользователю придется предоставить доступ к камере телефона)

1 Ответ

1 голос
/ 21 октября 2019

Благодаря этому руководству я наконец-то нашел решение, используя getUserMedia.

NB: начиная с последних версий Chrome, из соображений безопасности, оно толькоработает, если сайт HTTPS. Вы можете запустить Chrome с "C:\Program Files\Google\Chrome\Application\chrome.exe" --unsafely-treat-insecure-origin-as-secure="http://123.123.123.123", если хотите протестировать его на веб-сайте, отличном от HTTPS.

var videoElement = document.querySelector('video');
var audioSelect = document.querySelector('select#audioSource');
var videoSelect = document.querySelector('select#videoSource');

audioSelect.onchange = getStream;
videoSelect.onchange = getStream;

getStream().then(getDevices).then(gotDevices);

function getDevices() { return navigator.mediaDevices.enumerateDevices(); }

function gotDevices(deviceInfos) {
  window.deviceInfos = deviceInfos; 
  for (const deviceInfo of deviceInfos) {
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') { option.text = deviceInfo.label || `Microphone ${audioSelect.length + 1}`; audioSelect.appendChild(option); } 
if (deviceInfo.kind === 'videoinput') { option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`; videoSelect.appendChild(option); }
  }
}

function getStream() {
  if (window.stream) { window.stream.getTracks().forEach(track => { track.stop(); }); }
  const audioSource = audioSelect.value;
  const videoSource = videoSelect.value;
  const constraints = { audio: {deviceId: audioSource ? {exact: audioSource} : undefined}, video: {deviceId: videoSource ? {exact: videoSource} : undefined} };
  return navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(handleError);
}

function gotStream(stream) {
  window.stream = stream;
  audioSelect.selectedIndex = [...audioSelect.options].findIndex(option => option.text === stream.getAudioTracks()[0].label);
  videoSelect.selectedIndex = [...videoSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);
  videoElement.srcObject = stream;
}

function handleError(error) { console.error('Error: ', error); }
<div id="container">
<div class="select"><label for="audioSource">Audio source: </label><select id="audioSource"></select></div>
<div class="select"><label for="videoSource">Video source: </label><select id="videoSource"></select></div>
<video autoplay muted playsinline></video>
</div>
...