Tengo un video que transmite partes de un video a un MediaSource y lo reproduce. Tengo un lienzo en el que quiero dibujar el video y luego superponer algunos efectos. Sin embargo, en mi controlador, la llamada a drawImage , mientras funciona, solo parece copiar un solo píxel. El video en sí se reproduce bien.
Tengo una captura de pantalla de mi aplicación, que tiene el video de origen junto al elemento del lienzo de destino: 
Como puede ver, el color sólido del lienzo es el color del primer píxel del video de origen.
El código real en cuestión se parece a esto:
startWatch() { this.timer = setInterval(this.copyFrame.bind(this), 1000 / this.fps) } copyFrame() { const { width, height } = this.video.getBoundingClientRect() // I've tried the 3, 5, and 9 argument versions of this function // width is 300 and height is 168.75. this.ctx.drawImage(this.video, 0, 0, width, height, 0, 0, width, height) } (donde this.video es un elemento de video )
Este código "funciona" en el sentido de que el color del lienzo se actualiza con el tiempo a medida que se reproduce el video. Pero siempre es solo el píxel inicial. Entonces, el ciclo de tiempo funciona, pero la llamada a drawImage no está haciendo lo que esperaba.
(1) Usar const { width, height } puede no ser correcto. Verifique los valores que le dan.
¿Qué sucede si console.log . registra los valores de ancho o alto , son números correctos/esperados?
(2) "... Pero la llamada a drawImage no está haciendo lo que esperaba".
ctx.drawImage( someElement, 0, 0, A1, A2, 0, 0, B1, B2 );Considere el código anterior,
El primer ancho/alto (A1/A2) es para cuánto de la entrada dibujar (debe coincidir con el tamaño del propio ancho/alto de la entrada, de lo contrario se producirán recortes o márgenes). Por ejemplo: A1 == 720 si el video de entrada tiene 720 píxeles de ancho.
El segundo ancho/alto (B1/B2) es para cuánto cambiar el tamaño de la salida para dibujar. Por lo general, desea llenar el área completa del lienzo, así que use las dimensiones del lienzo (la relación de aspecto se deja al codificador para implementarla como prefiera).
En su código mostrado, su const { width, height } es
Soluciones posibles:
Intente (si debe usar un rectángulo delimitador):
function copyFrame() { //# width is 300 and height is 168.75. //const { width, height } = this.video.getBoundingClientRect() let myRect = this.video.getBoundingClientRect(); this.ctx.drawImage( this.video, 0, 0, this.video.videoWidth, this.video.videoHeight, 0, 0, myRect.width, myRect.height); }Alternativamente, podría simplemente dibujar la imagen en tamaño de lienzo:
function copyFrame() { //# assuming your Canvas is called "this.cnvs" this.ctx.drawImage( this.video, 0, 0, this.video.videoWidth, this.video.videoHeight, 0, 0, this.cnvs.width, this.cnvs.height); } Para la relación de aspecto, puede usar la fórmula a continuación (cambie todas las referencias de ancho y alto por un nuevo drawn_width )
myRatio = ( vid_height / vid_width ); drawn_height = ( myCanvas_width * myRatio );