具有UserMedia的Canvas视频无法在手机上使用

时间:2019-04-29 09:47:06

标签: angular typescript ionic-framework

我正在尝试构建一个Ionic应用程序,该应用程序使用“ getUserMedia”获取手机的后置摄像头并将此视频绘制到画布中。然后,应该在画布中使用名为jsQR的库识别QR码。

我尝试了多种创建画布的方法,以此类推,突然间我意识到,在chrome浏览器中,使用“离子服务”将应用程序完美部署就可以了。

我的问题是,如果我运行“ ionic cordova run android”,它将无法按需绘制到画布中。 可视化: https://imgur.com/a/A6zVneK

在chrome中的外观: https://imgur.com/a/cSLtAdJ

我的HTML:

<ion-header>
  <meta charset="utf-8">
  <title>jsQR Demo</title>
  <link href="https://fonts.googleapis.com/css?family=Ropa+Sans" rel="stylesheet">
</ion-header>

<ion-content>
  <h1 style="text-align: center">Jack's QR with User Media Test</h1>

  <div #videoContainer></div>
  <div #canvasContainer>
  </div>

</ion-content>

我的TYPESCRIPT:

import {AfterViewInit, Component, ViewChild} from '@angular/core';
import jsQR from 'jsqr';
import { Platform } from '@ionic/angular';
import { AndroidPermissions } from '@ionic-native/android-permissions/ngx';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements AfterViewInit {
  @ViewChild('videoContainer') videoContainer;
  public video: HTMLVideoElement;
  @ViewChild('canvasContainer') canvasContainer;

  public canvas: HTMLCanvasElement;
  public canvasContext: CanvasRenderingContext2D;

  constructor(private platform: Platform, private androidPermissions: AndroidPermissions) {
    this.video = document.createElement('video');
    this.video.width = 640;
    this.video.height = 480;
    this.video.setAttribute('autoplay', '');
    this.video.setAttribute('playsinline', '');
    this.video.setAttribute('facingMode', 'environment');
    this.video.setAttribute('hidden', '');

    this.canvas = document.createElement('canvas');
    this.canvas.width = 640;
    this.canvas.height = 480;
    this.canvasContext = this.canvas.getContext('2d');


    if (this.platform.is('cordova')) {
      this.platform.ready().then(() => {
        this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(
            result => console.log('Has permission?', result.hasPermission),
            err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA)
        );

        this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.CAMERA]).then(() => {});
      });
    }
  }

  ngAfterViewInit() {
    this.videoContainer.nativeElement.appendChild(this.video);
    this.canvasContainer.nativeElement.appendChild(this.canvas);

    this.initWebRTC();
  }

  initWebRTC() {
    const constraints = {
      video: true,
      audio: false,
      facingMode: 'environment'
    };

    const handleSuccess = (stream: MediaStream) => {
      this.video.srcObject = stream;
      this.video.setAttribute('playsinline', '');
      this.video.play();

      requestAnimationFrame(() => {
        this.draw();
      });
    };

    navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess);
  }

  drawLine(begin, end) {
    this.canvasContext.beginPath();
    this.canvasContext.moveTo(begin.x, begin.y);
    this.canvasContext.lineTo(end.x, end.y);
    this.canvasContext.lineWidth = 4;
    this.canvasContext.strokeStyle = '#4139ff';
    this.canvasContext.stroke();
  }

  draw() {
    this.canvas.height = this.video.height;
    this.canvas.width = this.video.width;

    this.canvasContext.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
    const imageData = this.canvasContext.getImageData(0, 0, this.canvas.width, this.canvas.height);
    const code = jsQR(imageData.data, imageData.width, imageData.height, { inversionAttempts: 'dontInvert' });
    if (code) {
      console.log('I found a QR!');
      this.drawLine(code.location.topLeftCorner, code.location.topRightCorner);
      this.drawLine(code.location.topRightCorner, code.location.bottomRightCorner);
      this.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner);
      this.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner);
      }
    requestAnimationFrame(() => {
      this.draw();
    });
  }
}

我的问题还在于:在手机上运行的Ionic应用程序与在计算机上运行的“浏览器”不同,例如铬?

0 个答案:

没有答案