浏览器中打开摄像头
 本⽂是讲述如何在浏览器中打开摄像头,并且实时显⽰在页⾯上。想要实现这⼀功能,需要依赖WebRTC (Web Real-Time Communications) 这⼀实时通讯技术,它允许浏览器之间视频流和⾳频流或者其他任意数据的传输,当然其中包含了⼤量的API和协议,这些在这⾥都不做介绍,具体的标准还在完善之中,所以使⽤的⽅法有时候也需要考虑到兼容问题,那么回到主题,怎样使⽤webRTC获取视频流。
  ⾸先对于html,我们需要⼀个video标签来播放视频(JS中添加也可以),当然画布也是能够实现的。使⽤video有些属性必须要配置。
<video id="video" autoplay playsinline></video>
  上⾯两个属性必须要添加,autoplay设置video⾃动播放,否则通信成功后页⾯将会保留第⼀张静⽌的画⾯。playsinline是由于有些浏览器默认会开启全屏播放,⽽全屏可能是画⾯变成⿊屏。
  webRTC⼤部分浏览器⽀持,IE(Edge)15+,Safari 11+,IOS Safari 11.2+, Android 64+, QQ、百度部分⽀持,对于IOS必须系统在11以上,并且只有Safari⽀持,UC 浏览器不⽀持。
  对于webRTC⽀持情况,可以采⽤以下代码判断。
if (diaDevices === undefined ||
if (diaDevices === undefined) {
var fctName = 'diaDevices'
} else if (umerateDevices === undefined) {
var fctName = 'umerateDevices'
} else if (UserMedia === undefined) {
var fctName = 'UserMedia'
} else {
console.assert(false)
}
alert('WebRTC issue-! ' + fctName + ' not present in your browser')
}
  获取video元素。
let video = document.querySelector('#video');
  如果⽀持webRTC,那么就调⽤mediaDevice的⽅法来遍历媒体对象,该⽅法返回⼀个promise对象,在第⼀个then⽅法的回调函数⾥⾯默认接收返回的媒体信息。umerateDevices().then(function (sourceInfos) {
})
  获取sourceInfos,要拿到后置摄像头的信息并不是通⽤的,PC、IOS、Android以及不同浏览器,处理⽅法都不同,这⾥只做IOS和Android区分。
if(!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
}
  如果不是IOS,那么就需要遍历sourceinfos,获取后置摄像头再获取视频流。声明⼀个exArray⽤来存放不同媒体设备的id,再通过id获取摄像头信息。
let exArray = [];
for (var i = 0; i < sourceInfos.length; ++i) {
if (sourceInfos[i].kind == 'videoinput') {
exArray.push(sourceInfos[i].deviceId);
}
}
  这样数组⾥⾯存放的都是摄像头的id,⽽我们需要的是后置摄像头,再调⽤获取媒体信息的⽅法。
if (UserMedia) {
// 该⽅法可以传递3个参数,分别为获取媒体信息的配置,成功的回调函数和失败的回调函数
audio: false, // 表明是否获取⾳频
video: {  // 对视频信息进⾏配置
optional: [{
'sourceId': exArray[1] // 下标为0是前置摄像头,1为后置摄像头,所以PC不能进⼊该判断,否则画⾯会保持在第⼀帧不动
}]
},
}, function successFunc(stream) {
// 对FireFox进⾏兼容,这⾥对返回流数据的处理不同
if (SrcObject !== undefined) {
//Firefox中,SrcObject最初为null,⽽不是未定义的,我们可以靠这个来检测Firefox的⽀持
} else {
// ⼀般的浏览器需要使⽤createObjectURL对流数据进⾏处理,再交给video元素的src
video.src = window.URL && ateObjectURL(stream) || stream;
}
}, function errorFunc(e) {
alert('Error!' + e);
}); //success是获取成功的回调函数
} else {
alert('Native device media streaming (getUserMedia) not supported in this browser.');
}
  在成功的回调函数中,将返回的视频流交给html中的video元素,这⾥src的⽅式实际是通过blob64的格式来传输的。
  // =============================  IOS
  在IOS中获取视频流现实的⽅式⼜不⼀样了,我们需要调⽤mediaDevice的获取媒体的⽅法,这也是最新的标准。⾸先需要些⼩⼩的配置:// 这⾥对⽣成视频进⾏配置
var userMediaConstraints = {
audio: false, // 是否获取⾳频
video: {
facingMode: 'environment',  // 环境表⽰后置摄像头,使⽤user表⽰采⽤前置
// 宽⾼的配置⽐较灵活,由于video⼀般都会显⽰固定宽⾼⽐,所以使⽤ideal理想值即可
width: {
ideal: 1024,
// min: 1024,
// max: 1920
},
height: {
ideal: 768,
// min: 776,
// max: 1080
}
}
}
  再调⽤⽅法获取视频就很简单了,如下:
video.srcObject = stream;
}).catch(function (error) {
alert(error.name + ssage)
});
  整体如下:
