浏览器调起摄像头(jquery+layui)
/*
实例化camvas配置参数
config = {
video:{width:Number(scale*4),height:Number(scale*3)},//视频比例4:3
canvasId:'canvas',//画布canvas节点ID
videoId:'v',//video节点ID
imgType:'png',//图片类型,/png|jpeg|bmp|gif/
quality:'1' //图片质量0-1之间
}
*/ window.URL = window.URL || window.webkitURL||window.mozURL || window.msURL; navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia window.requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame // Integrate navigator.getUserMedia & navigator.mediaDevices.getUserMedia
function getUserMedia (constraints, successCallback, errorCallback) {
if (!constraints || !successCallback || !errorCallback) {return} if (navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia(constraints).then(successCallback, errorCallback)
} else {
navigator.getUserMedia(constraints, successCallback, errorCallback)
}
} //获取摄像头设备源
function getMediaStream() {
var exArray = []; //存储设备源ID
MediaStreamTrack.getSources(function (sourceInfos) {
for (var i = 0; i != sourceInfos.length; ++i) {
var sourceInfo = sourceInfos[i];
//这里会遍历audio,video,所以要加以区分
if (sourceInfo.kind === 'video') {
exArray.push(sourceInfo.id);
}
}
});
return exArray;
} //用户手机端使用后置摄像头
function getMediaConfig() {
if (navigator.getUserMedia) {
if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
//手机端
return {
'video':
{'optional': [
{'sourceId': getMediaStream()[1] //0为前置摄像头,1为后置
}]
},
'audio':false
}
}else{
return {'video':true,'audio':false}
}
}
else {
alert('Native device media streaming (getUserMedia) not supported in this browser.');
}
} // The function takes a canvas context and a `drawFunc` function.
// `drawFunc` receives two parameters, the video and the time since
// the last time it was called.
function camvas(config) {
var self = this
self.convas = document.getElementById(config.canvasId)
self.ctx = self.convas.getContext('2d');
self.config = config
self.isStop = false; //video节点ID
self.video = document.getElementById(self.config.videoId) //video 显示尺寸
self.video.setAttribute('width', this.config.video.width)
self.video.setAttribute('height', this.config.video.height) //视频流控制句柄
var mediaStreamTrack;
//对外开启视频方法
this.startCamera = function () {
// The callback happens when we are starting to stream the video.
getUserMedia(getMediaConfig(), function(stream) {
// Yay, now our webcam input is treated as a normal video and
// we can start having fun
try {
mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks().length==1 ?
stream.getTracks()[0]:stream.getTracks()[1];
if(self.video.mozSrcObject !== undefined){
//Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
self.video.mozSrcObject = stream;
}else{
self.video.srcObject = stream;
}
} catch (error) {
self.video.src = window.URL && window.URL.createObjectURL(stream) || stream;
}
self.isStop = false;
self.video.play();
// Let's start drawing the canvas!
// self.recordVideo()
}, function(err){
alert(err);
})
} //录像方法
this.recordVideo = function() {
var self = this
var last = Date.now()
var loop = function() {
// For some effects, you might want to know how much time is passed
// since the last frame; that's why we pass along a Delta time `dt`
// variable (expressed in milliseconds)
var dt = Date.now() - last
self.draw(self.video, dt)
last = Date.now()
requestAnimationFrame(loop)
}
requestAnimationFrame(loop)
}
//停止视频
this.stop = function () {
self.ctx.clearRect(0, 0, self.config.video.width,self.config.video.height);
mediaStreamTrack && mediaStreamTrack.stop();
self.isStop = true;
}
//拍照,base64/image/png
this.drawImage=function (callback) {
if(!self.isStop){
self.ctx.drawImage(self.video,0,0,self.config.video.width,self.config.video.height);
var base64URL = self.convas.toDataURL('image/'+self.config.imgType,self.config.quality);
callback&&callback(base64URL);
}
} //录像数据帧
this.draw = function(video, dt) {
self.ctx.drawImage(video, 0, 0)
}
}
<style>
.camera-control {
position: absolute;
z-index: 10;
left: 0;
right: 0;
bottom: 0;
text-align: center;
padding: 10px;
min-height: 40px;
}
.camera-btn {
cursor: pointer;
border: none;
color: #fff;
padding: 8px 12px;
font-size: 14px;
outline: none;
background-color: rgba(255, 255, 255, 0.3);
transition: all 0.3s;
box-shadow: 0 2px 0 0 rgba(45, 140, 240, 0.8);
margin: 0 5px;
}
.camera-canvas-group {
display: flex;
left: 0;
right: 0;
height: 80px;
}
.camera-canvas-item {
opacity: 0.8;
flex: 1;
max-width: 100px;
height: 100%;
overflow: hidden;
clear: both;
margin-bottom: -1px;
transition: all 0.2s;
position: relative;
}
.camera-canvas-item img {
float: left;
width: 100%;
background-color: #000;
border: 1px solid #fff;
} .camera-canvas-item:hover {
position: relative;
opacity: 1;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.8);
} .camera-canvas-item:hover {}
.camera-btn:hover {
background-color: rgba(45, 140, 240, 0.6);
box-shadow: 0 2px 0 0 rgba(45, 140, 240, 1);
} .camera-btn:active {
background-color: rgba(45, 140, 240, 0.2);
}
.canvas-item-del{
position: absolute;
right: 0px;
font-size: 22px;
color: #ef475d;
cursor: pointer;
}
.camera-show-pc{
background-color:#FFFFFF;margin:0px auto;
}
</style>
<div class="layui-fluid layui-anim" id="camera" lay-title="摄像头测试">
<div class="layui-row">
<div class="layui-card" style="background-color:#1E8AE8;margin: auto auto;">
<div class="layui-card-body">
<div class="layui-row camera-show-pc">
<h1 style="padding: 23px 0px;;font-size: 2.4rem;color: #1E8AE8;font-weight: bold;text-align: center">camera</h1>
<div class="bag_display_flex" style="justify-content: center;">
<div style="position: relative;">
<video id="v" style="background-color: #000000"></video>
<div class="camera-control">
<button type="button" id="stop" class="layui-icon layui-icon-stop camera-btn">关闭</button>
<button type="button" id="start" class="layui-icon layui-icon-triangle-r camera-btn">开始</button>
<button type="button" id="snap" class="layui-icon layui-icon-camera-fill camera-btn">拍照</button>
<button type="button" id="save" class="layui-icon layui-icon-save camera-btn">保存</button>
<button type="button" id="clear" class="layui-icon layui-icon-fonts-clear camera-btn">清空</button>
</div>
</div>
<div>
<canvas id="canvas" style="margin-left: 2px;background-color: #000000"></canvas>
</div>
</div>
<div class="layui-row" style="position: relative">
<div class="camera-canvas-group"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/camera/camvas.js"></script>
<script data-th-inline="javascript" type="text/javascript">
layui.use(['jquery'], function () {
var $ = layui.jquery,
$view = $('#camera'),
config={},
myCamvas;
init();
onClick(); function init() {
let scale = 120;//宽高比例倍数
config = {
video:{width:Number(scale*4),height:Number(scale*3)},//4:3
canvasId:'canvas',
videoId:'v',
imgType:'png',
quality:'1' //图片质量0-1之间
};
$('.camera-show-pc').css('width',config.video.width*2+20);
$view.find('#canvas').attr('width',config.video.width);
$view.find('#canvas').attr('height',config.video.height);
//拍照实例化
myCamvas = new camvas(config);
myCamvas.startCamera();
$view.find('#start').hide();
}
function onClick() {
//停止拍照
$view.find('#stop').click(function () {
myCamvas.stop()
$view.find('#stop').hide()
$view.find('#start').show()
})
//启动摄像头
$view.find('#start').click(function () {
myCamvas.startCamera();
$view.find('#stop').show()
$view.find('#start').hide()
})
//拍照
$view.find('#snap').click(function () {
myCamvas.drawImage(function drawImage(base64URL) {
let xsCamera = $('<div></div>').addClass('camera-canvas-item');
xsCamera.append($('<img>').attr('src',base64URL)).append($('<span></span>').addClass('layui-icon layui-icon-close-circle-fill canvas-item-del'));
$('.camera-canvas-group').prepend(xsCamera);
});
})
//清空
$view.find('#clear').click(function () {
$view.find('.camera-canvas-group').empty()
}) //append方式添加节点直接click无效,点击显示大图
$view.find('.camera-canvas-group').on('click','.camera-canvas-item img',function () {
myCamvas.ctx.drawImage(this,0,0,config.video.width,config.video.height)
})
//删除图片
$view.find('.camera-canvas-group').on('click','.camera-canvas-item .canvas-item-del',function () {
//删除父节点元素
$(this).closest('.camera-canvas-item').remove()
})
//保存所有图片到本地
$view.find('#save').click(function () {
let fileName = getFileName();
let el_a = $('<a>');
layui.each($view.find('.camera-canvas-group .camera-canvas-item'),function (k,item) {
let t_filename = fileName+'_'+k+'.'+config.imgType;
downLoad($(this).find('img').attr('src'),t_filename,config.imgType);
})
})
//空格按下拍照
$(document).keypress(function (e) {
e.keyCode===32&&$('#snap').trigger('click');
})
};
//tode
function getFileName() {
let date = new Date();
let fileName = ''+date.getFullYear()+(date.getMonth()<9?+'0':'')
+(date.getMonth()+1) +(date.getDate()<10?+'0':'')+date.getDate()
+date.getHours() +date.getMinutes()+(date.getSeconds()<10?'0':'')+date.getSeconds();
return fileName;
}
function downLoad(dataURL,fileName,fileType) {
var reader = new FileReader();
reader.readAsDataURL(createFile(dataURL));
reader.onload = function (e) {
if ('msSaveOrOpenBlob' in navigator) { // IE,Edge
var base64file = e.target.result + '';
window.navigator.msSaveOrOpenBlob(createFile(base64file.replace('data:' + fileType + ';base64,', ''), fileType), fileName);
} else { // chrome,firefox
var link = document.createElement('a');
link.style.display = 'none';
link.href = e.target.result;
link.setAttribute('download', fileName);
// document.body.appendChild(link);
link.click();
$(link).remove();
}
} /*dataURL = dataURL.replace('image/'+fileType,'image/octet-stream');
var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
save_link.href = dataURL;
save_link.download = fileName;
$(save_link).click()
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
save_link.dispatchEvent(event);*/
}; // 解析 BASE64文件内容 for IE,Edge
function createFile(urlData) {
var arr = urlData.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = window.atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
} });
</script>
浏览器调起摄像头(jquery+layui)的更多相关文章
- 在火狐、360等浏览器中,用jquery创建表单并发送的问题
某些浏览器无法使用js或者jquery直接创建表单并发送,这是由于这些浏览器在提交页面表单时要求页面有完整的标签项即<html><head><title></ ...
- input type = file 在部分安卓手机上无法调起摄像头和相册
移动端H5web 用input type = file 在部分安卓手机上无法调起摄像头拍照,有的也无法访问相册而是直接访问了文档,解决办法是: 加上 accept = "image/*&qu ...
- 浏览器调起Hbuilder的APP
最近用Hbuilder来开发APP,测试各种功能,其中,最近测试到,要用这个浏览器调起APP的功能,我看官网有教程,但是有些可能刚工作没多久,所以,有些地方看不大明白,官方也没细说,所以 ...
- jquery layui的巨坑
jquery layui的巨坑 layui 模块不能写在ajax里 因为 layui只能执行一次 第二次会没效果 再执行需要刷新页面再执行
- 深入浏览器兼容 细数jQuery Hooks 属性篇
关于钩子:http://www.cnblogs.com/aaronjs/p/3387906.html 本章的目的很简单,通过钩子函数更细节的了解浏览器差异与处理方案, 版本是2.0.3所以不兼容ie6 ...
- 浏览器下载/导出文件 及jQuery表单提交
1 比如以下按钮, 用于导出文件,如EXCEL文件. <li> <button class="whiteBg btn2" onclick="doExp( ...
- 能跨域和跨浏览器的flashcookie for jquery插件
对于写网站时需要跨域和跨浏览器的可以看看这个. 引入jquery 和 swfstore.min.js 就可以了,蛮简单好用的,会jquery基础就可以咯. mySwfStore.set('myKey ...
- pasteimg浏览器中粘贴图片jQuery插件
pasteimg是一款可以在浏览器中实现图片粘贴的jQuery插件,兼容Chrome.Firefox.IE11以及其他使用这些内核的浏览器,比如,国内著名的360浏览器. pasteimg可以识别浏览 ...
- chrome浏览器模拟手机端:jquery click()点击无效解决方法
$(".sku-wrap .ok").click(); chrome浏览器模拟手机端,在油猴插件中写JS代码,然后发现click()点击失效. 解决方法:jquery的click( ...
随机推荐
- 关于conda-新手必读
一.管理conda 通过anaconda来安装python及python包,让你不必关心系统是否安装了一些依赖,如zlib等等,anaconda已经集成了这些依赖,可以方便的安装python 下载请点 ...
- Taro -- 微信小程序wxParse达到html转换wxml
Taro微信小程序可以用wxParse来达到html转换wxml的效果:https://github.com/NervJS/taro-components-test/blob/master/src/p ...
- Sass:@at-root
@at-root 从字面上解释就是跳出根元素.当你选择器嵌套多层之后,想让某个选择器跳出,此时就可以使用 @at-root.来看一个简单的示例: .a { color: red; .b { color ...
- windows2008R2-AD域控组策略设置与其它相关设置
防火墙设置 修改>计算机配置>策略>安全设置>高级安全windows防火墙>高级安全windows防火墙 修改入站规则 1.组名-文件和打印机共享(SMB-In)> ...
- hdu 6143: Killer Names (2017 多校第八场 1011)
题目链接 题意,有m种颜色,给2n个位置染色,使左边n个和右边n个没有共同的颜色. 可以先递推求出恰用i种颜色染n个位置的方案数,然后枚举两边的染色数就可以了,代码很简单. #include<b ...
- groovy-2.4.11.jar时出错; invalid LOC header (bad signature)
Information:java: Errors occurred while compiling module 'security'Information:javac 1.8.0_131 was u ...
- macOS 10.14 Mojave Apache Setup: Multiple PHP Versions
Part 1: macOS 10.14 Mojave Web Development Environment Developing web applications on macOS is a rea ...
- 5 October
POJ2676 Sudoku 位运算 + 搜索.更好的优化方法:方案数最小的空格先填. 把某一位 置为 0:a &=~ (1<<n) 把某一位 置为 1:a |= (1<&l ...
- 一个关于 ie 浏览器的 bug 解决过程和思考
首先我们测试了老师反馈的异常情况.这所中学使用的是 IE8 浏览器.IE8 浏览器提交作文评分的情况是:一直停留在“正在提交系统评分”的页面,停留了很长时间以后,页面空白. 换用火狐浏览器,可以正常评 ...
- 通过 homebrew下载速度过慢的解决方案
请移步 https://www.cnblogs.com/jingxiaoniu/p/11123377.html 进行操作