AngularJS中使用HTML5摄像头拍照

澳门新葡亰赌995577 3

本文由码农网 –
杨勇原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

此次demo使用chrome49调试测试

1. 项目背景

公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能。因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照。起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的。

澳门新葡亰赌995577 1

这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图:

澳门新葡亰赌995577 2

澳门新葡亰赌995577 3

前端在操作视频输入,音频输入,输出上一直是比较弱的,或者说很难进行相关的操作,经过我最近的一些研究发现,在PC上实际上是可以实现这一系列的功能的,其实现原理主要是得益于google的webRTC技术。

2. 如何调用摄像头

$scope.photoErr = false;
$scope.photoBtnDiable = true;
var mediaStream = null,track = null;

navigator.getMedia = (navigator.getUserMedia ||
                      navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
                      navigator.msGetUserMedia);
        if (navigator.getMedia) {
            navigator.getMedia(
           {
               video: true
           },
           // successCallback
           function (stream) {
               var s = window.URL.createObjectURL(stream);
               var video = document.getElementById('video');
               video.src = window.URL.createObjectURL(stream);
               mediaStream = stream;
               track = stream.getTracks()[0];
               $scope.photoBtnDiable = false;               $scope.$apply();
           },
           // errorCallback
           function (err) {
               $scope.errorPhoto();
               console.log("The following error occured:" + err);
           });
              } else {
            $scope.errorPhoto();
        }

代码解析:

navigator为浏览器对象,包含浏览器的信息,这里就是用这个对象打开摄像头。$scope为AndularJs语法。第一步声明navigator.getMedia来调用浏览器不同的打开摄像头函数,目前仅有getUserMedia、webkitGetUserMedia、mozGetUserMedia、msGetUserMedia四种方式分别对应通用浏览器、Google浏览器、火狐浏览器和IE浏览器,浏览器会自动判断调用哪一个函数。第二步是调用打开浏览器,包含三个参数,分别为需要使用的多媒体类型、获取成功返回的流数据处理函数以及操作失败返回错误消息处理函数。其中,使用时不仅可以设置视频还能设置使用麦克风,设置方式为:

{
      video: true,
      audio: true
}

调用成功即打开摄像头后返回视频流数据,我们可以将流数据设置到video标签在界面上实时显示图像。mediaStream用来记录获取到的流数据,track在Chrome浏览器中用来跟踪摄像头状态,这两个变量都能用来关闭摄像头。

什么是webRTC

WebRTC,名称源自网页即时通讯(英语:Web Real-Time
Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准[1][2][3]。(来自维基百科)

也就是说webRTC是让网页浏览器进行实时语音对话或者视频对话的一系列的解决方案。官方demo:

这个demo里面实际上功能非常多,关于调用摄像头我们主要关心的是这个demo,可是当大家把代码拉下来之后发现非常多东西,我在这里给大家简单的总结一下,并自己写上几个简单的demo,当然想要关心具体实现功能,或者代码的也可以看源码。

3. 拍照

$scope.snap = function () {
        var canvas = document.createElement('canvas');
            canvas.width = "400";
            canvas.height = "304";

            var ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, 400, 304);
            $scope.closeCamera();
            $uibModalInstance.close(canvas.toDataURL("image/png"));
};

拍照时需要使用到canvas标签,创建一个canvas标签,设置我们需要拍照的尺寸大小,通过drawImage函数将video当前的图像保存到canvas标签,最后将图像数据转换为base64数据返回并关闭摄像头,这样就完成了我们的拍照功能。这里的$uibModalInstance对象是我们项目中打开弹出层的一个对象,用来控制弹出层的显示。

如何在网页中调用摄像头

首先我们需要实现的就是在网页中调用到摄像头进行录制,假如没有摄像头的同学也可以去下载一个繁星伴奏,进行模拟,下载地址:

我们这里需要用到navigator.getUserMedia这个API,当然在chrome下需要使用兼容前缀即navigator.webkitGetUserMedia

代码如下:

<body>
    <video width="400" height="" id="video" autoplay="">
        <source src="myvideo.mp4" type="video/mp4"></source>
        <source src="myvideo.ogv" type="video/ogg"></source>
        <source src="myvideo.webm" type="video/webm"></source>
        <object width="" height="" type="application/x-shockwave-flash" data="myvideo.swf">
            <param name="movie" value="myvideo.swf" />
            <param name="flashvars" value="autostart=true&amp;file=myvideo.swf" />
        </object>
        当前浏览器不支持 video直接播放,点击这里下载视频: <a href="myvideo.webm">下载视频</a>
    </video>
</body>
<script type="text/javascript">     
    var constraints={video:true};   //设置参数LocalMediaStream
    var video_element=document.getElementById("video"); //
    if(navigator.getUserMedia){     //默认API
        navigator.getUserMedia(constraints)
        .then(function(stream) {
            console.info(stream);
               window.stream = stream; 
                video_element.srcObject = stream;
                video_element.src=URL.createObjectURL(stream);
             return navigator.mediaDevices.enumerateDevices();
          })
          .catch(errorCallback);
    }else if(navigator.webkitGetUserMedia){         //chrome兼容
        navigator.webkitGetUserMedia(constraints,function(stream){
            //成功获取后回调
            console.info(stream);
            window.stream = stream; 
            video_element.srcObject = stream;
            video_element.src=URL.createObjectURL(stream);
            return navigator.mediaDevices.enumerateDevices();
        },function(data){
            //失败回调
            console.info(data)
        });         
    }   
</script>

 

我们可以看下代码,HTML部分很简单
就是一个video标签,主要功能的实现在js中可以找到navigator.getUserMedia这个API,通过这个就可以调用当前摄像头,并且返回流信息。

澳门新葡亰赌995577,4. 如何关闭摄像头

$scope.closeCamera = function () {
            if (mediaStream != null) {
                if (mediaStream.stop) {
                    mediaStream.stop();
                }
                $scope.videosrc = "";
            }
            if (track != null) {
                if (track.stop) {
                    track.stop();
                }
            }
        }

正如前面所说,关闭摄像头的方式是通过mediaStream和track变量,只不过,track只能关闭Chrome浏览器中的摄像头,这也是Chrome 45版本以上关闭摄像头的方式。

关于navigator.getUserMedia

提示用户需要权限去使用像摄像头或麦克风之类的媒体设备,如果用户提供了这个权限。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图