getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

  • A+
所属分类:HTML5
概览随着Firefox支持getUserMedia,三个主要的桌面浏览器能够实现无需使用插件即可从摄像头中获取数据。因为现在仍处于初期阶段,所以浏览器之间的实现略有不同。下面的例子展示如何应对这些不同,并用一个脚本来帮助你做这些繁重的工作,但是首先必须了解这三款浏览器都是怎么工作的。
getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

getUserMedia 是通过在about:config中将 media.peerconnection.enabled option 设置为 true 启用的.

开始编码时会遇到各种差异,不过没关系,现在就让我们一起来一步一步看怎么解决这些问题。成功使用getUserMedia将按如下步骤为大家一一介绍:

1. 一点HTML5小知识
2. 特征检测
3. 视频流
4. 准备就绪
5. 最后一点小提示
深吸一口气哦,好戏即将开始…

一点HTML5小知识

在这个简短的教程中,我们的主要任务是只是为了将一个动态图像显示在一个页面中。视频都是普通视频,所以第一步是在HTML文件中引入一个简单的<video>元素:

getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

就这样。没有控制,没有源码,什么都没有。

在JavaScript中,需要得到关联到<video>元素,我们可以这样做(或者用一个id):

getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

特征检测

在我们检查getUserMedia支持时事情就变得有趣起来。我们绝对不会使用不可靠的用户代理去做嗅探 – 绝不,我们将用检查navigator.getUserMedia对象这种最简单的方式来实现。它是在Firefox和Chrome对前缀中,所以在所有的浏览器中将其分配到一个共同的对象会非常的方便。比如为window.URL对象采用这种方式,以便稍后使用。

navigator.getUserMedia= navigator.getUserMedia|| navigator.webkitGetUserMedia|| navigator.mozGetUserMedia|| navigator.msGetUserMedia;window.URL= window.URL|| window.webkitURL|| window.mozURL|| window.msURL;

然后实际存在性的检查如下:

if(navigator.getUserMedia){// Call the getUserMedia method here}else{ console.log('Native device media streaming (getUserMedia) not supported in this browser.');// Display a friendly "sorry" message to the user.}

如果getUserMedia支持,我们需要为它传递三个参数 – 一个选项对象,一个成功的回调函数和一个错误回调函数。需要注意的是错误回调函数在Firefox是必须的,但在Opera和Chrome是可选的。选项参数是一个JSON风格的对象,指定是否要使用音频,视频或两者都将使用。下面的示例代码仅适用于视频:
navigator.getUserMedia({video:true}, successCallback, errorCallback);

使用摄像机请求时的对话框
Firefox中的对话框

getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

Chrome中的对话框
getUserMedia/WebRTC助力跨浏览器摄像头捕获影像
Opera中的对话框

getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

视频流

到目前为止,一切都很好,让我们看看接下来会发生什么。成功回调函数接收一个参数,包含摄像头的视频流,我们需要将该视频流发送到我们的<video>元素。为此,我们设定它的src属性,但有几件事情要牢记:

Firefox使用mozSrcObject的属性,而Opera和Chrome使用src属性。
Chrome使用createObjectURL的方法,而Firefox和Opera直接发送视频流。

在Firefox中,video.mozSrcObject最初为null,而不是未定义的,所以我们可以靠这个来检测Firefox的支持(hat tip to Florent)。一旦视频流知道去哪儿了,我们就可以告诉视频流播放了。
getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

准备就绪

基本工作准备完毕。添加一个简单的错误回调函数,我们就拥有了一个可以工作的跨浏览器的脚本,它看起来像这样:

getUserMedia/WebRTC助力跨浏览器摄像头捕获影像
(注:此为部分截图,源码看这里

在GitHub上获取
getUserMedia/WebRTC助力跨浏览器摄像头捕获影像
为了方便大家学习跨网络浏览器的方式访问getUserMedia,我们把一个可以工作的例子放在了GitHub上:GumWrapper

最后一个小提示

如果你想要使用照相机流做更炫的事情,比如捕获静止图像或添加奇炫的效果,你可能会希望将数据传输到在画布背景下。您可以使用drawImage()来实现,在这种情况下,你需要视频的尺寸。这些都可以通过的video.videoWidth和video.videoHeight属性来活动,但要小心 - 他们只当浏览器有这些跟视频流相关的信息时才能设置。这意味着你必须监听某些事件,然后才能获取这些属性。有如下相关的事件,它们总是按以下顺序触发:

1. play
2. loadedmetadata
3. loadeddata
4. playing

Video.play()方法被调用后,play事件被触发,但是在视频开始播放之前有可能会有轻微的延迟。这就是palying事件被触发的情况,但请注意,当流或视频播放时,它在Firefox中会多次触发。在此之前,有一些数据事件,首先是只对metadata,但是在Firefox中它并不包括视频尺寸。因此,最可靠的可侦听事件是loadeddata的事件 – 你肯定能知道视频流的宽度和高度。你可以这样编写代码:
getUserMedia/WebRTC助力跨浏览器摄像头捕获影像

顺便说一句,你也可以使用流的尺寸做进一步的错误检查,例如检查是否宽度和高度都大于0。这将避免出现某些问题,如用户的网络摄像头被破坏或根本就没有插上。

这样就大功告成啦。我敢肯定,随着技术的成熟,浏览器之间的差异会消失。在目前的情况下,上面的代码应该可以根据你的需要帮助您。

英文原文

weinxin
我的微信
欢迎来撩!!

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: