Skip to content

Commit cbc079e

Browse files
committed
代码优化开启摄像头
1 parent f4367a8 commit cbc079e

1 file changed

Lines changed: 96 additions & 124 deletions

File tree

‎userMedia.html‎

Lines changed: 96 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -3,165 +3,137 @@
33

44
<head>
55
<meta charset="UTF-8">
6-
<title>Title</title>
6+
<title>摄像头画面web前端实时输出功能</title>
77
</head>
8+
<style>
9+
.wrapper {
10+
text-align: center;
11+
}
12+
13+
button {
14+
display: block;
15+
line-height: 20px;
16+
font-size: 14px;
17+
text-align: center;
18+
color: #4c5161;
19+
border-radius: 4px;
20+
border: 1px solid #d0d0d5;
21+
padding: 10px 15px;
22+
min-width: 80px;
23+
background-color: #fff;
24+
background-repeat: no-repeat;
25+
background-position: center;
26+
text-decoration: none;
27+
box-sizing: border-box;
28+
transition: border-color .15s, box-shadow .15s, opacity .15s;
29+
font-family: inherit;
30+
cursor: pointer;
31+
overflow: visible;
32+
margin: 20px auto;
33+
}
34+
35+
.video,
36+
.canvas {
37+
border: 1px solid #d0d0d5;
38+
}
39+
</style>
840

941
<body>
10-
<input type="button" title="开启摄像头" value="开启摄像头" onclick="getMedia();" /><br />
42+
<div class="wrapper">
43+
<button id="openCamera" title="开启摄像头">开启摄像头</button>
1144

12-
<video height="400px" autoplay="autoplay" style='border: 1px solid #f00;'></video>
13-
<hr />
45+
<video width="700px" height="390px" class="video" autoplay="autoplay"></video>
1446

15-
<input type="button" title="拍照" value="拍照" onclick="getPhoto();" /><br />
16-
17-
<canvas id="canvas1" height="400px" style='border: 1px solid #f00;'></canvas>
18-
<hr />
19-
20-
<input type="button" title="视频" value="视频" onclick="getVedio();" /><br />
21-
<canvas id="canvas2" height="400px" style='border: 1px solid #f00;'></canvas>
47+
<button title="拍照" id="photograph">拍照</button>
2248

49+
<canvas id="canvas" class="canvas" width="700" height="530"></canvas>
2350

51+
</div>
2452
<script type="text/javascript">
25-
var videoHeight;
26-
var videoWidth;
27-
var video = document.querySelector('video');
28-
var audio, audioType;
29-
var canvas1 = document.getElementById('canvas1');
30-
var context1 = canvas1.getContext('2d');
31-
var canvas2 = document.getElementById('canvas2');
32-
var context2 = canvas2.getContext('2d');
33-
34-
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
35-
navigator.msGetUserMedia;
53+
let openCamera = document.querySelector("#openCamera")
54+
let photograph = document.querySelector("#photograph")
55+
window.isOpenCamera = false
56+
57+
let video = document.querySelector('video');
58+
let canvas = document.getElementById('canvas');
59+
let context1 = canvas.getContext('2d');
3660
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
37-
var exArray = []; //存储设备源ID
38-
try {
39-
MediaStreamTrack.getSources(function (sourceInfos) {
40-
for (var i = 0; i != sourceInfos.length; ++i) {
41-
var sourceInfo = sourceInfos[i];
42-
//这里会遍历audio,video,所以要加以区分
43-
if (sourceInfo.kind === 'video') {
44-
exArray.push(sourceInfo.id);
45-
}
46-
}
47-
});
48-
} catch (e) {
49-
console.log(e)
50-
}
5161

52-
function getMedia() {
53-
if (navigator.getUserMedia) {
54-
navigator.getUserMedia({
55-
'video': {
56-
'optional': [{
57-
'sourceId': exArray[0] //0为前置摄像头,1为后置
58-
}]
59-
},
60-
'audio': true
61-
}, successFunc, errorFunc); //success是获取成功的回调函数
62-
} else {
63-
/**
64-
* 测试ios手机及笔记本,微信及浏览器, 有趣的是navigator有getUserMedia这个属性,但值为均为undefined
65-
*时间 20191120
66-
*
67-
* */
68-
alert('Native device media streaming (getUserMedia) not supported in this browser.');
62+
// 开启摄像头
63+
openCamera.addEventListener("click", () => {
64+
65+
if (!navigator.mediaDevices.getUserMedia) return alert(
66+
'Native device media streaming (getUserMedia) not supported in this browser.');
67+
68+
if (this.isOpenCamera) return console.log('[已经开启过摄像头的权限了]');
69+
70+
let exArray = getSources()
71+
const constraints = {
72+
'video': {
73+
'optional': [{
74+
'sourceId': exArray[0] //0为前置摄像头,1为后置
75+
}]
76+
},
77+
'audio': true
6978
}
70-
}
79+
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
80+
successFunc(stream)
81+
this.isOpenCamera = true
82+
83+
}).catch(function (err) {
84+
alert(err.name + ": " + err.message);
85+
}); // 总是在最后检查错误;
86+
})
7187

