AckerApple / ack-angular-webcam

MIT License
37 stars 19 forks source link

Getting a list of available MediaDevices #36

Closed hoomb closed 6 years ago

hoomb commented 6 years ago

Thank you for your very helpful component.

As I would like to use it in a Mobile Responsive Application, is it possible to get a list of available Cameras on Mobile? What about changing the facingmode on the fly?

Thank you.

hoomb commented 6 years ago

I could solve the first Problem by using this Code:

` <ack-media-devices [(videoInputs)]="videoDevices"

`

But changing the facingMode on the fly does not still work.

AckerApple commented 6 years ago

iOS does not use devices to change cameras. You need to use the facingMode option. It absolutely works. Try the demo for ack-angular-webcam and under “devices” just toggle the facingMode only and do NOT change the device.

iOs, the new internet explorer of our time, doesn’t do things like other browsers. If iOS didn’t exist we wouldn’t need the facingMode option as you would just change devices and not some stupid facingMode option.

It works, it’s confusing for iOS only

AckerApple commented 6 years ago

Any update? Figure it out?

hoomb commented 6 years ago

No, it does't work. Here is my code:

media-stream.component.html

    <div class="scan-camera">
      <a class="btn-floating waves-effect waves-light change-camera-button red" (click)="changeFacingMode()" *ngIf="multipleDevicesAvailable">
        <i class="material-icons">party_mode</i>
      </a>

      <ack-webcam
        [(ref)]="webcam"
        [options]="options"
        (success)="onCamSuccess()"
        (catch)="onCamError($event)"
        [facingMode]="facingMode"
      ></ack-webcam>

      <ack-media-devices
        [(videoInputs)]="videoDevices"
      ></ack-media-devices>
    </div>

    <a class="btn-floating btn-large waves-effect waves-light camera-button" (click)="processImage()"><i class="material-icons">camera</i></a>

  </div>

media-stream.component.ts

  cameraAvailable: boolean = false;
  multipleDevicesAvailable: boolean = false;
  facingMode: string = 'enviroment';

  webcam: WebCamComponent;
  options = {
    audio: false,
    video: true,
    width: 280,
    height: 210,
    fallbackMode: 'callback',
    fallbackSrc: 'jscam_canvas_only.swf',
    fallbackQuality: 85,
    cameraType: 'back'
  };

  videoDevices: MediaDeviceInfo[];

  changeFacingMode() {
    this.facingMode = (this.facingMode === 'enviroment') ? 
      'user' : 
      'enviroment';

    this.webcam.facingMode = this.facingMode;
  }
AckerApple commented 6 years ago

Does the demo page facing mode work for you? Must be iOS 11, I believe.

Here a three screen shots of the demo page working. If the demo page doesn’t change facingModes for you, then it’s your browser

594cc4d0-cc1b-4f17-bb5f-f1610a7788c0 332deb45-e11d-41a0-8582-bff8ce0e326d 2163364f-7172-4835-8a90-8704436233a2

hoomb commented 6 years ago

The Demo works on my iPhone and switches between both cameras properly. I must check the demo code to find out why switching does not work in my case.

AckerApple commented 6 years ago

It maybe possible that, in the demo, the camera is destroyed when using the devices panel. After the devices is closed, the webcam is redrawn.

I don't think this is it but it could be possible. I'll check your code again one more time right now

AckerApple commented 6 years ago

My above assumption about destroying the camera seems irrelevant to your code as I can see you default the camera to "enviroment".

I think the truth is, you are spelling environment incorrectly as "enviroment"

AckerApple commented 6 years ago

Confirmed, you are spelling environment wrong

hoomb commented 6 years ago

nice catch, although it didn't help either. I think I must destroy the webcam and recreate it as your demo.

AckerApple commented 6 years ago

If you would, please try that and tell me if it works.

If it works I will look at hooking into the facingMode property to auto redraw the video (destroy/create) onNgChanges

