前言
最近在做一个小h5页面,通过手机摄像头获取视频图像通过video播放出来,发现两个问题。
1.前置摄像头成像时,左右颠倒(举右手,视频显示左手)
![](https://i-blog.csdnimg.cn/blog_migrate/0c42ddfe30577fcfb3712333850cadc8.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/6ea4dd33878a516c1f213bad3c2a41f8.png)
2.手机旋转成横屏时,人物头像倒立
![](https://i-blog.csdnimg.cn/blog_migrate/f657b8ea633e2b385b623744c20d6ee7.png)
会发现竖屏可能是视频图像的方向发生错误,横屏也是如此。所以我们解决就需要改变视频图像方向为主(水平翻转)。
方案:
1.直接转摄像头的方向(不可行)
2.修改视频流,从而修改图像方向(不可行)
3.直接修改video视图的方向(可行)
具体操作
前置摄像头的video视图水平翻转180度。
transform:rotateY(180deg);
因为后置摄像头的成像没有问题,所以当切换成后置摄像头时,要将video恢复成水平0度。
transform:rotateY(0deg);
正确成像如下:
![](https://i-blog.csdnimg.cn/blog_migrate/62d2b7ff750617f0bc4199fc3dee97f3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6bf888d83c556625ba01e602408668a4.png)
全部测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>摄像头成像</title>
</head>
<body style="text-align: center">
<video id="video" width="320" height="480" controls></video>
<div>
<button id="camera">打开/切换摄像头</button>
<button id="stop">关闭摄像头</button>
</div>
<script>
//访问用户媒体设备的兼容方法
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');
function success(stream) {
//兼容webkit核心浏览器
let CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
console.log(stream);
//video.src = CompatibleURL.createObjectURL(stream);
video.srcObject = stream;
video.play();
}
function error(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
}
function close() { //关闭摄像头数据流
if (video.srcObject) {
try {
var tracks = video.srcObject.getTracks();
for (var track of tracks) {
track.stop();
}
} catch (e) {
alert(e);
}
}
}
document.getElementById('stop').addEventListener('click', close);
//设备摄像头数据获取
var device_videos = [];
var device_videos_index = 0;
navigator.mediaDevices.enumerateDevices().then(function (devices) {
devices.forEach(function (dv) {
var kind = dv.kind;
if (kind.match(/^video.*/)) {
device_videos.push(dv.deviceId);
}
});
});
var isQian=false;//是前置摄像头
document.getElementById('camera').addEventListener('click', function () {
if (isQian) {
isQian = false;
document.getElementById("video").style.cssText = "width:320px; height:480px;transform:rotateY(0deg);"
}else{
isQian = true;
document.getElementById("video").style.cssText = "width:320px; height:480px;transform:rotateY(180deg);"
}
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
//调用用户媒体设备, 访问摄像头
close();
getUserMedia({ video: { width: 320, height: 480, deviceId: device_videos[device_videos_index++%device_videos.length] } }, success, error);
} else {
alert('不支持访问用户媒体');
}
})
</script>
</body>
</html>
延伸
当通过h5的方式来实现视频对讲时:
1.自身终端为前置摄像头时自身视频视图需要水平翻转180度,当为后置摄像头时自身视频视图不需要翻转。
2.对方视频视图为前置摄像头采集时,需要将对方视频视图水平翻转180度,当对方视频视图采集为后置摄像头时不需要翻转。