Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

135
Vistas
¿Es normal que una secuencia capturada de HTMLCanvasElement se retrase en Chrome cuando el lienzo está oculto y su OffscreenCanvas lo dibuja en un trabajador web?

Ok, entonces la pregunta es un poco exagerada, pero en realidad menciona cada parte del "error" que estoy experimentando. No estoy seguro si es realmente un error o si hay algo que no entiendo todavía. Creé una demostración en codepen para reproducir el comportamiento extraño.

https://codepen.io/rroyerrivard/pen/jOwBLbB

Como escribí en el codepen, parece haber un error en Chrome por el cual la secuencia de un HTMLCanvasElement no se actualiza en cada dibujo de imagen cuando está oculto. Pero para que eso suceda, es necesario que existan estas 4 condiciones a la vez.

  • Debemos alimentar un HTMLVideoElement con un MediaStream obtenido de una llamada a HTMLCanvasElement.captureStream() (en lugar de mostrar directamente el HTMLCanvasElement ).
  • El HTMLCanvasElement del que obtenemos el MediaStream debe estar oculto (ya sea no en el DOM o tenerlo oculto con css).
  • Debemos dibujar en HTMLCanvasElement desde un OffscreenCanvas que obtenemos de una llamada a HTMLCanvasElement.transferControlToOffscreen() .
  • El sorteo en OffscreenCanvas debe realizarse en un trabajador web al que se transfirió OffscreenCanvas .

Tuve la mala suerte de cumplir con todas estas condiciones a la vez en una aplicación web en el trabajo. Puedo evitar el error al no usar la llamada transferControlToOffscreen() y dibujar un ImageBitmap en el hilo principal después de recibirlo del trabajador web, pero eso reduce el FPS en aproximadamente un 18%.

¿Es esto un error conocido? ¿Hay alguna manera de forzar que MediaStream se actualice en cada sorteo de OffscreenCanvas ?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Supongo que es el comportamiento esperado, sí.

Lo que pasa aquí es que hizo que su subproceso de trabajo esperara usando setTimeout y MessageEvents del subproceso principal.
OffscreenCanvas confirmará su mapa de bits en el lienzo de marcador de posición en el marco de representación del trabajador. Pero, de forma predeterminada, Worker no ingresará a este marco de representación. Debe solicitarlo mediante requestAnimationFrame .
Tener el marcador de posición visible en la página hará internamente la solicitud de que OffscreenCanvas confirme su mapa de bits cuando el lienzo del marcador de posición se represente (es decir, en el marco de representación del hilo principal), es por eso que funciona cuando el lienzo del marcador de posición es visible.

Tenga en cuenta que solíamos tener un método OffscreenCanvas.commit() pero quedó obsoleto cuando requestAnimationFrame apareció en WorkerContexts.

Por lo tanto, use requestAnimationFrame en su Worker para forzar la confirmación del mapa de bits en el lienzo del marcador de posición.

 const video = document.querySelector("video"); const select = document.querySelector("select"); const canvas = document.createElement("canvas"); const offscreen = canvas.transferControlToOffscreen(); const worker = new Worker(getWorkerURL()); worker.postMessage({ offscreen }, [offscreen]); select.oninput = e => worker.postMessage({ method: select.value }); worker.onmessage = (evt) => { video.srcObject = canvas.captureStream(); }; function getWorkerURL() { return URL.createObjectURL( new Blob([ document.querySelector("[type='text/worker']").textContent ], { type: "text/javascript" }) ); }
 canvas { border: 1px solid }
 <video controls autoplay></video> <label>waiting method:<select><option>rAF</option><option>setTimeout</option></select></label> <script type="text/worker"> let ctx; let waiting_method = "rAF"; onmessage = ({ data: { offscreen, method } }) => { if (offscreen) { ctx = offscreen.getContext("2d"); draw(); postMessage("ready"); } else if (method) { waiting_method = method; } }; function draw() { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillText(new Date().getTime(), 30, 30); if (waiting_method === "rAF") { requestAnimationFrame(draw); } else { setTimeout(draw, 1000/30); } } </script>


Ahora, supongo que también podríamos esperar que la llamada a captureStream() active la misma solicitud interna de compromiso que activa el lienzo de marcador de posición visible, por lo que es posible que desee presentar un problema en https://crbug.com independientemente.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda