Skip to content

WebRTC - part2(用你的摄像头来传输视频) #16

@EmberYu

Description

@EmberYu

WebRTC - part2(用你的摄像头来传输视频)

本文是笔者自己对https://codelabs.developers.google.com/codelabs/webrtc-web/#0的翻译版本,希望可以帮到各位理解WebRTC。如果有翻译不当之处,请参照原文
源码地址 git clone https://github.com/googlecodelabs/webrtc-web

这章你会学到

  • 从你的摄像头获取video stream
  • 操作stream回放
  • 使用CSS和SVG来操作视频

HTML代码

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <video autoplay playsinline></video>

  <script src="js/main.js"></script>

</body>

</html>

javascript代码

'use strict';

// On this codelab, you will be streaming only video (video: true).
const mediaStreamConstraints = {
  video: true,
};

// Video element where stream will be placed.
const localVideo = document.querySelector('video');

// Local stream that will be reproduced on the video.
let localStream;

// Handles success by adding the MediaStream to the video element.
function gotLocalMediaStream(mediaStream) {
  localStream = mediaStream;
  localVideo.srcObject = mediaStream;
}

// Handles error by logging a message to the console with the error message.
function handleLocalMediaStreamError(error) {
  console.log('navigator.getUserMedia error: ', error);
}

// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);

运行一下吧

建立一个本地服务器(可以使用http-server或者live-server),然后在浏览器中打开index.html,你会看到如下图的样子

注意Web RTC只能在本地环境或者HTTPS下才能启用

背后的原理

随着用户调用getUserMedia(),浏览器会向用户请求授权来访问系统的摄像头(同一个域名只有在第一次请求摄像头时才会发起请求)。如果授权成功,会返回一个MediaStream,可以通过媒体元素设置srcObject来使用。

navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
}
function gotLocalMediaStream(mediaStream) {
  localVideo.srcObject = mediaStream;
}

constraints参数允许你指定需要的媒体类型,在这个案例中,只捕获了视频,因为音频默认是禁用的(也可以通过配置audio: true打开音频捕获);
constraints参数同样也可以指定额外的参数,例如视频解析度

const hdConstraints = {
  video: {
    width: {
      min: 1280
    },
    height: {
      min: 720
    }
  }
}

你可以在这里找到所有的constraint类型,但是不是所有的设置都被所有浏览器支持,如果你的设置当前摄像头不支持,那么getUserMedia()会reject一个OverconstrainedError的状态,并且用户不会接收到访问摄像头的授权通知。
如果getUserMedia()调用成功,那么把通过摄像头返回的视频流设置为一个video标签的源即可播放

function gotLocalMediaStream(mediaStream) {
  localVideo.srcObject = mediaStream;
}

额外拓展

  • 示例代码中的localStream为全局变量,所以你可以在控制台中打印出来,看看它的数据格式以及包含的方法。
  • 尝试调用localStream.getVideoTracks(),看看返回值是什么
  • 常用调用localStream.getVideoTracks()[0].stop(),看看会发生什么
  • contraints对象的值改为{audio: true, video: true},看看会发生什么?
  • video元素的大小是多少?你如何通过Javascript获得video的原始大小,用Chrome开发工具审查一下
  • 试着将下面的css过滤器加到video元素上
video {
  filter: blur(4px) invert(1) opacity(0.5);
}
  • 试试SVG过滤器
video {
   filter: hue-rotate(180deg) saturate(200%);
 }

总结

这一样我们学会了

  • 从你的摄像头中获取video
  • 设置媒体的constraints
  • 给video元素增加CSS 过滤器(filter)
    完整的代码在git中的step-01文件夹下

提示

  • 不要忘记给video元素设置autoplay属性,不然你只能看到视频的一帧!
  • getUserMedia()的constraints有很多种配置,看一下demo你会发现有很多有趣的WebRTC案例

最佳实践

  • 确保video元素不会溢出它的容器,我们需要设置一个合适的widthmax-width。浏览器将会自动计算它的高度

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions