Actualmente estoy desarrollando una API que toma una pista de video como entrada y devuelve una pista de video procesada. Me las arreglé para dibujar el video procesado en un lienzo y espero usar canvas.captureStream() para capturar el videoStream de él.
Resulta que puedo capturar una secuencia que no esté en blanco solo si cargo el lienzo en el DOM document.body.appendChild(myTempCanvas) y lo mantengo visualizado, la secuencia se vuelve en blanco si escondo el lienzo myTempCanvas.style.display="none"
Entonces, ¿hay alguna forma de capturar la transmisión y mantener el lienzo oculto también?
Ejemplo: Si quita el comentario de la línea canvas.style.display = "none"; , entonces output_video también se queda en blanco.
<!DOCTYPE html> <html lang="en"> <head> <title>Demo</title> </head> <body> <div class="container"> <video autoplay class="input_video" ></video> <canvas class="output_canvas"></canvas> <video autoplay class="output_video" ></video> </div> <script> const video = document.getElementsByClassName("input_video")[0]; const canvas = document.getElementsByClassName("output_canvas")[0]; const output_video = document.getElementsByClassName("output_video")[0]; let imageCapture = null; let tmpStream = null; navigator.mediaDevices.getUserMedia({ video: true }) .then((stream) => { imageCapture = new ImageCapture(stream.getVideoTracks()[0]); window.requestAnimationFrame(frameloop); tmpStream = canvas.captureStream(20); // canvas.style.display = "none"; output_video.srcObject = tmpStream; }) function frameloop() { imageCapture.grabFrame() .then(imageBitmap => { drawCanvas(canvas, imageBitmap); window.requestAnimationFrame(frameloop); }) } /* Utils */ function drawCanvas(canvas, img) { canvas.width = getComputedStyle(canvas).width.split('px')[0]; canvas.height = getComputedStyle(canvas).height.split('px')[0]; let ratio = Math.min(canvas.width / img.width, canvas.height / img.height); let x = (canvas.width - img.width * ratio) / 2; let y = (canvas.height - img.height * ratio) / 2; canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height, x, y, img.width * ratio, img.height * ratio); } </script> </body> </html> </script> </body> </html>En su función drawCanvas , está configurando el ancho y la altura del lienzo en su ancho y alto CSS calculados.
Cuando oculta el lienzo a través display:none , o cuando no se adjunta en el documento, estos valores serán "0px" , porque el lienzo no está en el CSSOM.
Un lienzo con ancho o alto cero no puede producir ningún resultado.
Establecer el ancho o la altura del lienzo es una operación muy lenta, en Chrome, esto asignará un mapa de bits de imagen completamente nuevo cada vez que lo haga, además del restablecimiento de todos los valores predeterminados del contexto del lienzo.
Por lo tanto, nunca configure el ancho o la altura del lienzo en todos los marcos, solo cuando realmente cambió, y no lo configure en el tamaño calculado de su elemento <canvas> , configúrelo en el tamaño de su imagen de entrada y luego configure el tamaño de CSS en consecuencia.