js调用摄像头录像并传到后端
参考自https://juejin.im/entry/5b91e8e7f265da0ac55e2cd6?tdsourcetag=s_pcqq_aiomsg
项目要求前端h5页面调用摄像头录像,然后传给后端进行人脸识别,根据返回值进行路由跳转,流媒体这方面以前接触过的都是推流拉流转发之类的软件,前端进行流媒体开发,最常用的是flash,兼容性也最好,但是它的学习成本太高了,flash这方面由公司另找人做了,我主要负责移动手机页面的开发,然后把页面嵌入到app产品里面,公司领导找到了解决方案,我跟着改写了一下,效果还是可以的,特此记录
利用的是浏览器自带的apiMediaRecorder这个api
它有3个事件
onstart
录制开始
onstop
录制结束
onstart
录制结束时同时触发,事件对象中返回录制的媒体数据
/*navigator.mediaDevices.getUserMedia是获取手机摄像头跟话筒的方法,它返回的
是promise对象,因为用户要手动选择同意,只支持火狐浏览器,chrome浏览器必须在
localhost,https协议下访问,如果用ip+端口的话会因为安全策略拒绝获取摄像头*/
/*
{ audio: true, video: { facingMode: "user" } }这里是选择了前置摄像头
*/
requestAudioAccess() {
navigator.mediaDevices
.getUserMedia({ audio: true, video: { facingMode: "user" } })
.then(
stream => {
this.mediaStreamTrack =
typeof stream.stop === "function"
? stream
: stream.getTracks()[1];
this.recorder = new window.MediaRecorder(stream);
this.stream = stream;
this.bindEvents();
this.onPreview();
},
error => {
alert("出错,请确保已允许浏览器获取音视频权限");
}
);
},
绑定事件
bindEvents () {
//录制结束的时候获取视频保存下来
this.recorder.ondataavailable = this.getRecordingData;
this.recorder.onstop = this.saveRecordingData;
},
结束录制并传到后端,这里一开始用的axios,但是使用时会把二进制文件序列化导致失效,于是用的原生ajax
saveRecordingData() {
Indicator.open("上传视频中...");
this.uploading = true;
let blob = new Blob(this.chunks, { type: "video/webm" }),
videoStream = URL.createObjectURL(blob);
this.chunkList.push({ stream: videoStream });
var file = new File(
[blob],
"msr-" + new Date().toISOString().replace(/:|\./g, "-") + ".webm",
{
type: "video/webm"
}
);
var formData = new FormData();
formData.append("fileName", file);
formData.append("name", this.name);
formData.append("idCard", this.idCard);
var request = new XMLHttpRequest();
var url = "yourURL";
request.open("POST", url);
request.send(formData);
let self = this;
request.onreadystatechange = function() {
var res = request.responseText;
if (request.readyState == 4 && request.status == 200) {
Indicator.close();
this.uploading = false;
res = JSON.parse(res);
if (res.data.faceAuthFlg && res.data.faceAuthFlg == "1") {
self.$router.push({
path: "/rlsb/success",
query: {
successUrl: res.data.successUrl
}
});
} else {
self.$router.push({
path: "/rlsb/result",
query: {
failCount: res.data.failCount
}
});
}
} else {
Indicator.close();
this.uploading = false;
self.$router.push({
path: "/rlsb/result",
});
}
};
}