'Draw rectangle over HTML 5 tag video

I tried to use canvas to draw a rectangle 100 x 100 over the center of the image captured by webcam (using "navigator.mediaDevices.getUserMedia") and HTML 5 tag "video".

To capture a webcam image I use :

if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: 'user'}})
        .then( function(stream) {
            //Definir o elemento víde a carregar o capturado pela webcam
            video.srcObject = stream;
            return stream;            
        })
        .catch(function(error) {
            alert("Error on open device");
        });
    }

and to display this image on line I just use:

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

How can I draw a rectangle over image printed by HTML 5 tag video?

My code are :

camera.html

<!DOCTYPE html>
<html lang="pt-BR">
    <head>
        <!--Título-->
        <title>Camera Test</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Apenas um teste"/>

        <!--OpenType-->
        <meta property="og:locale" content="pt_BR" />
        <meta property="og:type" content="website" />
        <meta property="og:title" content="" />
        <meta property="og:description" content="" />
        <meta property="og:url" content="" />
        <meta property="og:site_name" content="" />

        <!--CSS-->
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div class="area">
            <video autoplay="true" id="webCamera">
            </video>
            <form target="POST">
                <textarea  type="text" id="base_img" name="base_img"></textarea>
                <button type="button" onclick="takeSnapShot()">Snapshot</button>
            </form>
            <img id="imagemConvertida"/>
            <p id="caminhoImagem" class="caminho-imagem"><a href="" target="_blank"></a></p>
            <!--Scripts-->
            <script src="script.js"></script>
        </div>
    </body>
</html>

script.js

function loadCamera(){
    //Captura elemento de vídeo
    var video = document.querySelector("#webCamera");
        //As opções abaixo são necessárias para o funcionamento correto no iOS
        video.setAttribute('autoplay', '');
        video.setAttribute('muted', '');
        video.setAttribute('playsinline', '');
        //--

    //Verifica se o navegador pode capturar mídia
    if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: 'user'}})
        .then( function(stream) {
            //Definir o elemento víde a carregar o capturado pela webcam
            video.srcObject = stream;
            return stream;            
        })
        .catch(function(error) {
            alert("Error on open device");
        });
    }
}

function takeSnapShot(){
    //Captura elemento de vídeo
    var video = document.querySelector("#webCamera");

    //Criando um canvas que vai guardar a imagem temporariamente
    var canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    var ctx = canvas.getContext('2d');

    //Desnehando e convertendo as minensões
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    //Criando o JPG
    var dataURI = canvas.toDataURL('image/jpeg'); //O resultado é um BASE64 de uma imagem.
    document.querySelector("#base_img").value = dataURI;

    sendSnapShot(dataURI); //Gerar Imagem e Salvar Caminho no Banco
}

function sendSnapShot(base64){  
    var request = new XMLHttpRequest();
        request.open('POST', 'save_photos.php', true);
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

        request.onload = function() {
            console.log(request);
            if (request.status >= 200 && request.status < 400) {
                //Colocar o caminho da imagem no SRC
                var data = JSON.parse(request.responseText);

                //verificar se houve erro
                if(data.error){
                    alert(data.error);
                    return false;
                }

                //Mostrar informações
                document.querySelector("#imagemConvertida").setAttribute("src", data.img);
                document.querySelector("#caminhoImagem a").setAttribute("href", data.img);
                document.querySelector("#caminhoImagem a").innerHTML = data.img.split("/")[1];
            } else {
                alert( "Error on save. Status:" + request.status );
            }
        };

        request.onerror = function() {
            alert("Error on save. Back-End fail.");
        }

        request.send("base_img="+base64); // Enviar dados
}


loadCamera();

style.css

body{
    font-family: sans-serif;
    margin: 0;
}

.area{
    margin: 10px auto;
    box-shadow: 0 10px 100px #ccc;
    padding: 20px;
    box-sizing: border-box;
    max-width: 500px;
}

.area video{
    width: 100%;
    height: auto;
    background-color: whitesmoke;
}

.area textarea{
    width: 100%;
    margin-top: 10px;
    height: 80px;
    box-sizing: border-box;
}

.area button{
    -webkit-appearance: none;
    width: 100%;
    box-sizing: border-box;
    padding: 10px;
    text-align: center;
    background-color: #068c84;
    color: white;
    text-transform: uppercase;
    border: 1px solid white;
    box-shadow: 0 1px 5px #666;
}

.area button:focus{
    outline: none;
    background-color: #0989b0;
}

.area img{
    max-width: 100%;
    height: auto;
}

.area .caminho-imagem{
    padding: 5px 10px;
    border-radius: 3px;
    background-color: #068c84;
    text-align: center;
}

.area .caminho-imagem a{
    color: white;
    text-decoration: none;
}

.area .caminho-imagem a:hover{
    color: yellow;
}


Solution 1:[1]

The best way that I found was to draw the video on canvas and after this draw the rectangle.

Step one: hide tag video.

<video autoplay="true" id="webCamera" style="display: none"> </video>

Step two: insert tag canvas on my div.

<canvas id="videoCanvas"></canvas>

Step three: create on my javascript a function that draws video and rectangle on the canvas.

function drawImge(){
    var video = document.querySelector("#webCamera");
    var canvas = document.querySelector("#videoCanvas");
    var ctx = canvas.getContext('2d');

    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;


    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    var faceArea = 300;
    var pX=canvas.width/2 - faceArea/2;
    var pY=canvas.height/2 - faceArea/2;

    ctx.rect(pX,pY,faceArea,faceArea);
    ctx.lineWidth = "6";
    ctx.strokeStyle = "red";    
    ctx.stroke();


    setTimeout(drawImge , 100);
}

Step four: fire my function when playing the video.

 var video = document.querySelector("#webCamera");
 video.onplay = function() {
  setTimeout(drawImge , 300);
 };

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anderson Rossi