问题
I'm getting MediaStreamError { name: "AbortError", message: "Starting video failed", constraint: "", stack: "" } on my desktop PC, but not on my notebook PC. Note: both PCs run Windows 10 and use identical code base.
The app works great on my notebook using Firefox (with USB 2.0 HD UVC Webcam), but on my desktop PC, whether using Firefox, Edge, or Chrome, I still get the error. My desktop PC camera is Logitech (Logitech HD WebCam C270), and I saw on another post for the same error Firefox 54 (ubuntu 14.04): Twilio video failed getUserMedia that someone else (@Roger Walsh) also had the same error using a Logitech camera.
Here is the code: Front-end (Angular View)
<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>
Front-end (Angular Component)
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();
}
}
}
Back-end (Express)
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"});
});
},
];
Has anyone else had this problem? Any ideas? Tks!
回答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:
- https://www.onlinemictest.com/webcam-test/
- https://webcamtests.com/
- 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.
回答2:
https://bugzilla.mozilla.org/show_bug.cgi?id=1588939 Says:
"Evidently two instances of getUserMedia({video:true}) cannot exist at the same time."
来源:https://stackoverflow.com/questions/56640137/getting-mediastreamerror-name-aborterror-message-starting-video-failed