检查网站是否已经使用https, http协议下无法使用(当然还是可以解决的)。
<el-dialog
title="拍照上传"
:visible.sync="visible"
@close="onCancel"
:close-on-click-modal="false"
width="1065px">
<div class="box">
<video id="videoCamera" class="canvas" :width="500" :height="400" autoPlay></video>
<canvas id="canvasCamera" class="canvas" :width="500" :height="400"></canvas>
</div>
<div slot="footer">
<el-button @click="getCompetence" icon="el-icon-camera" v-if="!isPhoto" type="primary" size="small">调用摄像头</el-button>
<el-button @click="drawImage" icon="el-icon-camera" v-if="isPhoto" type="primary" size="small">拍照</el-button>
<el-button @click="onUpload" v-if="imgSrc.length > 3" :loading="loading" type="primary" icon="el-icon-upload2" size="small">上传</el-button>
</div>
</el-dialog>
//绘制图片
drawImage() {
this.imgSrc = ''
// 点击,canvas画图 高400 宽500 根据个人情况设定
this.thisContext.drawImage(this.thisVideo, 0, 0, 500, 400);
// 获取图片base64链接
this.imgSrc = this.thisCancas.toDataURL('image/png');
},
onUpload(){
if (this.imgSrc) {
const file = this.imgSrc; // 把整个base64给file
const time = (new Date()).valueOf();//生成时间戳
const name = time + ".png"; // 定义文件名字(例如:abc.png , cover.png)
const conversions = this.dataURLtoFile(file, name); // 调用base64转图片方法
const data = new FormData();
data.append('file', conversions);
const options = {
method: "POST", //请求方法
body: data, //请求体
headers: {
'Accept': 'application/json'
},
};
this.loading = true;
fetch(process.env.BASE_API + 'upload/oss', options)
.then((response) => {
return response.json();
})
.then((responseText) => {
console.log(responseText,'responseText')
this.loading = false;
if (responseText.code === 0) {
this.imgSrc = responseText.data.src;
// this.$emit('getImg', responseText.data.url);//传递给父组件
this.onCancel();
this.$notify({
title: '上传成功',
message: '上传成功',
type: 'success'
});
}
})
.catch((error) => {
this.loading = false;
this.$notify.error({
title: '上传失败',
message: error.msg,
});
})
}else {
this.$notify({
title: '警告',
message: '请点击拍照',
type: 'warning'
});
}
},
dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, {
type: mime})
},
// 取消
onCancel() {
this.visible = false;
this.isPhoto = false
this.resetCanvas();
this.thisVideo.srcObject.getTracks()[0].stop()
},
// 重置
resetCanvas() {
this.imgSrc = "";
this.clearCanvas('canvasCamera');
},
getCompetence(){
this.$nextTick(function () {
var _this = this;
this.thisCancas = document.getElementById('canvasCamera');
// console.log(this.thisCancas,'this.thisCancas',_this.thisCancas)
this.thisContext = this.thisCancas.getContext('2d');
this.thisVideo = document.getElementById('videoCamera');
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {
}
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
// 使用getUserMedia,因为它会覆盖现有的属性。
// 这里,如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia;
// 有些浏览器不支持,会返回错误信息
// 保持接口一致
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
var constraints = {
audio: false, video: {
width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } };
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
// 旧的浏览器可能没有srcObject
if ('srcObject' in _this.thisVideo) {
_this.thisVideo.srcObject = stream
} else {
// 避免在新的浏览器中使用它,因为它正在被弃用。
_this.thisVideo.src = window.URL.createObjectURL(stream)
}
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play()
}
}).catch(err => {
console.log(err)
return -1
})
this.isPhoto = true
})
},
//清空画布
clearCanvas(id) {
let c = document.getElementById(id);
let cxt = c.getContext("2d");
cxt.clearRect(0, 0, c.width, c.height);
}
由于用的不是https,使用的时候就会说获取不到摄像头权限
Error: getUserMedia is not implemented in this browser
at Object.navigator.mediaDevices.getUserMedia.navigator.mediaDevices.getUserMedia (chunk-5b18.a29aa0b5.js:1)
at a. (chunk-5b18.a29aa0b5.js:1)
at Array. (chunk-libs.18e4aae5.js:18)
at Gt (chunk-libs.18e4aae5.js:18)
at MfQN.t.exports (chunk-libs.18e4aae5.js:24)
at m. (chunk-libs.18e4aae5.js:8)
at Number.g (chunk-libs.18e4aae5.js:8)
at MessagePort.b (chunk-libs.18e4aae5.js:8)
看了很多方法,都不行,大多数都是说:创建谷歌浏览器快捷键,在快捷键(右键属性:目标)里面加
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-web-security --user-data-dir="C:/ChromeDevSession"
上面这种就得在c盘下创建chromeDEVSession文件
方法地址:https://www.cnblogs.com/aunrea/p/12671765.html
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --unsafely-treat-insecure-origin-as-secure="http://example.com"
方法地址:https://jingyan.baidu.com/article/eae0782771e36e1fec5485e6.html
以上均在lz项目中没办法解决;
lz项目中解决方法
地址栏输入:chrome://flags/#unsafely-treat-insecure-origin-as-secure
就会出现页面【里面输入对应项目地址(需要用摄像头项目地址)】