88+
// 摄像机成功回调
7289
function successFunc(stream) {
73-
//alert('Succeed to get media!');
74-
console.log(stream);
7590
if (video.mozSrcObject !== undefined) {
76-
//Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
7791
video.mozSrcObject = stream;
7892
} else {
7993
try {
8094
video.src = window.URL && window.URL.createObjectURL(stream) || stream;
8195
} catch (e) {
82-
/**
83-
* 之前工作的网页调用摄像头获取视频并拍照的作品报错:
84-
Failed to execute 'createObjectURL' on 'URL'
85-
原因是Chrome升级后,新版本的Chrome不再支持该用法。
86-
其他主流浏览器也是如此,详细讨论请参考如下链接:
87-
https://www.fxsitecompat.com/en-CA/docs/2017/url-createobjecturl-stream-has-been-deprecated/
88-
* */
8996
try {
9097
video.srcObject = stream;
9198
} catch (error) {
9299
console.log(error)
93100
}
94101
}
95-
96-
97-
}
98-
//video.play();
99-
// 音频
100-
audio = new Audio();
101-
audioType = getAudioType(audio);
102-
if (audioType) {
103-
audio.src = 'polaroid.' + audioType;
104-
audio.play();
105-
}
106-
video.onplay = function (ev) {
107-
videoHeight = video.videoHeight;
108-
videoWidth = video.videoWidth;
109-
console.log(videoHeight)
110-
console.log(videoWidth)
111-
canvas1.width = videoWidth;
112-
canvas1.height = videoHeight;
113-
canvas2.width = videoWidth;
114-
canvas2.height = videoHeight;
115102
}
116-
117-
}
118-
119-
function errorFunc(e) {
120-
alert('Error!' + e);
121103
}
122104

123-
var img = new Image();
124-
img.src = "./imgs/shabi.png";
125-
img.onload = function (ev) {
126-
context1.drawImage(img, 0, 0);
127-
context2.drawImage(img, 0, 0);
105+
// 获取存储设备源ID
106+
function getSources() {
107+
let exArray = []; //存储设备源ID
108+
try {
109+
MediaStreamTrack.getSources(function (sourceInfos) {
110+
for (let i = 0; i != sourceInfos.length; ++i) {
111+
let sourceInfo = sourceInfos[i];
112+
//这里会遍历audio,video,所以要加以区分
113+
if (sourceInfo.kind === 'video') {
114+
exArray.push(sourceInfo.id);
115+
}
116+
}
117+
});
118+
} catch (e) {
119+
console.log('[获取存储设备源ID]', e)
120+
}
121+
return exArray
128122
}
129123

130-
// 将视频帧绘制到Canvas对象上,Canvas每60ms切换帧,形成肉眼视频效果
131-
function drawVideoAtCanvas(video, context) {
132-
window.setInterval(function () {
133-
context.drawImage(video, 0, 0);
134-
context.drawImage(img, 0, 0);
135-
136-
}, 60);
137-
}
124+
//拍照
125+
photograph.addEventListener("click", () => {
126+
if (!this.isOpenCamera) return alert("请开启摄像机权限")
138127

139-
//获取音频格式
140-
function getAudioType(element) {
141-
if (element.canPlayType) {
142-
if (element.canPlayType('audio/mp4; codecs="mp4a.40.5"') !== '') {
143-
return ('aac');
144-
} else if (element.canPlayType('audio/ogg; codecs="vorbis"') !== '') {
145-
return ("ogg");
146-
}
128+
let img = new Image();
129+
img.src = "";
130+
img.onload = function (ev) {
131+
context1.drawImage(img, 0, 0);
147132
}
148-
return false;
149-
}
150133

151-
// vedio播放时触发,绘制vedio帧图像到canvas
152-
// video.addEventListener('play', function () {
153-
// drawVideoAtCanvas(video, context2);
154-
// }, false);
155-
//拍照
156-
function getPhoto() {
157134
context1.drawImage(video, 0, 0); //将video对象内指定的区域捕捉绘制到画布上指定的区域,实现拍照。
158135
context1.drawImage(img, 0, 0);
159-
}
160-
161-
//视频
162-
function getVedio() {
163-
drawVideoAtCanvas(video, context2);
164-
}
136+
})
165137
</script>
166138
</body>
167139

0 commit comments

Comments
 (0)