An Introduction to the getUserMedia API 机翻
原文:An Introduction to the getUserMedia API - SitePoint
什么是 getUserMedia API
getUserMedia API 提供对来自本地设备的多媒体流(视频、音频或两者)的访问。这个 API 有几个用例。第一个显然是实时通信,但我们也可以用它来录制教程或在线课程的课程。另一个有趣的用例是监视您的家庭或工作场所。就其本身而言,此 API 只能获取音频和视频,不能发送数据或将其存储在文件中。例如,要进行完整的工作聊天,我们需要通过 Internet 发送数据。这可以使用RTCPeerConnection API来完成。要存储数据,我们可以使用MediaStreamRecorder API。
getUserMedia API 对于开发人员和用户来说都很棒。开发人员现在可以通过单个函数调用访问音频和视频源,而用户无需安装额外的软件。从用户的角度来看,这也意味着开始使用该功能的时间减少,也意味着非技术人员对该软件的使用增加。
尽管 getUserMedia API 已经存在了一段时间,但截至 2013 年 12 月 30日,它仍然是 W3C 工作草案。因此,规格可能会受到一些变化的影响。API 只公开了一个getUserMedia()
属于该window.navigator
对象的方法。该方法接受一个约束对象、一个成功回调和一个失败回调作为其参数。constraints
参数是具有属性audio
和之一或两者的对象video
。这些属性的值是一个布尔值,其中true
表示请求流(音频或视频),false
而不请求流。因此,要同时请求音频和视频,请传递以下对象。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-">{
video: true,
audio: true
}</code></span></span>
或者,该值可以是一个Constraints对象。这种类型的对象允许我们对请求的流有更多的控制。事实上,我们可以选择以高分辨率检索视频源,例如 1280×720,或低分辨率,例如 320×180。每个Constraints
对象包含两个属性,mandatory
和optional
。mandatory
是一个对象,它指定了 UA 必须满足或调用 errorCallback 的一组约束。 optional
, 是一个对象数组,它指定了 UA 应该尝试满足的约束集,但如果不能满足它们可能会忽略。
假设我们想要用户的音频和视频,其中视频必须至少具有高分辨率并且帧速率为 30。此外,如果可用,我们希望视频的帧速率为 60。执行此任务,我们必须传递以下对象。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-">{
video: {
mandatory: {
minWidth: 1280,
minHeight: 720,
minFrameRate: 30
},
optional: [
{ minFrameRate: 60 }
]
},
audio: true
}</code></span></span>
您可以在规格中找到有关可用属性的更多信息。
的另外两个参数getUserMedia()
只是分别在成功或失败时调用的两个回调。成功时,将检索到的流传递给回调。错误回调传递了一个MediaError对象,其中包含有关发生的错误的信息。
浏览器兼容性
对 getUserMedia API 的支持在桌面上是不错的,但在移动设备上却很差。此外,大多数支持它的浏览器,仍然有供应商前缀的版本。目前,实现 API 的桌面浏览器是 Chrome 21+(-webkit 前缀)、Firefox 17+(-moz 前缀)和 Opera 12+(版本 15 到 17 不支持),但在旧版本中存在一些问题。在移动浏览器上,只有 Chrome 21+(-webkit 前缀)和 Opera 12+(-webkit 版本 16 的前缀)支持 API。另请注意,如果通过file://
Chrome 中的协议打开包含使用此 API 的说明的页面,它将无法工作。
Opera 的案例非常有趣,值得一提。该浏览器实现了 API,但由于(对我而言)未知的原因,在版本 15 中切换到 Blink 渲染引擎后,他们不再支持它。最后,API 支持在 18 版本中恢复。似乎还不够,Opera 18 也是第一个支持音频流的版本。
也就是说,由于有一个名为getUserMedia.js的填充程序,我们可以忽略兼容性问题。后者将测试浏览器,如果 API 未实现,则回退到 Flash。
演示
在本节中,我将向您展示一个基本演示,以便您了解 getUserMedia API 的工作原理并具体了解其参数。该演示的目标是创建一个“镜子”,即从网络摄像头和麦克风捕获的所有内容都将通过屏幕和音频扬声器进行流式传输。我们将询问用户访问这两个多媒体流的权限,然后使用 HTML5video
元素输出它们。标记非常简单。除了video
元素之外,我们还有两个按钮:一个开始执行,一个停止执行。
关于脚本部分,我们首先测试浏览器支持。如果 API 不受支持,我们会显示消息“API not supported”,并禁用这两个按钮。如果浏览器支持 getUserMedia API,我们将监听器附加到click
按钮的事件。如果单击“播放演示”按钮,我们会测试是否由于上一节中描述的问题而处理的是旧版本的 Opera。然后,我们从用户的设备请求音频和视频数据。如果请求成功,我们使用video
元素流式传输数据;否则,我们会显示控制台上发生的错误。“停止演示”按钮会导致视频暂停并停止流。
此处提供了以下代码的现场演示。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-"><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>getUserMedia Demo</title>
<style>
body
{
max-width: 500px;
margin: 2em auto;
font-size: 20px;
}
h1
{
text-align: center;
}
.buttons-wrapper
{
text-align: center;
}
.hidden
{
display: none;
}
#video
{
display: block;
width: 100%;
}
.button-demo
{
padding: 0.5em;
display: inline-block;
margin: 1em auto;
}
.author
{
display: block;
margin-top: 1em;
}
</style>
</head>
<body>
<h1>getUserMedia API</h1>
<video id="video" autoplay="autoplay" controls="true"></video>
<div class="buttons-wrapper">
<button id="button-play-gum" class="button-demo" href="#">Play demo</button>
<button id="button-stop-gum" class="button-demo" href="#">Stop demo</button>
</div>
<span id="gum-unsupported" class="hidden">API not supported</span>
<span id="gum-partially-supported" class="hidden">API partially supported (video only)</span>
<script>
var videoStream = null;
var video = document.getElementById("video");
// Test browser support
window.navigator = window.navigator || {};
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
null;
if (navigator.getUserMedia === null) {
document.getElementById('gum-unsupported').classList.remove('hidden');
document.getElementById('button-play-gum').setAttribute('disabled', 'disabled');
document.getElementById('button-stop-gum').setAttribute('disabled', 'disabled');
} else {
// Opera <= 12.16 accepts the direct stream.
// More on this here: http://dev.opera.com/articles/view/playing-with-html5-video-and-getusermedia-support/
var createSrc = window.URL ? window.URL.createObjectURL : function(stream) {return stream;};
// Opera <= 12.16 support video only.
var audioContext = window.AudioContext ||
window.webkitAudioContext ||
null;
if (audioContext === null) {
document.getElementById('gum-partially-supported').classList.remove('hidden');
}
document.getElementById('button-play-gum').addEventListener('click', function() {
// Capture user's audio and video source
navigator.getUserMedia({
video: true,
audio: true
},
function(stream) {
videoStream = stream;
// Stream the data
video.src = createSrc(stream);
video.play();
},
function(error) {
console.log("Video capture error: ", error.code);
});
});
document.getElementById('button-stop-gum').addEventListener('click', function() {
// Pause the video
video.pause();
// Stop the stream
videoStream.stop();
});
}
</script>
</body>
</html></code></span></span>
结论
本文向您介绍了 WebRTC 项目,这是近年来最令人兴奋的 Web 项目之一。特别是,本文讨论了 getUserMedia API。仅使用浏览器和很少的代码行来创建实时通信系统的可能性非常好,并带来了很多新的机会。
正如我们所见,getUserMedia API 简单但非常灵活。它只公开了一个方法,但它的第一个参数constraints
允许我们要求音频和视频流更适合我们的应用程序的需求。浏览器之间的兼容性不是很广泛,但正在增加,这是个好消息!为了更好地理解本文中的概念,不要忘记使用提供的演示。最后一点,我强烈建议您尝试更改代码以执行某些任务,例如应用 CSS 过滤器来更改视频流的显示方式。