3

我在台式电脑上收到 MediaStreamError { name: "AbortError", message: "Starting video failed", constraint: "", stack: "" },但在我的笔记本电脑上没有。注意:两台 PC 都运行 Windows 10 并使用相同的代码库。

该应用程序在我使用 Firefox(带有 USB 2.0 HD UVC 网络摄像头)的笔记本上运行良好,但在我的台式电脑上,无论是使用 Firefox、Edge 还是 Chrome,我仍然会收到错误消息。我的台式电脑摄像头是罗技(罗技 HD WebCam C270),我在另一篇帖子中看到同样的错误Firefox 54(ubuntu 14.04):Twilio video failed getUserMedia其他人(@Roger Walsh)也有同样的错误使用罗技相机。

这是代码:前端(角度视图)

<div class="camera">
  <video #videoRef id="video" [(ngModel)]="video" (canplay)="setVideo()" name="video" ngDefaultControl>Video stream not available.</video>
  <button #startbuttonRef id="startbutton" [(ngModel)]="startbutton" (click)="takePicture()" name="startbutton" ngDefaultControl>Take photo</button>
</div>

<canvas #canvasRef id="canvas" [(ngModel)]="canvas" name="canvas" ngDefaultControl style="display:none"></canvas>
<div class="output">
  <img #photoRef id="photo" [(ngModel)]="photo" name="photo" ngDefaultControl alt="The screen capture will appear in this box.">
</div>

前端(角度组件)

import { Component, Input, OnInit, forwardRef, ViewChild, ElementRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-capture-image',
  templateUrl: './capture-image.component.html',
  styleUrls: ['./capture-image.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CaptureImageComponent),
      multi: true
    }
  ]
})
export class CaptureImageComponent implements OnInit {
  @ViewChild('videoRef') videoRef: ElementRef;
  @ViewChild('canvasRef') canvasRef: ElementRef;
  @ViewChild('photoRef') photoRef: ElementRef;
  @ViewChild('startbuttonRef') startbuttonRef: ElementRef;
  streaming = false;
  width = 320;
  height = 0;

  constructor(private http: HttpClient) { }

  ngOnInit() {
    navigator.mediaDevices.getUserMedia({video: true, audio: false})
      .then((stream) => {
        this.videoRef.nativeElement.srcObject = stream;
        this.videoRef.nativeElement.play();
      })
      .catch(function(err) {
        console.log(err);
      });
      this.clearPhoto();
  }


  setVideo() {
    if (!this.streaming) {
      this.height = this.videoRef.nativeElement.videoHeight/ (this.videoRef.nativeElement.videoWidth/this.width);
      this.videoRef.nativeElement.width = this.width;
      this.videoRef.nativeElement.height = this.height;
      this.canvasRef.nativeElement.width = this.width;
      this.canvasRef.nativeElement.height = this.height;
      this.streaming = true; 
    }
  }

  clearPhoto() {
    let context = this.canvasRef.nativeElement.getContext('2d');
    context.fillStyle = "#AAA";
    context.fillRect(0,0,this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);

    var data = this.canvasRef.nativeElement.toDataURL('image/png');
    this.photoRef.nativeElement.src = data;
  }

  takePicture() {
    let context: CanvasRenderingContext2D  = this.canvasRef.nativeElement.getContext('2d');

    if (this.width && this.height) {
      this.canvasRef.nativeElement.width = this.width;
      this.canvasRef.nativeElement.height = this.height;
      context.drawImage(this.videoRef.nativeElement, 0, 0, this.width, this.height);

      let fd = new FormData();

      this.canvasRef.nativeElement.toBlob((blob) => {
        let url = URL.createObjectURL(blob);
        this.photoRef.nativeElement.onload = function() {
          URL.revokeObjectURL(url);
        };
        this.photoRef.nativeElement.src = url;

        fd.append('image', blob, "myPicture");
        fd.append('timeStamp', Date.now().toString());
        console.log("Uploading: " + JSON.stringify(fd));
        try {
            this.http.post("http://localhost:3000/selection/test-photo",fd)
            .subscribe(
              (res) => {
                console.log("Successful result: " + JSON.stringify(res))},
              (err) => {
                console.log("Subscribe error: " + JSON.stringify(err))} 
          );
        }
        catch(e) {
          console.log("Caught error: " + e);
        }

      }, 'image/png')

    } else {
      this.clearPhoto();
    }
  }

}

