Фронтенд разработка на языке JavaScript./ Работа с веб камерой и холстом.

Работа с веб камерой и холстом.

В начале необходимо добавить элемент video на страницу.

<video autoplay="true" id="videoElement"></video>

ссылка на документацию элемента

В коде получаем элемент.

var video = document.querySelector("#videoElement");

Этот элемент имеет такое свойство video.srcObject в которое можно положить видеопоток камеры.

Существует такой метод

navigator.mediaDevices.getUserMedia({ video: true })

Он нам возвращает промис, который может запустить колбек, который мы впихнем в then и передаст в него поток с камеры.

ссылка на документацию

Захватываем видео.

if (navigator.mediaDevices.getUserMedia) {
  navigator.mediaDevices.getUserMedia({ video: true })
    .then(function (stream) {
      video.srcObject = stream;
    })
    .catch(function (err0r) {
      console.log("Something went wrong!");
    });
}

У элемента video есть одно полезное событие, которое происходит в момент доступности видео, т.к. процесс инициализации может занимать время, это бывает полезно.

video.addEventListener('canplay', function(ev){...})

Приостановка трансляции.

Поток может содержать много треков (например брать звук с нескольких мкрофонов).

Поэтому при останове, мы по ним должны пробегать и каждого стопать.

function stop(e) {
  var stream = video.srcObject;
  var tracks = stream.getTracks();

  for (var i = 0; i < tracks.length; i++) {
    var track = tracks[i];
    track.stop();
  }

  video.srcObject = null;
}

Забираем картинку с камеры и пишем в канвас.

Ставим на страницу канвас и элемент картинки.

  <canvas id="canvas"> </canvas>
  <img id="photo" alt="The screen capture will appear in this box.">

Получаем элементы.

canvas = document.getElementById('canvas');
photo = document.getElementById('photo');

Прикол канваса в том, что в его контекст можно запихнуть то, что в данный момент в элементе video так:

context.drawImage(video, 0, 0, width, height);

Но сперва этот контекст нужно получить.

 var context = canvas.getContext('2d');

Конвертировать то что на холсте в формат, доступный элементу img.

var data = canvas.toDataURL('image/png');

Кинуть данные в img.

photo.setAttribute('src', data);

ссылка на статью с работой с инструментом webcam-easy

Рисование примитивов.

Сетка.

start page

Прямоугольники.

Холст поддерживает только одну примитивную фигуру: прямоугольник.

Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть функции, которые делают возможным составление очень сложных фигур.

Функции для рисования.

fillRect(x, y, width, height) - Рисование заполненного прямоугольника.

strokeRect(x, y, width, height) - Рисование прямоугольного контура.

clearRect(x, y, width, height) - Очистка прямоугольной области, делая содержимое совершенно прозрачным.

Рисование контуров (path)

ссылка на источник

Остальные примитивные фигуры создаются контурами. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

Создание фигур используя контуры происходит в несколько важных шагов:

Сначала вы создаете контур.

Затем, используя команды рисования, рисуете контур.

Потом закрываете контур (чтобы вернуться в контекст).

Созданный контур вы можете обвести или залить для его отображения.

Функции

beginPath() - Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.

closePath() - Закрывает контур, так что будущие команды рисования вновь направлены контекст.

stroke() - Рисует фигуру с внешней обводкой.

fill() - Рисует фигуру с заливкой внутренней области.

Пример рисования треугольника.

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.moveTo(75,50);
    ctx.lineTo(100,75);
    ctx.lineTo(100,25);
    ctx.fill();
  }
}

moveTo - передвижение пера.

Дуги

Для рисования дуг и окружностей, используем методы arc() и arcTo().

arc(x, y, radius, startAngle, endAngle, anticlockwise)

Рисуем дугу с центром в точке (x,y) радиусом radius, начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).

arcTo(x1, y1, x2, y2, radius)

Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.

Openvidu

Установка docker и docker-compose.

apt install docker-ce docker-compose

Установка openvidu

cd /opt
curl https://s3-eu-west-1.amazonaws.com/aws.openvidu.io/install_openvidu_latest.sh | bash

Прописываем настройки DOMAIN_OR_PUBLIC_IP и OPENVIDU_SECRET в .env

Стартуем сервер.

./openvidu start

Старт сервера вручную

docker run -p 4443:4443 --rm -e OPENVIDU_SECRET=MY_SECRET openvidu/openvidu-server-kms:2.18.0

Устанавливаем пример приложения.

git clone https://github.com/OpenVidu/openvidu-tutorials.git -b v2.18.0

Подсоединяем клиента.

<script src="openvidu-browser-2.18.0.js"></script>

Стартуем сессию.

var myapp = {
    initappSender: (uname) => {
        console.log(`Init sender ${uname}`);
        OV = new OpenVidu();
        session = OV.initSession();
        console.log(session);
    }
}

Далее создаем сессию на сервере, передав токен пользователя.

var myapp = {
    OPENVIDU_SERVER_URL: 'https://localhost:4443',
    OPENVIDU_SERVER_SECRET: 'MY_SECRET',
    initappSender: function (uname){
        console.log(`Init sender ${uname}`);
        OV = new OpenVidu();
        session = OV.initSession();

        session.on('exception', (exception) => {
            console.warn(exception);
        });
        this.createSession('dimon');
    },

    createSession: function(sessionId) { // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-openviduapisessions
        return new Promise((resolve, reject) => {
            $.ajax({
                type: "POST",
                url: this.OPENVIDU_SERVER_URL + "/openvidu/api/sessions",
                data: JSON.stringify({ customSessionId: sessionId }),
                headers: {
                    "Authorization": "Basic " + btoa("OPENVIDUAPP:" + this.OPENVIDU_SERVER_SECRET),
                    "Content-Type": "application/json"
                },
                success: (response) => { 
                    console.log(response);
                    resolve(response.id)
                },
                error: (error) => {
                    if (error.status === 409) {
                        resolve(sessionId);
                    } else {
                        console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + this.OPENVIDU_SERVER_URL);
                        if (window.confirm('No connection to OpenVidu Server. This may be a certificate error at \"' + this.OPENVIDU_SERVER_URL + '\"\n\nClick OK to navigate and accept it. ' +
                            'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' + this.OPENVIDU_SERVER_URL + '"')) {
                            location.assign(this.OPENVIDU_SERVER_URL + '/accept-certificate');
                        }
                    }
                }
            });
        });
    }

}
Задать вопрос, прокомментировать.