image-capture
Advanced tools
Comparing version
@@ -1,183 +0,223 @@ | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
(function (global, factory) { | ||
if (typeof define === "function" && define.amd) { | ||
define(['exports'], factory); | ||
} else if (typeof exports !== "undefined") { | ||
factory(exports); | ||
} else { | ||
var mod = { | ||
exports: {} | ||
}; | ||
factory(mod.exports); | ||
global.imagecapture = mod.exports; | ||
} | ||
})(this, function (exports) { | ||
'use strict'; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
// Copyright 2016 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. | ||
// | ||
//////////////////////////////////////////////////////////////////////////////// | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
// MediaStream ImageCapture polyfill | ||
var _createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
export var ImageCapture = window.ImageCapture; | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
if (typeof ImageCapture === 'undefined') { | ||
ImageCapture = function () { | ||
// Copyright 2016 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. | ||
// | ||
//////////////////////////////////////////////////////////////////////////////// | ||
/** | ||
* TODO https://www.w3.org/TR/image-capture/#constructors | ||
* | ||
* @param {MediaStreamTrack} videoStreamTrack - A MediaStreamTrack of the 'video' kind | ||
*/ | ||
function ImageCapture(videoStreamTrack) { | ||
_classCallCheck(this, ImageCapture); | ||
// MediaStream ImageCapture polyfill | ||
if (videoStreamTrack.kind !== 'video') throw new DOMException('NotSupportedError'); | ||
var ImageCapture = exports.ImageCapture = window.ImageCapture; | ||
this._videoStreamTrack = videoStreamTrack; | ||
if (!('readyState' in this._videoStreamTrack)) { | ||
// Polyfill for Firefox | ||
this._videoStreamTrack.readyState = 'live'; | ||
} | ||
if (typeof ImageCapture === 'undefined') { | ||
exports.ImageCapture = ImageCapture = function () { | ||
// MediaStream constructor not available until Chrome 55 - https://www.chromestatus.com/feature/5912172546752512 | ||
this._previewStream = new MediaStream([videoStreamTrack]); | ||
this.videoElement = document.createElement('video'); | ||
this.videoElement.src = URL.createObjectURL(this._previewStream); | ||
this.videoElement.muted = true; | ||
this.videoElement.play(); // required by Firefox | ||
/** | ||
* TODO https://www.w3.org/TR/image-capture/#constructors | ||
* | ||
* @param {MediaStreamTrack} videoStreamTrack - A MediaStreamTrack of the 'video' kind | ||
*/ | ||
function ImageCapture(videoStreamTrack) { | ||
_classCallCheck(this, ImageCapture); | ||
this.canvasElement = document.createElement('canvas'); | ||
// TODO Firefox has https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas | ||
this.canvas2dContext = this.canvasElement.getContext('2d'); | ||
} | ||
if (videoStreamTrack.kind !== 'video') throw new DOMException('NotSupportedError'); | ||
/** | ||
* https://w3c.github.io/mediacapture-image/index.html#dom-imagecapture-videostreamtrack | ||
* @return {MediaStreamTrack} The MediaStreamTrack passed into the constructor | ||
*/ | ||
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.videoElement.src = URL.createObjectURL(this._previewStream); | ||
this.videoElement.muted = true; | ||
this.videoElement.play(); // required by Firefox | ||
_createClass(ImageCapture, [{ | ||
key: 'getPhotoCapabilities', | ||
this.canvasElement = document.createElement('canvas'); | ||
// TODO Firefox has https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas | ||
this.canvas2dContext = this.canvasElement.getContext('2d'); | ||
} | ||
/** | ||
* 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 | ||
* https://w3c.github.io/mediacapture-image/index.html#dom-imagecapture-videostreamtrack | ||
* @return {MediaStreamTrack} The MediaStreamTrack passed into the constructor | ||
*/ | ||
value: function getPhotoCapabilities() { | ||
return new Promise(function executorGPC(resolve, reject) { | ||
// TODO see https://github.com/w3c/mediacapture-image/issues/97 | ||
var 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 | ||
_createClass(ImageCapture, [{ | ||
key: 'getPhotoCapabilities', | ||
/** | ||
* 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 | ||
*/ | ||
value: function getPhotoCapabilities() { | ||
return new Promise(function executorGPC(resolve, reject) { | ||
// TODO see https://github.com/w3c/mediacapture-image/issues/97 | ||
var 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')); | ||
}); | ||
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 | ||
*/ | ||
/** | ||
* 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 | ||
*/ | ||
}, { | ||
key: 'setOptions', | ||
value: function setOptions() { | ||
var photoSettings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
}, { | ||
key: 'setOptions', | ||
value: function setOptions() { | ||
var photoSettings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return new Promise(function executorSO(resolve, reject) { | ||
// TODO | ||
}); | ||
} | ||
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 | ||
*/ | ||
/** | ||
* 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 | ||
*/ | ||
}, { | ||
key: 'takePhoto', | ||
value: function takePhoto() { | ||
var 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') { | ||
// -- however, checking for `live` alone doesn't guarantee the video is ready | ||
if (self.videoElement.videoWidth) { | ||
try { | ||
self.canvasElement.width = self.videoElement.videoWidth; | ||
self.canvasElement.height = self.videoElement.videoHeight; | ||
self.canvas2dContext.drawImage(self.videoElement, 0, 0); | ||
self.canvasElement.toBlob(function (blob) { | ||
resolve(blob); | ||
}); | ||
} catch (error) { | ||
}, { | ||
key: 'takePhoto', | ||
value: function takePhoto() { | ||
var 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') { | ||
// -- however, checking for `live` alone doesn't guarantee the video is ready | ||
if (self.videoElement.videoWidth) { | ||
try { | ||
self.canvasElement.width = self.videoElement.videoWidth; | ||
self.canvasElement.height = self.videoElement.videoHeight; | ||
self.canvas2dContext.drawImage(self.videoElement, 0, 0); | ||
self.canvasElement.toBlob(function (blob) { | ||
resolve(blob); | ||
}); | ||
} catch (error) { | ||
reject(new DOMException('UnknownError')); | ||
} | ||
} else { | ||
reject(new DOMException('UnknownError')); | ||
} | ||
} else { | ||
reject(new DOMException('UnknownError')); | ||
reject(new DOMException('InvalidStateError')); | ||
} | ||
} else { | ||
reject(new DOMException('InvalidStateError')); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
/** | ||
* 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 | ||
*/ | ||
/** | ||
* 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 | ||
*/ | ||
}, { | ||
key: 'grabFrame', | ||
value: function grabFrame() { | ||
var self = this; | ||
return new Promise(function executorGF(resolve, reject) { | ||
if (self._videoStreamTrack.readyState === 'live') { | ||
if (self.videoElement.videoWidth) { | ||
try { | ||
// videoWidth is available after videoElement.onloadedmetadata fires | ||
self.canvasElement.width = self.videoElement.videoWidth; | ||
self.canvasElement.height = self.videoElement.videoHeight; | ||
// The video has an image after videoElement.oncanplay triggers | ||
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) { | ||
}, { | ||
key: 'grabFrame', | ||
value: function grabFrame() { | ||
var self = this; | ||
return new Promise(function executorGF(resolve, reject) { | ||
if (self._videoStreamTrack.readyState === 'live') { | ||
if (self.videoElement.videoWidth) { | ||
try { | ||
// videoWidth is available after videoElement.onloadedmetadata fires | ||
self.canvasElement.width = self.videoElement.videoWidth; | ||
self.canvasElement.height = self.videoElement.videoHeight; | ||
// The video has an image after videoElement.oncanplay triggers | ||
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')); | ||
} | ||
} else { | ||
reject(new DOMException('UnknownError')); | ||
} | ||
} else { | ||
reject(new DOMException('UnknownError')); | ||
reject(new DOMException('InvalidStateError')); | ||
} | ||
} else { | ||
reject(new DOMException('InvalidStateError')); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'videoStreamTrack', | ||
get: function get() { | ||
return this._videoStreamTrack; | ||
} | ||
}]); | ||
}); | ||
} | ||
}, { | ||
key: 'videoStreamTrack', | ||
get: function get() { | ||
return this._videoStreamTrack; | ||
} | ||
}]); | ||
return ImageCapture; | ||
}(); | ||
} | ||
return ImageCapture; | ||
}(); | ||
} | ||
}); |
{ | ||
"name": "image-capture", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "MediaStream ImageCapture polyfill: takePhoto(), grabFrame() and more", | ||
@@ -10,3 +10,3 @@ "main": "lib/imagecapture.js", | ||
"prepublish": "babel -d lib src/", | ||
"dev": "webpack-dev-server --progress --colors", | ||
"dev": "webpack-dev-server --progress", | ||
"lt": "lt --port 8080 --subdomain imagecapture", | ||
@@ -52,3 +52,3 @@ "docs": "webpack" | ||
{ | ||
"modules": false | ||
"modules": "umd" | ||
} | ||
@@ -55,0 +55,0 @@ ] |
@@ -121,6 +121,6 @@ # ImageCapture polyfill | ||
* Chrome 55 | ||
* Firefox 49 | ||
* Chrome 52 for Android | ||
* Firefox 48 for Android | ||
* Chrome 55+ | ||
* Firefox 49+ | ||
* Chrome 52+ for Android | ||
* Firefox 48+ for Android | ||
@@ -136,16 +136,16 @@ For the widest compatibility, you can additionally load the [WebRTC adapter](https://github.com/webrtc/adapter). That will expand support to: | ||
## [yarn](https://code.facebook.com/posts/1840075619545360) | ||
## [yarn](https://yarnpkg.com/en/) | ||
```sh | ||
yarn | ||
yarn run dev | ||
``` | ||
## npm (slower) | ||
```sh | ||
npm install | ||
npm run dev | ||
``` | ||
```sh | ||
yarn | ||
yarn run dev | ||
``` | ||
## npm (slower) | ||
```sh | ||
npm install | ||
npm run dev | ||
``` | ||
Before committing, make sure you pass yarn/npm `run lint` without errors, and run yarn/npm `run docs` to generate the demo. |
229268
3.93%29
3.57%799
4.72%