后端(快递)

exports.selection_test_photo = [
    (req,res,next) => {
        const photo = new Photo();
        console.log("Entering Post: " + util.inspect(req.file) + "; " + req.body.timeStamp);        
        photo.photo.data = fs.readFileSync(req.file.path);
        photo.photo.contentType = 'image/png';
        photo.timeStamp = {"value": req.body.timeStamp};
        console.log("About to save . . . ");
        photo.save(function(err){
            if (err) {return next(err)};
            res.json({"foo": "bar"});
        });        
    },

];

有没有其他人有这个问题?有任何想法吗?谢!

4

3 回答 3

4

https://bugzilla.mozilla.org/show_bug.cgi?id=1588939 说:

“显然 getUserMedia({video:true}) 的两个实例不能同时存在。”

于 2019-12-08T13:41:27.280 回答
1

我遇到了同样的问题,结果与 FF 无法正常工作有关。我意识到我的解决方案可能无法解决 OP 的代码,但这篇文章在搜索结果中显示得相当高,所以我想我会帮助其他可能最终出现在这里的人(就像我一样)。

我正在使用 MacBook Pro、CalDigit 扩展坞、带额外 USB 端口的戴尔超宽显示器和罗技 1080p 摄像头(确切的硬件并不重要,因为我认识的其他人有不同的硬件/设置但同样的问题)。我以两种不同的方式重现了我的问题。它是零星的(意味着一个配置可能有一天会起作用,但不会在下一天起作用)并且只发生在 Firefox 中

  1. 罗技通过 USB 插入戴尔 -> 戴尔通过 USB 插入扩展坞 -> 扩展坞通过迅雷插入 macbook
  2. 罗技通过 USB 插入扩展坞 -> 扩展坞通过迅雷插入 macbook

原来这与getUserMedia(). 例如:

await window.navigator.mediaDevices.getUserMedia({
  audio: {},
  video: {​​​
    deviceId: { exact: 'id of logitech camera' },
    frameRate: { ideal: 30 }, ​​​
    height: { ideal: 2160 },​​​
    width: { ideal: 4096 }
  }
});

那会抛出一个MediaStreamErrorwith AbortError: Starting video failed

错误信息

当我这样调用它时,它会成功:

await window.navigator.mediaDevices.getUserMedia({
  audio: {},
  video: {​​​
    deviceId: { exact: 'id of logitech camera' },
    frameRate: { ideal: 30 }, ​​​
    height: { ideal: 720 },​​​ // drop down to 720p
    width: { ideal: 1280 } // drop down to 1280p
  }
});

看来 Firefox 没有遵守该ideal约束。此外,相机和机器之间一定会出现问题,因为我尝试过1080p(我的相机支持)但它仍然失败。我不得不把它降到这么低。另一个注意事项(证明它与 FF 没有正确处理外部硬件有关),如果我调用它,它每次都可以工作。

await window.navigator.mediaDevices.getUserMedia({
  audio: {},
  video: {​​​
    deviceId: { exact: 'ID OF MAC BOOK BUILTIN CAMERA' },
    frameRate: { ideal: 30 }, ​​​
    height: { ideal: 2160 },​​​
    width: { ideal: 4096 }
  }
});
于 2020-11-09T20:24:30.550 回答
1

This might be the browser specific issue. please check your web-cam in the browser using some web cam test sites. Following are some example sites which you can use to test:

  1. https://www.onlinemictest.com/webcam-test/
  2. https://webcamtests.com/
  3. https://www.vidyard.com/cam-test/

If it is working, then try adding the following code to the onload event of your page:

navigator.mediaDevices.getUserMedia = navigator.mediaDevices.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;

It should provide cross browser support as well.

于 2019-09-16T08:24:03.593 回答