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!