QR scanning app via UserMedia with jsQR

Hi folks,

I’m trying to get the rear camera of the phone with usermedia and display the live video in a canvas. this works if I start the project with ionic serve on the pc and also on the mobile phones google chrome within an Ionic app obviously. But if I run a “ionic cordova run android” I can’t see the video. How is that possible? shouln’t the app and the browser be the same?
In the app on the phone I just see a default HTML video tag with no video rendering…

My end goal: is to be able to have an app which can display the camera output in a canvas and then use the library: https://github.com/cozmo/jsQR to scan a QR code and get the coordinates of the endpoints of the QR code to be able to draw a live line on the qr code…

My HTML code:

<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>

My TS File:

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;
  @ViewChild('canvasContainer') canvasContainer;
  @ViewChild('canvasInHTML') canvasInHTML;

  public canvas;
  public canvasContext;

  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.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();

      // this.canvasContext.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
      this.draw();

      // requestAnimationFrame(this.tick);
    };

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

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

  draw() {
    // if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
    this.canvas.height = this.video.videoHeight;
    this.canvas.width = this.video.videoWidth;
    console.log('I found a QR!');

    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) {
      this.drawLine(code.location.topLeftCorner, code.location.topRightCorner, '#FF3B58');
      this.drawLine(code.location.topRightCorner, code.location.bottomRightCorner, '#FF3B58');
      this.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, '#FF3B58');
      this.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, '#FF3B58');
      }
    // }
    // requestAnimationFrame(this.tick);
  }
}

My component file:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { HomePage } from './home.page';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild([
      {
        path: '',
        component: HomePage
      }
    ])
  ],
  declarations: [HomePage]
})
export class HomePageModule {}

My end goal is to have an app in ionic that does the same like this demo of the jsQR library:
https://cozmo.github.io/jsQR/