媒体模型

浏览器提供了从源(sources)到接收器(sinks)的媒体管道(pipeline)。 在浏览器中,接收器是 <img><video><audio> 标记。 来源可以是物理网络摄像头,麦克风,来自用户硬盘驱动器的本地视频或音频文件,网络资源或静态图像。 这些来源产生的媒体通常不会随时间变化。 这些源可以被认为是静态的。 向用户显示此类源的接收器(实际标签本身)具有用于控制源内容的各种控件。

getUserMedia() API方法添加了动态源,例如麦克风和相机。 这些来源的特性可能会根据应用需求而变化,这些来源本质上可以被认为是动态的。

媒体约束

约束是一项可选功能,用于限制 MediaStream 轨道源上允许的可变性范围。约束通过 Constrainable 接口在轨道上公开,该接口包括用于动态更改约束的 API

getUserMedia() 调用还允许在首次获取轨道时应用一组初始约束(例如,设置视频分辨率的值)

约束的核心概念是一种功能,它由对象的属性或特征以及可能的值集组成,可以将值指定为范围或枚举。

约束存储在 track 对象上,而不是对象资源。每个轨道都可以选择使用约束进行初始化。另外,可以在初始化之后通过专用的约束 API 添加约束。

约束可以是可选的或强制的。可选约束由有序列表表示,而强制约束与无序集合相关。

这样做是为了在发布 API 的最终版本之前为更多约束提供支持。约束包括高宽比,面向照相机的模式(正面或背面),音频和视频帧率,视频高度和宽度等等。

使用约束

在本节中,我们将快速了解如何使用 getUserMedia() 调用获取轨道时如何应用初始约束集。

::: danger WebRTC 浏览器中的 getUserMedia() 约束支持

目前仅在 Chrome 中支持 getUserMedia() 约束。 本节中的示例将假定您使用此浏览器。

:::

首先,在 例2-3 中构建HTML页面。

例2-3 播放和约束:在 HTML 页面

  1. <!DOCTYPE html>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  3. "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <title>getUserMedia() and constraints</title>
  7. </head>
  8. <body>
  9. <div id="mainDiv">
  10. <h1><code>getUserMedia()</code>: playing with video constraints</h1>
  11. <p>Click one of the below buttons to change video resolution...</p>
  12. <div id="buttons">
  13. <button id="qvga">320x240</button>
  14. <button id="vga">640x480</button>
  15. <button id="hd">1280x960</button>
  16. </div>
  17. <p id="dimensions"></p>
  18. <video autoplay></video>
  19. <script src="js/getUserMedia_constraints.js"></script>
  20. </div>
  21. </body>
  22. </html>

从 例2-3 中的代码片段和 图2-7 中的快照都可以看到,该页面包含三个按钮,每个按钮与以特定分辨率(从低分辨率到高清视频)表示的本地视频流相关联

图2-7

图2-7 一个简单的 HTML 页面,显示 Chrome 中约束的使用

例2-4 显示了用于获取本地视频流并明确定义的分辨率添加到网页的 JavaScript 代码

例2-4 播放约束: getUserMedia_constraints.js 文件

  1. // Define local variables associated with video resolution selection
  2. // buttons in the HTML page
  3. var vga Button = document.querySelector("button#vga");
  4. var qvgaButton = document.querySelector("button#qvga");
  5. var hdButton = document.querySelector("button#hd");
  6. // Video element in the HTML5 pagevar
  7. video = document.querySelector("video");
  8. // The local MediaStream to play with
  9. var stream;
  10. // Look after different browser vendors' ways of calling the
  11. // getUserMedia() API method:
  12. navigator.getUserMedia = navigator.getUserMedia ||
  13. navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
  14. // Callback to be called in case of success...
  15. function successCallback(gotStream) {
  16. // Make the stream available to the console for introspection
  17. window.stream = gotStream;
  18. // Attach the returned stream to the <video> element
  19. // in the HTML page
  20. video.src = window.URL.createObjectURL(stream);
  21. // Start playing video
  22. video.play();
  23. }
  24. // Callback to be called in case of failure...
  25. function errorCallback(error){
  26. console.log("navigator.getUserMedia error: ", error);
  27. }
  28. // Constraints object for low resolution video
  29. var qvgaConstraints = {
  30. video: {
  31. mandatory: {
  32. maxWidth: 320,
  33. maxHeight: 240
  34. }
  35. }
  36. };
  37. // Constraints object for standard resolution video
  38. var vgaConstraints = {
  39. video: {
  40. mandatory: {
  41. maxWidth: 640,
  42. maxHeight: 480
  43. }
  44. }
  45. };
  46. // Constraints object for high resolution video
  47. var hdConstraints = {
  48. video: {
  49. mandatory: {
  50. minWidth: 1280,
  51. minHeight: 960
  52. }
  53. }
  54. };
  55. // Associate actions with buttons:
  56. qvgaButton.onclick = function() {
  57. getMedia(qvgaConstraints)
  58. };
  59. vgaButton.onclick = function() {
  60. getMedia(vgaConstraints)
  61. };
  62. hdButton.onclick = function() {
  63. getMedia(hdConstraints)
  64. };
  65. // Simple wrapper for getUserMedia() with constraints object as
  66. // an input parameter
  67. function getMedia(constraints) {
  68. if (!!stream) {
  69. video.src = null;
  70. stream.stop();
  71. }
  72. navigator.getUserMedia(constraints, successCallback, errorCallback);
  73. }

例2-4 中的代码非常简单。 核心部分与约束对象的正确定义有关,每个约束对象都可以作为输入参数传递给 getUserMedia() 函数。 其中包含的三个样本对象只是简单地指出,视频应视为强制性的,并根据视频的宽度和高度的下限进一步指定分辨率。 为了使读者了解其含义,图2-8 和 图2-9 分别显示了320×240 和 640×480 的分辨率流。

图2-8 在 Chrome 中显示 320×240 分辨率的视频

图2-9 在 Chrome 中显示 640×480 分辨率的视频