Search code examples
javascriptwebapiimage-capture

ImageCapture.takePhoto throws DOMException: platform error


Im trying to use the takePhoto method of image capture, using the following code.

addPicture: function (typeEvidence) {
    if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
        this.typeEvidence = typeEvidence;
        var _self = this;
        this.initializeCamera();
        navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } })
            .then(mediaStream => {
                _self.video.srcObject = mediaStream;
                _self.video.onloadedmetadata = () => {
                    _self.video.play();
                };
                _self.track = mediaStream.getVideoTracks()[0];
                _self.imageCapture = new ImageCapture(_self.track);
            })
            .catch((err) => {
                $.MenssagesGrowl.Show(3, 'Error: ' + err.name + ' - ' + err.message);
            });
        $("#modalAddPicture").modal("show");
    }
    else {
        $.MenssagesGrowl.Show(3, 'The browser does not support media devices');
    }
},    
initializeCamera: function () {
        var _self = this;
        this.dataURL = '';
        this.disableTakePicture = true;
        this.blob = null;
        this.streaming = false;
        this.imageCapture= null;
        this.video = document.querySelector('video');
        this.canvas = document.getElementById('cameraCanvas');
        this.video.addEventListener('canplay', (ev) => {
            if (!_self.streaming) {
    
                _self.picWidth = _self.video.videoWidth;
                _self.picHeight = _self.video.videoHeight;
                //_self.picWidth = _self.video.videoWidth / (_self.video.videoHeight / _self.picHeight);
    
                // Firefox currently has a bug where the height can't be read from
                // the video, so we will make assumptions if this happens.
    
                if (isNaN(_self.picWidth)) {
                    _self.picWidth = _self.picHeight / (4 / 3);
                }
    
                _self.video.setAttribute('width', _self.picWidth);
                _self.video.setAttribute('height', _self.picHeight);
                _self.canvas.setAttribute('width', _self.picWidth);
                _self.canvas.setAttribute('height', _self.picHeight);
    
                _self.streaming = true;
                _self.disableTakePicture = false;
            }
        }, false);
        this.clearPhoto();
    },
    takePicture: function () {
        var _self = this;
        this.imageCapture.takePhoto(null)
            .then((blob) => {
                return Promise.all([createImageBitmap(blob),blob]);
            })
            .then((result) => {
                //result[0] bitmap
                //result[1] blob
                //guardar foto
                var _sequence = _self.getConsecutiveForFileName();
                var _filename = _self.PrevioHeader.ControlNum + "_" + _self.PreviousConsignment.ConsignmentNum + "_" + _sequence + ".png";
                var _file = new File([result[1]], _filename, {
                    type: 'image/png'
                });
                var _formData = new FormData();
                _formData.append("image", _file);
                _formData.append("id", _self.PreviousConsignment.Guid);
                axios({
                    method: 'post',
                    url: this.url,
                    data: _formData,
                    headers: { "Content-Type": "multipart/form-data" }
                }
                ).then((response) => {
                    if (response.data.result == true) {
                        $.MenssagesGrowl.Show(response.data.typeMessage, response.data.message);
                        var _context = _self.canvas.getContext('2d');
                        if (_self.picWidth && _self.picHeight) {
                            _self.canvas.width = _self.picWidth;
                            _self.canvas.height = _self.picHeight;
                            _context.drawImage(result[0], 0, 0, _self.picWidth, _self.picHeight);
                            var _dataURL = _self.canvas.toDataURL('image/png');
                            _self.PreviousConsignment.Images.push({
                                dataURL: _dataURL,
                                fileName: _filename,
                                id: response.data.id,
                                sequence: _sequence,
                                typeEvidence: _self.typeEvidence,
                                temporal: 1
                            });
                        }
                        else
                            _self.clearPhoto();
                    }
                });
            })
            .catch((error) => {
                console.log(error);
            });
    },

The application was working ok with the following line

this.imageCapture.takePhoto()

, but suddenly stopped working today throwing a generic error DOMException: platform error. I did a little bit of research and realized they had made a change a year ago to use it as

takePhoto(photoSettings)

as the documentation in mdn web docs says, since photoSettings is optional i tried to use

this.imageCapture.takePhoto(null)

and it worked for a while until later this day, when it started throwing again the same error. Does anyone knows the reason, is the ImageCapture not stable for production and if it is not is there an alternative or workaround?

Im running the app under chrome and using vue as framework.


Solution

  • Edit 1/31/2023: Chrome is now actively working on fixing this issue: https://bugs.chromium.org/p/chromium/issues/detail?id=1287227

    It appears updating Chrome doesn't fix the issue, because Chrome is feature flag testing MediaFoundationD3D11VideoCapture. When MediaFoundationD3D11VideoCapture is disabled, the issue doesn't occur.

    Original Answer 1/12/2023

    My customers started getting this error on 1/12/2023. I think Chrome released a version with a bug in the webcam APIs.

    I had them update their version of chrome and it immediately started working again. The version that fixed it was v109.0.5414.75

    To update chrome:

    Update Chrome

    Version that worked for me:

    Version that worked