直入正题,JS打开摄像头并截图上传至后端的一个完整步骤
1. 打开摄像头主要用到getUserMedia方法,然后将获取到的媒体流置入video标签 2. 截取图片主要用到canvas绘图,使用drawImage方法将video的内容绘至canvas中 3. 将截取的内容上传至服务器,将canvas中的内容转为base64格式上传,后端(PHP)通过file_put_contents将其转为图片
要注意的是,在chrome以外的浏览器中,使用摄像头或多或少会出现一些问题,可能也是老问题了,所以以下代码主要基于chrome使用
比如在最新版FireFox中的报错,不知为啥
getUserMedia 有新版本和旧版本两种,建议使用新版本
旧版本位于navigator 对象下,根据浏览器不同有所不同
// 获取媒体方法(旧方法)
navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;
if (navigator.getMedia) {
navigator.getMedia({
video: true
}, function(stream) {
mediaStreamTrack = stream.getTracks()[0];
video.src = (window.URL || window.webkitURL).createObjectURL(stream);
video.play();
}, function(err) {
console.log(err);
});
}
第一个参数中指示需要使用视频(video)或音频(audio),更多参见文档
第二个参数中指示调用成功后的回调,其中带一个参数(MediaStream),在旧版本中可以直接通过调用MediaStream.stop() 来关闭摄像头,不过在新版之中已废弃。需要使用MediaStream.getTracks()[index].stop() 来关闭相应的Track
第三个参数指示调用失败后的回调
新版本位于navigator.mediaDevices 对象下
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(function(stream) {
console.log(stream);
mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1];
video.src = (window.URL || window.webkitURL).createObjectURL(stream);
video.play();
}).catch(function(err) {
console.log(err);
})
}
与旧版类似,不过该方法返回了一个Promise对象,可以使用then和catch表示成功与失败的回调
需要注意的是,MediaStream.getTracks() 返回的Tracks数组是按第一个参数倒序排列的
比如现在定义了
{
video: true,
audio: true
}
想关闭摄像头,就需要调用MediaStream.getTracks()[1].stop();
同理,0对应于audio的track
使用createObjectURL 将MediaStream写入video标签,就能够存储实时的媒体流数据(也可以方便的实时查看画面)
旧版本中webkitURL 对象以不被支持,需要使用URL对象
<video width="200" height="150"></video>
<canvas width="200" height="150"></canvas>
<p>
<button id="snap">截取图像</button>
<button id="close">关闭摄像头</button>
<button id="upload">上传图像</button>
</p>
<img id="uploaded" width="200" height="150" />
将内容写入即可
// 截取图像
snap.addEventListener('click', function() {
context.drawImage(video, 0, 0, 200, 150);
}, false);
// 关闭摄像头
close.addEventListener('click', function() {
mediaStreamTrack && mediaStreamTrack.stop();
}, false);
canvas.toDataURL('image/png')
// 上传截取的图像
upload.addEventListener('click', function() {
jQuery.post('/uploadSnap.php', {
snapData: canvas.toDataURL('image/png')
}).done(function(rs) {
rs = JSON.parse(rs);
console.log(rs);
uploaded.src = rs.path;
}).fail(function(err) {
console.log(err);
});
}, false);
而这里的后端(PHP)则将获取的内容转换成图像文件保存
需要注意的是,要将base64的头部信息字段去掉再保存,否则似乎图像是损坏无法打开滴
<?php
$snapData = $_POST['snapData'];
$snapData = str_replace('data:image/png;base64,', '', $snapData);
// $snapData = str_replace(' ', '+', $snapData);
$img = base64_decode($snapData);
$uploadDir = 'upload/';
$fileName = date('YmdHis', time()) . uniqid();
if (!(file_put_contents($uploadDir . $fileName, $img))) {
echo json_encode(array('code' => 500, 'msg' => '文件上传失败'));
} else {
echo json_encode(array('code' => 200, 'msg' => '文件上传成功', 'path' => $uploadDir . $fileName));
}
?>
完整JS代码
1 <script type="text/javascript" src="jquery.js"></script>
2 <script type="text/javascript">
3 function $(elem) {
4 return document.querySelector(elem);
5 }
6
7 // 获取媒体方法(旧方法)
8 navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;
9
10 var canvas = $('canvas'),
11 context = canvas.getContext('2d'),
12 video = $('video'),
13 snap = $('#snap'),
14 close = $('#close'),
15 upload = $('#upload'),
16 uploaded = $('#uploaded'),
17 mediaStreamTrack;
18
19 // 获取媒体方法(新方法)
20 // 使用新方法打开摄像头
21 if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
22 navigator.mediaDevices.getUserMedia({
23 video: true,
24 audio: true
25 }).then(function(stream) {
26 console.log(stream);
27
28 mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1];
29
30 video.src = (window.URL || window.webkitURL).createObjectURL(stream);
31 video.play();
32 }).catch(function(err) {
33 console.log(err);
34 })
35 }
36 // 使用旧方法打开摄像头
37 else if (navigator.getMedia) {
38 navigator.getMedia({
39 video: true
40 }, function(stream) {
41 mediaStreamTrack = stream.getTracks()[0];
42
43 video.src = (window.URL || window.webkitURL).createObjectURL(stream);
44 video.play();
45 }, function(err) {
46 console.log(err);
47 });
48 }
49
50 // 截取图像
51 snap.addEventListener('click', function() {
52 context.drawImage(video, 0, 0, 200, 150);
53 }, false);
54
55 // 关闭摄像头
56 close.addEventListener('click', function() {
57 mediaStreamTrack && mediaStreamTrack.stop();
58 }, false);
59
60 // 上传截取的图像
61 upload.addEventListener('click', function() {
62 jQuery.post('/uploadSnap.php', {
63 snapData: canvas.toDataURL('image/png')
64 }).done(function(rs) {
65 rs = JSON.parse(rs);
66
67 console.log(rs);
68
69 uploaded.src = rs.path;
70 }).fail(function(err) {
71 console.log(err);
72 });
73 }, false);
74
75 </script>
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有