WebRTC 之 MediaStream: 用你的浏览器拍照

概述

先看一下效果,你可以在这里亲自动手试试 https://www.fanyamin.com/webrtc/examples/media_stream.html

WebRTC 中对媒体流 Media Stream 做了内置的支持,可以从电脑的摄像头,麦克风中捕获音频或视频流,并在 HTML5 所支持的

  • MediaStream 代表音频或视频数据流, 一个 MediaStream包含零个或多个 MediaStreamTrack ,

WebRTC 标准中对 MediaStream 对象有如下定义

interface MediaStream : EventTarget {
  constructor();
  constructor(MediaStream stream);
  constructor(sequence tracks);
  readonly attribute DOMString id;
  sequence getAudioTracks();
  sequence getVideoTracks();
  sequence getTracks();
  MediaStreamTrack? getTrackById(DOMString trackId);
  undefined addTrack(MediaStreamTrack track);
  undefined removeTrack(MediaStreamTrack track);
  MediaStream clone();
  readonly attribute boolean active;
  attribute EventHandler onaddtrack;
  attribute EventHandler onremovetrack;
};
  • MediaStreamTrack 代表各种 audio 或 video track, 一个 MediaStreamTrack 包含一个或多个 Channels .
interface MediaStreamTrack : EventTarget {
  readonly attribute DOMString kind;
  readonly attribute DOMString id;
  readonly attribute DOMString label;
  attribute boolean enabled;
  readonly attribute boolean muted;
  attribute EventHandler onmute;
  attribute EventHandler onunmute;
  readonly attribute MediaStreamTrackState readyState;
  attribute EventHandler onended;
  MediaStreamTrack clone();
  undefined stop();
  MediaTrackCapabilities getCapabilities();
  MediaTrackConstraints getConstraints();
  MediaTrackSettings getSettings();
  Promise applyConstraints(optional MediaTrackConstraints constraints = {});
};

Media Track 有 liveended 两种状态, 还支持如下设置

dictionary MediaTrackSettings {
  long width;
  long height;
  double aspectRatio;
  double frameRate;
  DOMString facingMode;
  DOMString resizeMode;
  long sampleRate;
  long sampleSize;
  boolean echoCancellation;
  boolean autoGainControl;
  boolean noiseSuppression;
  double latency;
  long channelCount;
  DOMString deviceId;
  DOMString groupId;
};
  • Channel 代表媒体流的最小单元, 例如音频信号关联到一个给定的 Speaker , 如立体声道的左右声道.

MediaStream对象具有单个输入和单个输出。 由getUserMedia() 方法生成的MediaStream对象称为本地对象,其输入之一是用户的摄像机或麦克风。

非本地MediaStream可能表示为媒体元素(例如

MediaStream对象的输出链接到使用者。 它可以是媒体元素,例如

MediaStream

API

var promise = navigator.mediaDevices.getUserMedia(constraints);

基本用法

async function getMedia(constraints) {
  let stream = null;

  try {
    stream = await navigator.mediaDevices.getUserMedia(constraints);
    /* use the stream */
  } catch(err) {
    /* handle the error */
  }
}
// or not use promise
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* use the stream */
})
.catch(function(err) {
  /* handle the error */
});

实例

开始提到的实例怎么实现呢,其实很简单

1)先创建一个 media_stream.html







 WebRTC Examples




















Click the button to open, close camera or take snapshot



  1. 创建 media_stream_demo.js
'use strict';

// Put variables in global scope to make them available to the browser console.


function handleSuccess(stream) {
  const video = document.querySelector('video');
  const videoTracks = stream.getVideoTracks();
  console.log('Got stream with constraints:', constraints);
  console.log(`Using video device: ${videoTracks[0].label}`);
  window.stream = stream; // make variable available to browser console
  video.srcObject = stream;
}

function handleError(error) {
  if (error.name === 'ConstraintNotSatisfiedError') {
    const v = constraints.video;
    errorMsg(`The resolution ${v.width.exact}x${v.height.exact} px is not supported by your device.`);
  } else if (error.name === 'PermissionDeniedError') {
    errorMsg('Permissions have not been granted to use your camera and ' +
      'microphone, you need to allow the page access to your devices in ' +
      'order for the demo to work.');
  }
  errorMsg(`getUserMedia error: ${error.name}`, error);
}

function errorMsg(msg, error) {
  const errorElement = document.querySelector('#logDiv');
  errorElement.innerHTML += `

${msg}

`; if (typeof error !== 'undefined') { console.error(error); } } async function openCamera(e, constraints) { try { const stream = await navigator.mediaDevices.getUserMedia(constraints); handleSuccess(stream); e.target.disabled = true; document.querySelector('#close').disabled = false; } catch (ex) { handleError(ex); } } function closeCamera(e) { const videoElem = document.querySelector('video'); const stream = videoElem.srcObject; const tracks = stream.getTracks(); e.target.disabled = true; document.querySelector('#open').disabled = false; tracks.forEach(function(track) { track.stop(); }); videoElem.srcObject = null; } async function takeSnapshot(e) { console.log("take snapshot"); try { const video = document.querySelector('video'); const canvas = window.canvas = document.querySelector('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); } catch (ex) { handleError(ex); } }
  1. 点击 "Oper Camera" 来打开摄像头,点击 “Take Snapshot” 来拍摄快照

  2. 可以自己动手试试,通过选择 "resolution" 来调整 getUserMedia 的 Contraints

  3. 可以自己动手试试,通过更改 "Filter" 来为摄像头捕捉的视频添加滤镜。

参考资料

  • https://webrtc.github.io/samples/
  • https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

你可能感兴趣的:(WebRTC 之 MediaStream: 用你的浏览器拍照)