2022.01.14更新
MediaRecorder
录制api ,这个api在uc浏览器和iphone的safari浏览器中不支持)MediaRecorder
参考文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>摄像头拍照</title>
</head>
<body>
<video id="video" width="300" height="300" controls>
</video>
<div>
<button id="capture">拍照</button>
</div>
<canvas id="canvas" width="480" height="320"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.11.0/vconsole.min.js"></script>
<script>
// var vConsole = new VConsole();
//访问用户媒体设备的兼容方法
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints, success, error)
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, success, error);
}
}
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
function success(stream) {
//兼容webkit核心浏览器
let CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
console.log(stream);
// video.src = CompatibleURL.createObjectURL(new Blob(stream));
video.srcObject = stream;
video.play();
}
function error(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
console.log(error)
}
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator
.mozGetUserMedia) {
//调用用户媒体设备, 访问摄像头
getUserMedia({
video: {
width: 300,
height: 300
}
}, success, error);
} else {
alert('不支持访问用户媒体');
}
document.getElementById('capture').addEventListener('click', function() {
context.drawImage(video, 0, 0, 480, 320);
})
</script>
</body>
</html>
<template>
<div>
<video id="video" width="300" height="300" controls></video>
<div>
<button id="capture" @click="btnClick">拍照</button>
</div>
<canvas id="canvas" width="320" height="320"></canvas>
</div>
</template>
<script>
export default {
data() {
return {
video: null,
canvas: null,
context: null,
}
},
mounted() {
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
// uniapp 对 video 标签进行了封装 所以用下面的方式获取
// let video = document.getElementsByClassName('uni-video-video')[0]
// let canvas = document.getElementsByTagName('canvas')[0]
console.log(canvas)
let context = canvas.getContext('2d');
this.video = video
this.init()
this.canvas = canvas
this.context = context
},
methods: {
// 获取设备
getUserMedia(constraints, successCallback, errorCallback) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(successCallback).catch(errorCallback);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, successCallback, errorCallback);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
},
successCallback(stream) {
//兼容webkit核心浏览器
// let CompatibleURL = window.URL || window.webkitURL;
// video.src = CompatibleURL.createObjectURL(new Blob(stream));
//将视频流设置为video元素的源
console.log(stream);
console.log(this.video)
this.video.srcObject = stream;
this.video.play();
},
errorCallback(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
console.log(error)
},
init() {
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
//调用用户媒体设备, 访问摄像头
this.getUserMedia(
{
video: { width: 320, height: 320 },
},
this.successCallback,
this.errorCallback
);
} else {
alert('不支持访问用户媒体');
}
},
btnClick() {
this.context.drawImage(this.video, 0, 0, 320, 320);
}
}
}
</script>
<style>
</style>
<template>
<view>
<video id="video" class="video-box" width="120" height="120" :controls="false"></video>
<div>
<button id="capture" @click="btnClick">拍照</button>
</div>
<canvas id="canvas" width="120" height="120"></canvas>
<!-- <view class="">
上传成功地址: {{uploadSuccessURL}}
</view> -->
<view v-for="(item,index) in list" :key="index">
{{item}}
</view>
</view>
</template>
<script>
import { uploadFileURL } from '@/common/config.js'
export default {
data() {
return {
video: null,
canvas: null,
context: null,
uploadSuccessURL: '',
list: []
}
},
onReady() {
// #ifdef H5
// uniapp 对 video 标签进行了封装 所以用下面的方式获取
let video = document.getElementsByClassName('uni-video-video')[0]
// let video = document.getElementById('video');
// let canvas = document.getElementById('canvas');
let canvas = document.getElementsByTagName('canvas')[0]
console.log(canvas)
let context = canvas.getContext('2d');
this.video = video
this.canvas = canvas
this.context = context
const _this = this
uni.showModal({
content: '是否进行人脸认证',
success(r) {
if(r.confirm) {
_this.init()
}
if(r.cancel) {
uni.redirectTo({
url: '/pages/index/index'
})
}
}
})
// this.init()
// #endif
},
methods: {
// 获取设备
// constraints 这个用来控制你需要调取的设备
getUserMedia(constraints, successCallback, errorCallback) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices.getUserMedia(constraints).then(successCallback).catch(errorCallback);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, successCallback, errorCallback);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
},
// 调用摄像头 成功的回调
successCallback(stream) {
//兼容webkit核心浏览器
this.list.push('走进摄像头成功回调')
//将视频流设置为video元素的源
console.log(stream);
// console.log(this.video)
// 录制视频
this.recordVideo(stream)
// 录制视频 end
this.video.srcObject = stream;
this.video.play();
},
// 调用摄像头 失败的回调
errorCallback(error) {
this.list.push('摄像头调用失败')
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
console.log(error)
const errorMap = {
'NotAllowedError': '摄像头已被禁用,请在系统设置或者浏览器设置中开启后重试',
'AbortError': '硬件问题,导致无法访问摄像头',
'NotFoundError': '未检测到可用摄像头',
'NotReadableError': '操作系统上某个硬件、浏览器或者网页层面发生错误,导致无法访问摄像头',
'OverConstrainedError': '未检测到可用摄像头',
'SecurityError': '摄像头已被禁用,请在系统设置或者浏览器设置中开启后重试',
'TypeError': '类型错误,未检测到可用摄像头'
};
if(errorMap[error.name]) {
console.log(errorMap[error.name])
this.$toast(errorMap[error.name])
}
},
// 录制视频
recordVideo(stream) {
this.list.push('走进录制视频')
const _this = this
// https://developer.mozilla.org/zh-CN/docs/Web/API/MediaRecorder
if(!MediaRecorder) {
this.$toast('当前环境不支持MediaRecorder录制')
return
}
this.list.push('当前环境含有MediaRecorder')
var chunks = [];
var mediaRecorder = new MediaRecorder(stream);
this.list.push('当前环境成功 new MediaRecorder')
mediaRecorder.start()
this.list.push('当前环境 mediaRecorder.start')
// 默认录制3秒后上传 mediaRecorder.stop()会触发 mediaRecorder.ondataavailable()事件
setTimeout(function() {
mediaRecorder.stop()
}, 3000 )
// 获取录制的资源 上传文件
mediaRecorder.ondataavailable = function(e) {
_this.list.push('获取录制的资源 ondataavailable')
chunks.push(e.data);
console.log('chunks', chunks)
var file = new File(chunks, "media_.mp4");
_this.list.push('获取录制的资源 new File 成功')
console.log('file', file)
var formData = new FormData();
formData.append('file', file);
console.log('formData', formData)
console.log(e)
_this.list.push('获取录制的资源 成功走到上传前')
// 创建 ajax 开始上传
var xhr = new XMLHttpRequest();
xhr.open('post', uploadFileURL);
xhr.send(formData);
xhr.onreadystatechange = function(){
// 判断服务器是否响应,判断异步对象的响应状态
if(xhr.status == 200 && xhr.readyState == 4){
console.log(xhr.responseText);
const res = JSON.parse(xhr.responseText)
_this.uploadSuccessURL = res.data.path
_this.$toast(res.message || '上传完成')
} else if(xhr.readyState == 4 && xhr.status != 200) {
console.log(xhr.status)
}
}
}
},
// 初始化调用
init() {
// #ifdef H5
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator .mozGetUserMedia) {
//调用用户媒体设备, 访问摄像头
this.getUserMedia(
{
// audio: true, // 调用录音
video: {
width: 120,
height: 120,
facingMode: "user" //调用前置摄像头
},
},
this.successCallback,
this.errorCallback
);
} else {
alert('不支持访问用户媒体');
}
// #endif
},
// 点击拍照
btnClick() {
this.context.drawImage(this.video, 0, 0, 120, 120);
},
close() {
this.video = null
this.canvas = null
this.context = null
}
}
}
</script>
<style scoped>
.video-box {
width: 120px;
height: 120px;
border-radius: 50%;
margin: 0 auto;
margin-top: 100rpx;
display: block;
}
</style>