<!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>web RTC</title>
</head>
<body>
<!-- 这⾥必须设置autoplay,否则视频画⾯静⽌为第⼀张 -->
<!-- 必须设置为playsinline,默认全屏播放可能会导致⿊屏 -->
<video id="video" autoplay playsinline></video>
<script>
// 习惯性写在函数中,控制变量
;(function(){
//  由于IOS必须在版本11以上才能使⽤webrtc,并且只有Safari⽀持,所以做⼀个⼩⼩的判断,限定在
if(/(iPhone|iPad|iPod|iOS)/i.test(window.navigator.userAgent) && navigator.vender.indexOf("apple") > -1) {
    return;
}
/**
* =============实现在浏览器中打开摄像头,并且将摄像头内容显⽰在页⾯中
* 想要实现这⼀功能,需要了解webRTC(Web Real-Time Communication)⽹络实时通话技术,它允许浏览器实现视频、⾳频、P2P⽂件分享等功能。    */
// 开启视频功能,依赖window的navigator对象,采⽤getUserMedia⽅法,有版本差异,所以需要判断区分
// 需要IE(Edge)15+, Safari 11+, IOS Safari 11.2+, Android 64+, UC 不⽀持, QQ、百度部分⽀持
// 所以⾸先需要对浏览器⽀持情况进⾏判断
/
/ 先判断浏览器是否⽀持
if (diaDevices === undefined ||
// 再判断具体是那个⽅法不⽀持,并向⽤户显⽰
if (diaDevices === undefined) {
var fctName = 'diaDevices'
} else if (umerateDevices === undefined) {
var fctName = 'umerateDevices'
} else if (UserMedia === undefined) {
var fctName = 'UserMedia'
} else {
console.assert(false)
}
alert('WebRTC issue-! ' + fctName + ' not present in your browser')
}
const video = document.querySelector('#video')
// 如果浏览器⽀持,该⽅法的更新是向后兼容,新版将所有功能都使⽤diaDevices进⾏了封装
// 如果⽀持新的⽅法,那么就使⽤新的⽅法来获取,当然这是⼀种⽐较主流的判断⽅法
// 如果是想旧的⽅法兼容,可以使⽤下⾯作为判断条件,除IOS和PC以外,均使⽤旧的获取⽅式
/
/ !(navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) || !/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent))
/**
* ⽆论是旧的写法还是新的标准,思路都是通过设备信息,获取摄像头的视频流,通过转换变成blob的格式交给video的src
*/
if (!UserMedia) {
// 声明⼀个数组,⽤于装载设备媒体设备的相关信息,由于回调中sourceInfos对象中携带有所有媒体对象的相关信息
// 这⾥对信息进⾏遍历筛选,只选出摄像头的Id并保存在数组中
var exArray = [];
for (var i = 0; i < sourceInfos.length; ++i) {
if (sourceInfos[i].kind == 'videoinput') {
exArray.push(sourceInfos[i].deviceId);
}
}
// 通过navigator的getUserMedia获取摄像头的视频流,并在成功的回调中将视频流交给video
getMedia();
function getMedia() {
if (UserMedia) {
// 该⽅法可以传递3个参数,分别为获取媒体信息的配置,成功的回调函数和失败的回调函数
audio: false, // 表明是否获取⾳频
web浏览器在哪里打开
video: {  // 对视频信息进⾏配置
optional: [{
'sourceId': exArray[1] // 下标为0是前置摄像头,1为后置摄像头,所以PC不能进⼊该判断,否则画⾯会保持在第⼀帧不动
}]
},
}, successFunc, errorFunc); //success是获取成功的回调函数
}, successFunc, errorFunc); //success是获取成功的回调函数
} else {
alert('Native device media streaming (getUserMedia) not supported in this browser.');
}
}
// 这⾥是获取媒体信息成功的回调函数
function successFunc(stream) {
// 对FireFox进⾏兼容,这⾥对返回流数据的处理不同
if (SrcObject !== undefined) {
//Firefox中,SrcObject最初为null,⽽不是未定义的,我们可以靠这个来检测Firefox的⽀持            SrcObject = stream;
} else {
// ⼀般的浏览器需要使⽤createObjectURL对流数据进⾏处理,再交给video元素的src
video.src = window.URL && ateObjectURL(stream) || stream;
}
}
// 获取媒体信息失败的回调
function errorFunc(e) {
alert('Error!' + e);
}
} else {  // 当采⽤最新的标准⽅式获取视频时
// 这⾥对⽣成视频进⾏配置
var userMediaConstraints = {
audio: false, // 是否获取⾳频
video: {
facingMode: 'environment'  // 环境表⽰后置摄像头,使⽤user表⽰采⽤前置
}
}
/
/ 这⾥就采⽤新的⽅法来获取视频
video.srcObject = stream;
}).catch(function (error) {
alert(error.name + ssage)
});
}
}).catch(function(error) {
alert(error.name + ssage)
})
})();
</script>
</body>
</html>
  最后提供⼀个将视频全屏显⽰的⽅法,对于PC和要求不⾼的⼿机已经可以实现全屏
* {
margin: 0;
}
body {
overflow: hidden;
}
#video {
min-width: 100%;
min-height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
  在⼿机上,这个还有⼀点点横向滚动条,要想完全去掉,需要改动html,让video⾃动适⽤全屏的div
  html
<div id="wrapper">
<video id="video" autoplay playsinline></video>
</div>
  css
* {
margin: 0;
}
#wrapper {
width: 100%;
height: 100%;
position: absolute;  top: 0;
left: 0;
overflow: hidden; }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。