Skip to content

WebRTC打开本地摄像头

更新日期: 2022-5-20
  • 2022-5-20 调整视频大小
  • 2022-5-17 更新js源
  • 2021-11-24 新建文档

本文使用WebRTC的功能,打开电脑上的摄像头,并且把摄像头预览到的图像显示出来。 纯网页实现,能支持除IE外的多数浏览器。手机浏览器也可用。

引入依赖

我们需要引入adapter-latest.js

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script> <!-- (1) -->

  1. 有可能因网络原因连接不到GitHub,开发时候请注意这点

这个WebRTC adapter曾是WebRTC中的一部分,但现在被移出来了。 我们会用到它提供的功能。

html

我们在界面上先摆放一些控件。

1
2
3
4
5
6
7
8
9
<div id="container">
    <video id="video-local" autoplay playsinline></video>
    <button id="showVideo">打开摄像头</button>
    <button id="stopVideo">关闭摄像头</button>
    <p>显示摄像头预览的内容,网页上由元素video来呈现。</p>
    <p>点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
    <div id="errorMsg"></div>
    <div id="tipMsg"></div>
</div>

  • video 用来显示预览的视频
  • 两个button用来控制开启和关闭
  • 再放几个显示信息的地方

js

先设置一下,我们只使用视频

1
2
3
4
const constraints = window.constraints = {
  audio: false,
  video: true
};

在网页上显示一些信息,便于调试。

function showErrMsg(msg, error) {
  const errorElement = document.querySelector('#errorMsg');
  errorElement.innerHTML += `<p>${msg}</p>`;
  if (typeof error !== 'undefined') {
    console.error(error);
  }
}

function showMsg(msg) {
    const msgEle = document.querySelector('#tipMsg');
    msgEle.innerHTML += `<p>-> ${msg}</p>`;
    console.log(msg);
}

完整代码在main.js中。css可自行定义。

打开摄像头

要打开摄像头,使用MediaDevices.getUserMedia()方法

async function openCamera(e) {
  try {
    showMsg('正在打开摄像头');
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    showMsg('获取到了stream');
    gotStream(stream);
    e.target.disabled = true;
  } catch (err) {
    onErr(err);
  }
MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。

如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException

方法的文档MediaDevices.getUserMedia()

显示视频

获取到stream后,让video显示视频

1
2
3
4
5
6
7
function gotStream(stream) {
  const videoEle = document.querySelector('video');
  const videoTracks = stream.getVideoTracks();
  showMsg(`正在使用的设备: ${videoTracks[0].label}`);
  window.stream = stream;
  videoEle.srcObject = stream;
}
document.querySelector('video')直接获取html上的video控件。 把stream直接交给videoEle.srcObject

停止视频流

要停止视频,我们可以从video元素入手,拿到stream,然后把里面的track停掉。

function stopVideo(e) {
    showMsg("停止视频");
    const videoElem = document.querySelector('video');
    const stream = videoElem.srcObject;

    document.querySelector('#showVideo').disabled = false; // 允许开启

    if(stream == null) {
        return;
    }
    const tracks = stream.getTracks();

    tracks.forEach(function(track) {
      track.stop();
    });
    videoElem.srcObject = null;
}
stream.getTracks()方法拿到所有的轨道(track),遍历一遍全部关掉。 最后,把videoElem.srcObject设置为null,它与前面的stream解除关联,方便将它释放。

参考 MediaStreamTrack-stop

小结

示例使用的WebRTC的功能。显示的是本地摄像头的视频,不涉及传输。拿到视频流后交给video来显示。 getUserMedia是示例中最关键的方法。以后的示例都会用到它。

参考

本文链接 - WebRTC打开本地摄像头

本文也发布在

掘金 华为云社区 cnblog 知乎 简书 csdn 头条


WebRTC系列

效果预览

完整的效果请参考 open-camera - an.rustfisher.com

以下是简易效果,打开摄像头


作者: rustfisher.com | rf.cs@foxmail.com
示例: AndroidTutorial Gitee, Tutorial Github
本文链接: https://www.an.rustfisher.com/webrtc/web-samples/getUserMedia-open-camera/
一家之言,仅当抛砖引玉。如有错漏,还请指出。如果喜欢本站的内容,还请支持作者。也可点击1次下方的链接(链接内容与本站无关),谢谢支持服务器