乐趣区

关于html5:getUserMedia-获取相机信息

js 获取相机信息,并输入到 video,同时绘制到 canvas 上,性能实现如下:

<!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>Demo</title>
<style>

  body {margin: 0;}
.container {
    height: 150px;
    background: #f4f4f4;
}
input {
    margin: 20px;
    display: inline-block;
}
video {
    position: fixed;
    top: 30%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: none;
}
#canvas2 {
    position: fixed;
    top: 60%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: none;
}

</style>
<!– vconsole 引入 –>
<script src=”https://unpkg.com/vconsole/dist/vconsole.min.js”></script>
<script type=”text/javascript”>

  new VConsole()

</script>
</head>

<body>
<div class=”container”>
<input type=”button” title=” 开启摄像头 ” value=” 开启摄像头 ” muted onclick=”getMedia();” />

<input type=”button” title=” 切换摄像头 ” value=” 切换摄像头 ” muted onclick=”changeMode();” />

<video

  height="120px"
  autoplay="autoplay"
  x5-video-player-type="h5-page"
  playsinline="true"
  webkit-playsinline="true"
  x5-video-ignore-metadata="false"
  x5-video-player-fullscreen="false"
  x5-video-player-orientation="landscape"

</video>
<!– <input type=”button” title=” 视频 ” value=” 视频绘制 ” onclick=”getVideo();” />
–>
<canvas id=”canvas2″></canvas>
</div>
<script>

// 老的浏览器可能基本没有实现 mediaDevices,所以咱们能够先设置一个空的对象
if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {};
}

// 一些浏览器局部反对 mediaDevices。咱们不能间接给对象设置 getUserMedia
// 因为这样可能会笼罩已有的属性。这里咱们只会在没有 getUserMedia 属性的时候增加它。if (navigator.mediaDevices.getUserMedia === undefined) {navigator.mediaDevices.getUserMedia = function(constraints) {

        // 首先,如果有 getUserMedia 的话,就取得它
        var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

        // 一些浏览器基本没实现它 - 那么就返回一个 error 到 promise 的 reject 来放弃一个对立的接口
        if (!getUserMedia) {return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
        }

        // 否则,为老的 navigator.getUserMedia 办法包裹一个 Promise
        return new Promise(function(resolve, reject) {getUserMedia.call(navigator, constraints, resolve, reject);
        });
    }
}

var video = document.querySelector('video');
var audio, audioType;
var canvas2 = document.getElementById('canvas2');
var context2 = canvas2.getContext('2d');
var mode = 'user'
var streamData

function getMedia() {if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({
            'video': {
                frameRate: {
                    ideal: 10,
                    max: 15
                },
                facingMode: mode
            },
            'audio':false
        }).then(successFunc).catch(errorFunc)
    }
    else {alert('Native device media streaming (getUserMedia) not supported in this browser.');
    }
}

function successFunc(stream) {
    streamData = stream
    if (video.mozSrcObject !== undefined) {
        //Firefox 中,video.mozSrcObject 最后为 null,而不是未定义的,咱们能够靠这个来检测 Firefox 的反对
        video.mozSrcObject = stream;
    } else if ('srcObject' in video) {console.log('srcObject')
        video.srcObject = stream;
    } else {console.log('src')
        // 避免在新的浏览器里应用它,应为它曾经不再反对了
        video.src = window.URL.createObjectURL(stream);
    }

    video.style.display = 'block';
    getVideo()

    video.onloadedmetadata = function(e) {console.log('onloadedmetadata')
        // video.play();};

    // 音频
    // audio = new Audio();
    // audioType = getAudioType(audio);
    // if (audioType) {
    //     audio.src = 'polaroid.' + audioType;
    //     audio.play();
    // }
}

function errorFunc(e) {console.log('获取资源谬误', e)
}

// 切换摄像头
function changeMode() {
    mode = mode === 'user' ? 'environment' : 'user'
    streamData.getTracks()[0].stop()
    getMedia()}

// 获取音频格式
function getAudioType(element) {if (element.canPlayType) {if (element.canPlayType('audio/mp4; codecs="mp4a.40.5"') !=='') {return ('aac');
        } else if (element.canPlayType('audio/ogg; codecs="vorbis"') !=='') {return ("ogg");
        }
    }
    return false;
}
// 视频
function getVideo() {drawVideoAtCanvas(video, context2);
}

// 将视频帧绘制到 Canvas 对象上,Canvas 每 60ms 切换帧,造成肉眼视频成果
function drawVideoAtCanvas(video, context2) {
    canvas2.style.display = 'block';
    window.setInterval(function () {var w = parseInt(getComputedStyle(video).width)
        var h = parseInt(getComputedStyle(video).height)
        var x = (parseInt(getComputedStyle(canvas2).width) - w) / 2
        context2.drawImage(video, x, 0, w, h);
    }, 60);
}

</script>
</body>

</html>

踩坑指南:
1、iOS 不反对裁剪绘制到 canvas 上
2、兼容性如下:
android: 局部浏览器只能关上前置摄像头,反对双向的浏览器切换摄像头前须要先将原 mideaStream 暂停;
ios:初始化和切换均可实现;

退出移动版