English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Пример использования камеры и съёмки экрана с помощью JS

Без weiterer Worte, полный процесс JS для открытия камеры и создания скриншота для загрузки на сервер

1. Для открытия камеры используется метод getUserMedia, а затем получаемый поток媒体 вставляется в тег video

2. Для захвата изображения 主要 используется canvas для рисования, метод drawImage используется для рисования содержимого video на canvas

3. Загружаем содержимое на сервер, преобразуем содержимое canvas в формат base64 и загружаем его, а сервер (PHP) использует file_put_contents для преобразования его в изображение

需要注意的是, в браузерах, кроме Chrome, использование камеры может вызывать некоторые проблемы, возможно, это и старая проблема, поэтому следующий код основан на Chrome

Например, ошибка в последней версии Firefox, не знаю почему

1. Открываем камеру

getUserMedia имеет две версии: старую и новую. Рекомендуется использовать новую версию

Старая версия находится под объектом navigator, в зависимости от браузера может варьироваться

 // 获取媒体方法(旧方法)
  navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia; 
if (navigator.getMedia) {
    navigator.getMedia({
      
    
      mediaStreamTrack = stream.getTracks()[0];
      video.src = (window.URL || window.webkitURL).createObjectURL(stream);
      video.play();
    }, function(err) {
      console.log(err);
    });
  } 

Первый параметр указывает, необходимо ли использовать видео (video) или аудио (audio)

Второй параметр указывает на обработчик вызова в случае успеха, который принимает один параметр (MediaStream). В старой версии можно было напрямую вызвать MediaStream.stop() для关闭 камеры, но в новой версии это уже устарело. Необходимо использовать MediaStream.getTracks()[index].stop() для закрытия соответствующего трека

Третий параметр указывает на обработчик вызова в случае неудачи

Новая версия находится под объектом navigator.mediaDevices

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true
    }).then(function(stream) {
      console.log(stream);
      mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1];
      video.src = (window.URL || window.webkitURL).createObjectURL(stream);
      video.play();
    }).catch(function(err) {
      console.log(err);
    })
  } 

Как и в старой версии, но该方法 возвращает объект Promise, который можно использовать с then и catch для обработки вызовов успеха и неудачи

需要注意的是, массив Tracks, возвращаемый MediaStream.getTracks(), отсортирован в обратном порядке по первому параметру

Например, сейчас определено

{
  video: true,
  audio: true
} 

Чтобы关闭 камеру, нужно вызвать MediaStream.getTracks()[1].stop();

Аналогично, 0 соответствует треку аудио

Используя createObjectURL, можно записать MediaStream в тег video, чтобы хранить данные реального времени потокового媒体 (и также удобно смотреть на изображение в реальном времени)

в старых версиях объект webkitURL больше не поддерживается, нужно использовать объект URL

  <video width="200" height="150"></video>
  <canvas width="200" height="150"></canvas>
  <p>
    <button id="snap">Capture image</button>
    <button id="close">Закрыть камеру</button>
    <button id="upload">Загрузить изображение</button>
  </p>
  <img id="uploaded" width="200" height="150" /> 

2. Capture image

введите содержимое

 // Снимок изображения
  snap.addEventListener('click', function() {
    context.drawImage(video, 0, 0, 200, 150);
  }, false); 

3. Закрытие камеры

 // Закрытие камеры
  close.addEventListener('click', function() {
    mediaStreamTrack && mediaStreamTrack.stop();
  }, false); 

4. Загрузка загруженного изображения

canvas.toDataURL('image/png')

// Загрузка截анного изображения
  upload.addEventListener('click', function() {
    jQuery.post('/uploadSnap.php', {
      snapData: canvas.toDataURL('image/png')
    }).done(function(rs) {
      rs = JSON.parse(rs);
      console.log(rs);
      uploaded.src = rs.path;
    }).fail(function(err) {
      console.log(err);
    });
  }, false); 

а здесь серверная часть (PHP) преобразует полученный контент в файл изображения и сохраняет его

необходимо учитывать, что перед сохранением нужно удалить заголовок информации base64, в противном случае изображение, возможно, будет повреждено и не откроется

 <?php
  $snapData = $_POST['snapData'];
  $snapData = str_replace('data:image/png;base64,', '', $snapData);
  // $snapData = str_replace(' ', '+', $snapData);
  $img = base64_decode($snapData);
  $uploadDir = 'upload/';
  $fileName = date('YmdHis', time()) . uniqid();
  if (!(file_put_contents($uploadDir . $fileName, $img))) {
    echo json_encode(array('code' => 500, 'msg' => 'файл не загружен'));
  } else {
    echo json_encode(array('code' => 200, 'msg' => 'файл загружен успешно', 'path' => $uploadDir . $fileName));
  }
?> 

полный код JS

<script type="text/javascript" src="jquery.js"></script>