hoomb commented 6 years ago

even this code doesn't work. I'm out of ideas:

  webcam: WebCamComponent;
  facingMode: string = 'environment';
  options: Options = {
    audio: false,
    video: true,
    width: 280,
    height: 210,
    cameraType: {
      deviceId: { exact: '' },
      facingMode: 'environment'
    },
    fallback: false,
    fallbackMode: 'callback',
    fallbackSrc: 'jscam_canvas_only.swf',
    fallbackQuality: 85
  };

  videoDevices: MediaDeviceInfo[];
  currentDeviceId: number;

  getNextVideoDevice(): string {
    this.currentDeviceId ++;
    if (this.currentDeviceId > this.videoDevices.length) {
      this.currentDeviceId = 0;
    }

    return this.videoDevices[this.currentDeviceId].deviceId;
  }

  changeFacingMode() {
    this.facingMode = (this.facingMode === 'environment') ? 'user' : 'environment';
    this.options.cameraType = {
      deviceId: { exact: this.getNextVideoDevice() },
      facingMode: this.facingMode
    };

    this.webcam.facingMode = this.facingMode;
    this.webcam.options = this.options;
    this.webcam.setWebcam(this.options);
    this.webcam.resize(5);
    this.webcam.refChange.subscribe(() => {
      this.webcam.facingMode = this.facingMode;
      this.webcam.options = this.options;
    });
  }
AckerApple commented 6 years ago

Here’s what I think is wrong with your code:

  1. You are changing this.webcam.facingMode. You should be changing this.facingMode . The way you have your code, it’s like you don’t fully understand how Angular bindings work. The way you have it, this.webcam.facingMode will ALWAYS be overridden by [facingMode]=“facingMode”. It’s as if my convenient [(ref)] binding is steering you in the wrong direction because you are changing ref variables that will ALWAYS be overridden by your template bindings. STOP setting anything onto this.webcam and ONLY use this.webcam to reference variables.

  2. Get rid of this.options.cameraType.facingMode

I will get you a plunker example by Tuesday. Your code is certainly bastardizing [(ref)] and I think thats your main problem.

AckerApple commented 6 years ago

After closer inspection I see you are changing both in the method changeFacingMode

I don’t see you destroying the webcam by wrapping it in an ngIf like the demo does. The demo removes the webcam when selecting devices by making an ngIf false around the webcam. After changing facing mode the webcam is brought back by making an *ngIf true that’s wrapped around the webcam.

Again, I’ll get you a working example. Bottom line, video elm has to be redrawn when changing facing modes and currently this package does not seem to be doing that, we’ll get it right

AckerApple commented 6 years ago

This package had enviroment spelled wrong as well. Fixing issues right now. This may have been pre-fork code

AckerApple commented 6 years ago

PACKAGE UPDATED!

Please acquire version 1.8.0

## [1.8.0] - 2018-02-17
- Change facingMode ondemand without requiring developer to redraw
- Breaking Change
  - This package had spelled environment incorrectly as "enviroment". Check your code for this misspelling
AckerApple commented 6 years ago

If after 1.8.0 you are still having issues, I will get you a plunker that we can debug together

hoomb commented 6 years ago

Thank you, I will made the changes as you suggested and come back to you.

AckerApple commented 6 years ago

Hopefully the only thing you’ll need to do, is just update to 1.8.0

hoomb commented 6 years ago

Really appreciate for your help. I confirm that 1.8.0 switches the camera properly. I have also thrown out the obsolete code and keep just these lines:

  facingMode: string = 'environment';
  options = {
    audio: false,
    video: true,
    width: 280,
    height: 210
  };

  changeFacingMode() {
    this.facingMode = (this.facingMode === 'environment') ? 'user' : 'environment';
  }
AckerApple commented 6 years ago

Awesomeness. Thank you for helping make this package better.

Please star, follow and perform any other social actions that will naturally boost the popularity of this package