Работа с видео и элементом canvas в Angular

#angular #html5-canvas #html5-video

#angular #html5-canvas #html5-видео

Вопрос:

Я пытаюсь получить поток и отобразить его с помощью drawImage, как предлагается в некоторых руководствах Google для разработчиков. Я продолжаю получать ошибку:

Ошибка типа: не удалось выполнить ‘drawImage’ в ‘CanvasRenderingContext2D’: предоставленное значение не относится к типу ‘(CSSImageValue или HTMLImageElement, или SVGImageElement, или HTMLVideoElement, или HTMLCanvasElement, или ImageBitmap, или OffscreenCanvas)’

По прошествии нескольких часов я все еще не могу понять, почему, поэтому я подумал, что обращусь за помощью. Мой код прилагается…

 import {
  Component,
  OnInit,
  ViewChild,
  ElementRef
} from '@angular/core';


@Component({
  selector: 'app-scanner',
  templateUrl: './scanner.component.html',
  styleUrls: ['./scanner.component.css']
})
export class ScannerComponent implements OnInit {
  constructor() {}

  @ViewChild('mycanvas') mycanvas: ElementRef;
  @ViewChild('myvideo') myvideo: ElementRef;
  ctx;

  ngOnInit() {
    this.drawOnCanvas();
  }

  drawOnCanvas() {
    this.ctx = this.mycanvas.nativeElement.getContext('2d');

    navigator.mediaDevices
      .getUserMedia({
        audio: false,
        video: true
      })
      .then(stream => {
        this.myvideo.nativeElement.srcObject = stream;
        this.drawCanvas();
        //this.myvideo.nativeElement.play();
      });
  }

  drawCanvas() {
    this.mycanvas.nativeElement.width = this.myvideo.nativeElement.clientWidth;
    this.mycanvas.nativeElement.height = this.myvideo.nativeElement.clientHeight;
    this.ctx.drawImage(
      this.myvideo.nativeElement.srcObject,
      0,
      0,
      this.mycanvas.nativeElement.width,
      this.mycanvas.nativeElement.height
    );
  }
}  
 <div>
  <canvas #mycanvas id="mycanvasid"></canvas>
  <video #myvideo></video>
</div>  

Комментарии:

1. Вместо того, чтобы запускать это drawOnCanvas в ngOnInit , попробуйте это в ngAfterViewInit . Вид и элементы не будут готовы при ngOnInit запуске.

2. Да, извините, я только что обновил код (там была старая копия, прежде чем я ее вставил) Я действительно пробовал использовать ngAfterViewInit и все еще получал (и получаю) ту же ошибку.

Ответ №1:

похоже, вы не запускаете свой поток…

Поскольку я его использую

HTML

   <div id="inner_video" >
      <video #video id="video" autoplay></video>
  </div>

  <canvas #canvas id="canvas" width="1024" height="768">canvas</canvas>      
  

ts

  @ViewChild("video")
  public video: ElementRef;

  @ViewChild("canvas")
  public canvas: ElementRef;

  ngOnInit() {
    if (navigator.mediaDevices amp;amp; navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
          this.video.nativeElement.srcObject = stream;
          this.video.nativeElement.play();
      });
    }
  } 
  

захват кода

  capture(event) {
    event.preventDefault();
    var context = this.canvas.nativeElement.getContext("2d").drawImage(this.video.nativeElement, 0, 0, 1024, 768);
    var picture: any = this.canvas.nativeElement.toDataURL("image/png");
    ...
  }
  

Комментарии:

1. Спасибо за ваш отзыв. Я запускал поток ранее, но закомментировал его. Я просто вставил его обратно (фактически переработал код, чтобы он был точно таким, как у вас выше), но я получаю следующую ошибку при попытке запустить метод drawCanvas… Не удалось выполнить ‘drawImage’ в ‘CanvasRenderingContext2D’: предоставленное значение не соответствует типу… Я попытался перевести вызов этого метода в «button», просто чтобы посмотреть, не было ли проблемы с тем, что некоторые элементы не успели загрузиться, но я все еще получаю ту же ошибку.

2. не должна ли команда drawCanvas выполняться после выполнения инструкции play? Также это, getContext должен быть таким же, после (в любом случае, я предполагаю, что вы сделали это, как вы сказали «рефакторинг»)

3. Когда я отвечал, я видел только небольшую часть вашего ответа (я думаю, что я, возможно, ответил, пока вы все еще редактировали фрагмент кода! Сейчас я играю с вашим полным ответом на код, большое спасибо, что нашли время ответить. Скоро вернусь с результатами.

4. Также обратите внимание, что это должно быть this.myvideo.nativeElement , а не this.myvideo.nativeElement.srcObject