前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WEBRTC 实现浏览器拍照

WEBRTC 实现浏览器拍照

作者头像
wade
发布2023-09-01 09:09:40
2020
发布2023-09-01 09:09:40
举报
文章被收录于专栏:coding个人笔记coding个人笔记

最近的几个需求都涉及到了扫码和拍照之类的功能,扫码用的是插件 html5-qrcode,拍照就自己写了一下,没多少行代码。

用的是 WEBRTC 的 api 然后把视频流画到 canvas 里面,再保存成图片,直接上代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    *{
      margin: 0;
      padding: 0;
      list-style: none;
    }
  </style>
</head>
<body>
<div>
  <video id="cameraVideo" autoplay="true"></video>
</div>
<button onclick="takePhoto()">开始</button>
<button onclick="snapPhoto()">拍照</button>
<button onclick="closePhoto()">关闭</button>

<script>
  let mediaStream = null;
  var track = null;

  function takePhoto () {
    navigator.mediaDevices
      .getUserMedia({
        video: true,
      })
      .then(function (stream) {
        let video = document.getElementById('cameraVideo');
        video.srcObject = stream;
        mediaStream = stream;
        track = stream.getTracks()[0];
      })
      .catch(function (err) {
        console.log(err);
      });
  }

  function snapPhoto () {
    var canvas = document.createElement('canvas');
    let videoEl = document.getElementById('cameraVideo');
    let videoH = videoEl.videoHeight;
    let videoW = videoEl.videoWidth;
    canvas.width = videoW;
    canvas.height = videoH;
    var video = document.getElementById('cameraVideo');
    var ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, videoW, videoH);
    canvas.toBlob(function(blob){
      var file = new File([blob], Date.now().toString() + '.png', {
        type: "image/png",
        lastModified: Date.now()
      });
      download(Date.now().toString() + '.png', file);
    });
  }

  function closePhoto () {
    if (mediaStream !== null) {
      if (mediaStream.stop) {
          mediaStream.stop();
      }
    };
    if (track !== null) {
        if (track.stop) {
            track.stop();
        }
    };

    var video = document.getElementById('cameraVideo');
    video.src = "";
  }

  const download = (fileName, blob) => {
    const link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = fileName;
    link.click();
    link.remove();
    URL.revokeObjectURL(link.href);
  };
</script>
</body>
</html>

一开始用的是简写 navigator.getUserMedia,结果 ios 居然不行,后面 navigator.mediaDevices.getUserMedia 就可以了,也是神奇。

还有要注意,如果不想视频拍照的时候全屏(移动端),给 video 加上属性 webkit-playsinline playsinline x5-video-player-type="h5-page"

另外视频可以设置前置和后置摄像头,分辨率,video 是对象,user 是前置,environment 是后置,width/height 是分辨率,移动端可能还反着来,就是这个分辨率一直不知道是怎么可以设置全,因为拍照的框是固定的,所以很难设置的刚好,如果只是播放视频还好,通过判断分辨率然后用 css 控制 object-fit,是 cover 还是 contain,如果是 fill 就有肯能变形。

代码语言:javascript
复制
{
  facingMode: 'environment',
  width: { ideal: 720 },
  height: { ideal: 1280 },
}

要是有人对这个分辨率有很好的理解,求指教,毕竟现在的项目有可能要解决满框。

也可以到 GitHub 下载对应的代码:https://github.com/wade3po/demoCode

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 coding个人笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档