ImageCapture.takePhoto 抛出 DOMException:平台错误

问题描述 投票:0回答:2

我尝试使用图像捕获的 takePhoto 方法,使用以下代码。

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);
            });
    },

应用程序运行正常,使用以下行

this.imageCapture.takePhoto()

,但今天突然停止工作并抛出一般错误DOMException:平台错误。 我做了一些研究,意识到他们一年前做了改变,将其用作

拍照(照片设置)

正如 mdn web docs 中的文档所说,由于 photoSettings 是可选的,我尝试使用

this.imageCapture.takePhoto(null)

它工作了一段时间,直到今天晚些时候,它又开始抛出同样的错误。 有谁知道原因,ImageCapture 生产不稳定吗?如果不是,是否有替代方案或解决方法?

我在 chrome 下运行应用程序并使用 vue 作为框架。

javascript webapi image-capture
2个回答
2
投票

编辑 2023 年 1 月 31 日: Chrome 目前正在积极致力于解决此问题: https://bugs.chromium.org/p/chromium/issues/detail?id=1287227

更新 Chrome 似乎并不能解决问题,因为 Chrome 正在进行功能标记测试

MediaFoundationD3D11VideoCapture
。当
MediaFoundationD3D11VideoCapture
禁用时,不会出现此问题。

原始答案2023年1月12日

我的客户于 2023 年 1 月 12 日开始收到此错误。我认为 Chrome 发布的版本在网络摄像头 API 中存在错误。

我让他们更新了 Chrome 版本,它立即又开始工作了。修复它的版本是 v109.0.5414.75

更新 chrome:

对我有用的版本:


0
投票

您可以使用await imageCapture.grabFrame(),它将返回一个解析为ImageBitMap对象的Promise,然后将其传递给await createImageBitmap(ImageBitMap_object)并将图像Bitmap转换为Canvas,然后将其绘制到它并使用canvas.toBlob保存图片! Have created a separate function to download the image which is given in second ss

© www.soinside.com 2019 - 2024. All rights reserved.