123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /**
- * MediaStream ImageCapture polyfill
- *
- * @license
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- export let ImageCapture = window.ImageCapture;
- if (typeof ImageCapture === 'undefined') {
- ImageCapture = class {
- /**
- * TODO https://www.w3.org/TR/image-capture/#constructors
- *
- * @param {MediaStreamTrack} videoStreamTrack - A MediaStreamTrack of the 'video' kind
- */
- constructor(videoStreamTrack) {
- if (videoStreamTrack.kind !== 'video')
- throw new DOMException('NotSupportedError');
- this._videoStreamTrack = videoStreamTrack;
- if (!('readyState' in this._videoStreamTrack)) {
- // Polyfill for Firefox
- this._videoStreamTrack.readyState = 'live';
- }
- // MediaStream constructor not available until Chrome 55 - https://www.chromestatus.com/feature/5912172546752512
- this._previewStream = new MediaStream([videoStreamTrack]);
- this.videoElement = document.createElement('video');
- this.videoElementPlaying = new Promise(resolve => {
- this.videoElement.addEventListener('playing', resolve);
- });
- if (HTMLMediaElement) {
- this.videoElement.srcObject = this._previewStream; // Safari 11 doesn't allow use of createObjectURL for MediaStream
- }
- else {
- this.videoElement.src = URL.createObjectURL(this._previewStream);
- }
- this.videoElement.muted = true;
- this.videoElement.setAttribute('playsinline', ''); // Required by Safari on iOS 11. See https://webkit.org/blog/6784
- this.videoElement.play();
- this.canvasElement = document.createElement('canvas');
- // TODO Firefox has https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
- this.canvas2dContext = this.canvasElement.getContext('2d');
- }
- /**
- * https://w3c.github.io/mediacapture-image/index.html#dom-imagecapture-videostreamtrack
- * @return {MediaStreamTrack} The MediaStreamTrack passed into the constructor
- */
- get videoStreamTrack() {
- return this._videoStreamTrack;
- }
- /**
- * Implements https://www.w3.org/TR/image-capture/#dom-imagecapture-getphotocapabilities
- * @return {Promise<PhotoCapabilities>} Fulfilled promise with
- * [PhotoCapabilities](https://www.w3.org/TR/image-capture/#idl-def-photocapabilities)
- * object on success, rejected promise on failure
- */
- getPhotoCapabilities() {
- return new Promise(function executorGPC(resolve, reject) {
- // TODO see https://github.com/w3c/mediacapture-image/issues/97
- const MediaSettingsRange = {
- current: 0, min: 0, max: 0,
- };
- resolve({
- exposureCompensation: MediaSettingsRange,
- exposureMode: 'none',
- fillLightMode: ['none'],
- focusMode: 'none',
- imageHeight: MediaSettingsRange,
- imageWidth: MediaSettingsRange,
- iso: MediaSettingsRange,
- redEyeReduction: false,
- whiteBalanceMode: 'none',
- zoom: MediaSettingsRange,
- });
- reject(new DOMException('OperationError'));
- });
- }
- /**
- * Implements https://www.w3.org/TR/image-capture/#dom-imagecapture-setoptions
- * @param {Object} photoSettings - Photo settings dictionary, https://www.w3.org/TR/image-capture/#idl-def-photosettings
- * @return {Promise<void>} Fulfilled promise on success, rejected promise on failure
- */
- setOptions(_photoSettings = {}) {
- return new Promise(function executorSO(_resolve, _reject) {
- // TODO
- });
- }
- /**
- * TODO
- * Implements https://www.w3.org/TR/image-capture/#dom-imagecapture-takephoto
- * @return {Promise<Blob>} Fulfilled promise with [Blob](https://www.w3.org/TR/FileAPI/#blob)
- * argument on success; rejected promise on failure
- */
- takePhoto() {
- const self = this;
- return new Promise(function executorTP(resolve, reject) {
- // `If the readyState of the MediaStreamTrack provided in the constructor is not live,
- // return a promise rejected with a new DOMException whose name is "InvalidStateError".`
- if (self._videoStreamTrack.readyState !== 'live') {
- return reject(new DOMException('InvalidStateError'));
- }
- self.videoElementPlaying.then(() => {
- try {
- self.canvasElement.width = self.videoElement.videoWidth;
- self.canvasElement.height = self.videoElement.videoHeight;
- self.canvas2dContext.drawImage(self.videoElement, 0, 0);
- self.canvasElement.toBlob(resolve);
- }
- catch (error) {
- reject(new DOMException('UnknownError'));
- }
- });
- });
- }
- /**
- * Implements https://www.w3.org/TR/image-capture/#dom-imagecapture-grabframe
- * @return {Promise<ImageBitmap>} Fulfilled promise with
- * [ImageBitmap](https://www.w3.org/TR/html51/webappapis.html#webappapis-images)
- * argument on success; rejected promise on failure
- */
- grabFrame() {
- const self = this;
- return new Promise(function executorGF(resolve, reject) {
- // `If the readyState of the MediaStreamTrack provided in the constructor is not live,
- // return a promise rejected with a new DOMException whose name is "InvalidStateError".`
- if (self._videoStreamTrack.readyState !== 'live') {
- return reject(new DOMException('InvalidStateError'));
- }
- self.videoElementPlaying.then(() => {
- try {
- self.canvasElement.width = self.videoElement.videoWidth;
- self.canvasElement.height = self.videoElement.videoHeight;
- self.canvas2dContext.drawImage(self.videoElement, 0, 0);
- // TODO polyfill https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapFactories/createImageBitmap for IE
- resolve(window.createImageBitmap(self.canvasElement));
- }
- catch (error) {
- reject(new DOMException('UnknownError'));
- }
- });
- });
- }
- };
- }
- window.ImageCapture = ImageCapture;
|