react-get-user-media
Advanced tools
Comparing version 0.1.16 to 0.1.17
@@ -44,1 +44,7 @@ 0.1.0 ~ 0.1.8 | ||
- Creating blob with correct mimeTypes | ||
0.1.17 | ||
- Rollup now exports module as ES5 instead ES2015 | ||
- Creating a minified file on build |
@@ -12,9 +12,9 @@ 'use strict'; | ||
var dataURLToBlob = function dataURLToBlob(dataURL) { | ||
const byteString = atob(dataURL.split(',')[1]); | ||
const mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0]; | ||
var byteString = atob(dataURL.split(',')[1]); | ||
var mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0]; | ||
const arrayBuffer = new ArrayBuffer(byteString.length); | ||
const uint8Array = new Uint8Array(arrayBuffer); | ||
var arrayBuffer = new ArrayBuffer(byteString.length); | ||
var uint8Array = new Uint8Array(arrayBuffer); | ||
for (let i = 0; i < byteString.length; i++) { | ||
for (var i = 0; i < byteString.length; i++) { | ||
uint8Array[i] = byteString.charCodeAt(i); | ||
@@ -27,8 +27,7 @@ } | ||
var consoleErrors = { | ||
elementNotFound(element) { | ||
console.error(`@withGetUserMedia: Missing ID on ${element} tag`); | ||
elementNotFound: function elementNotFound(element) { | ||
console.error("@withGetUserMedia: Missing ID on " + element + " tag"); | ||
}, | ||
missingStream(methodName) { | ||
console.error(`@withGetUserMedia: [Method: ${methodName}] MediaStream not found | ||
Use props.getUserMedia to create one before using this method`); | ||
missingStream: function missingStream(methodName) { | ||
console.error("@withGetUserMedia: [Method: " + methodName + "] MediaStream not found\nUse props.getUserMedia to create one before using this method"); | ||
} | ||
@@ -39,11 +38,19 @@ }; | ||
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
const VIDEO_MIME_TYPE = 'video/webm;codecs=vp8'; | ||
const AUDIO_MIME_TYPES = ['audio/webm', 'audio/ogg']; | ||
const DEFAULT_CONSTRAINTS = { | ||
var VIDEO_MIME_TYPE = 'video/webm;codecs=vp8'; | ||
var AUDIO_MIME_TYPES = ['audio/webm', 'audio/ogg']; | ||
var DEFAULT_CONSTRAINTS = { | ||
audio: false, | ||
@@ -55,153 +62,191 @@ video: { | ||
const withGetUserMedia = (HOCProps = {}) => Component => { | ||
class GetUserMedia extends react.Component { | ||
constructor(props) { | ||
super(props); | ||
var withGetUserMedia = function withGetUserMedia() { | ||
var HOCProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return function (Component) { | ||
var GetUserMedia = function (_React$Component) { | ||
_inherits(GetUserMedia, _React$Component); | ||
Object.assign(this, { | ||
stopStream: this.stopStream.bind(this), | ||
getUserMedia: this.getUserMedia.bind(this), | ||
takePhoto: this.takePhoto.bind(this), | ||
handleGrantedPermissions: this.handleGrantedPermissions.bind(this), | ||
handleDeniedPermissions: this.handleDeniedPermissions.bind(this), | ||
function GetUserMedia(props) { | ||
_classCallCheck(this, GetUserMedia); | ||
startRecording: this.startRecording.bind(this), | ||
stopRecording: this.stopRecording.bind(this), | ||
createMediaObjectURL: this.createMediaObjectURL.bind(this), | ||
createMediaRecorder: this.createMediaRecorder.bind(this), | ||
var _this = _possibleConstructorReturn(this, (GetUserMedia.__proto__ || Object.getPrototypeOf(GetUserMedia)).call(this, props)); | ||
constraints: HOCProps.constraints || DEFAULT_CONSTRAINTS, | ||
Object.assign(_this, { | ||
stopStream: _this.stopStream.bind(_this), | ||
getUserMedia: _this.getUserMedia.bind(_this), | ||
takePhoto: _this.takePhoto.bind(_this), | ||
handleGrantedPermissions: _this.handleGrantedPermissions.bind(_this), | ||
handleDeniedPermissions: _this.handleDeniedPermissions.bind(_this), | ||
state: { | ||
recording: false, | ||
permitted: false, | ||
asked: false | ||
} | ||
}); | ||
} | ||
startRecording: _this.startRecording.bind(_this), | ||
stopRecording: _this.stopRecording.bind(_this), | ||
createMediaObjectURL: _this.createMediaObjectURL.bind(_this), | ||
createMediaRecorder: _this.createMediaRecorder.bind(_this), | ||
componentWillUnmount() { | ||
this.stopStream(); | ||
} | ||
constraints: HOCProps.constraints || DEFAULT_CONSTRAINTS, | ||
get streamElement() { | ||
const streamElementNode = document.getElementById(HOCProps.streamElementId); | ||
state: { | ||
recording: false, | ||
permitted: false, | ||
asked: false | ||
} | ||
}); | ||
return _this; | ||
} | ||
streamElementNode.setAttribute('autoPlay', true); | ||
streamElementNode.setAttribute('playsInline', true); | ||
_createClass(GetUserMedia, [{ | ||
key: 'componentWillUnmount', | ||
value: function componentWillUnmount() { | ||
this.stopStream(); | ||
} | ||
}, { | ||
key: 'stopStream', | ||
value: function stopStream() { | ||
if (!this.stream) return; | ||
return streamElementNode; | ||
} | ||
this.stream.getTracks().forEach(function (track) { | ||
return track.stop(); | ||
}); | ||
this.stream = null; | ||
this.toggleStreamSrcObject(); | ||
this.setState({ recording: false }); | ||
} | ||
}, { | ||
key: 'getUserMedia', | ||
value: function getUserMedia() { | ||
var _state = this.state, | ||
asked = _state.asked, | ||
permitted = _state.permitted; | ||
stopStream() { | ||
if (!this.stream) return; | ||
if (asked && permitted && this.stream) return this.toggleStreamSrcObject(); | ||
this.stream.getTracks().forEach(track => track.stop()); | ||
this.stream = null; | ||
this.toggleStreamSrcObject(); | ||
this.setState({ recording: false }); | ||
} | ||
navigator.mediaDevices.getUserMedia(this.constraints).then(this.handleGrantedPermissions).catch(this.handleDeniedPermissions); | ||
} | ||
}, { | ||
key: 'handleDeniedPermissions', | ||
value: function handleDeniedPermissions(error) { | ||
if (this.state.asked) return; | ||
// TODO: Provide a better way to debug | ||
console.error(error); | ||
this.setState({ permitted: false, asked: true }); | ||
} | ||
}, { | ||
key: 'handleGrantedPermissions', | ||
value: function handleGrantedPermissions(stream) { | ||
this.stream = stream; | ||
this.toggleStreamSrcObject(); | ||
this.setState({ permitted: true, asked: true }); | ||
} | ||
}, { | ||
key: 'createMediaRecorder', | ||
value: function createMediaRecorder(stream) { | ||
if (!window.MediaRecorder) { | ||
var AudioRecorder = audioRecorderPolyfill; | ||
AudioRecorder.mimeType = 'audio/wav'; | ||
return new AudioRecorder(stream); | ||
} | ||
getUserMedia() { | ||
const { asked, permitted } = this.state; | ||
if (asked && permitted && this.stream) return this.toggleStreamSrcObject(); | ||
if (!this.constraints.video) { | ||
return new window.MediaRecorder(stream, { mimeType: this.audioSupportedType }); | ||
} | ||
navigator.mediaDevices.getUserMedia(this.constraints).then(this.handleGrantedPermissions).catch(this.handleDeniedPermissions); | ||
} | ||
return new window.MediaRecorder(stream, { mimeType: VIDEO_MIME_TYPE }); | ||
} | ||
}, { | ||
key: 'createMediaObjectURL', | ||
value: function createMediaObjectURL(_ref) { | ||
var data = _ref.data; | ||
handleDeniedPermissions(error) { | ||
if (this.state.asked) return; | ||
// TODO: Provide a better way to debug | ||
console.error(error); | ||
this.setState({ permitted: false, asked: true }); | ||
} | ||
if (!data || data.size <= 0 || !data.type) return; | ||
handleGrantedPermissions(stream) { | ||
this.stream = stream; | ||
this.toggleStreamSrcObject(); | ||
this.setState({ permitted: true, asked: true }); | ||
} | ||
var mediaBlob = new Blob([data], { type: data.type }); | ||
get audioSupportedType() { | ||
return AUDIO_MIME_TYPES.find(type => window.MediaRecorder.isTypeSupported(type)); | ||
} | ||
this.setState({ mediaBlob: mediaBlob, mediaObjectURL: URL.createObjectURL(mediaBlob) }); | ||
} | ||
}, { | ||
key: 'startRecording', | ||
value: function startRecording() { | ||
if (!this.stream) return consoleErrors.missingStream('startRecording'); | ||
createMediaRecorder(stream) { | ||
if (!window.MediaRecorder) { | ||
const AudioRecorder = audioRecorderPolyfill; | ||
AudioRecorder.mimeType = 'audio/wav'; | ||
return new AudioRecorder(stream); | ||
} | ||
this.mediaRecorder = this.createMediaRecorder(this.stream); | ||
this.mediaRecorder.addEventListener('dataavailable', this.createMediaObjectURL); | ||
this.mediaRecorder.start(); | ||
this.setState({ recording: true }); | ||
} | ||
}, { | ||
key: 'stopRecording', | ||
value: function stopRecording() { | ||
this.mediaRecorder.stop(); | ||
this.setState({ recording: false }); | ||
} | ||
}, { | ||
key: 'takePhoto', | ||
value: function takePhoto() { | ||
if (!this.stream) return consoleErrors.missingStream('takePhoto'); | ||
if (!this.streamElement) return consoleErrors.elementNotFound('streamElementId'); | ||
if (!this.constraints.video) { | ||
return new window.MediaRecorder(stream, { mimeType: this.audioSupportedType }); | ||
} | ||
var _streamElement = this.streamElement, | ||
videoWidth = _streamElement.videoWidth, | ||
videoHeight = _streamElement.videoHeight; | ||
return new window.MediaRecorder(stream, { mimeType: VIDEO_MIME_TYPE }); | ||
} | ||
var canvasElement = document.createElement('canvas'); | ||
canvasElement.height = videoHeight; | ||
canvasElement.width = videoWidth; | ||
canvasElement.getContext('2d').drawImage(this.streamElement, 0, 0); | ||
createMediaObjectURL({ data }) { | ||
if (!data || data.size <= 0 || !data.type) return; | ||
var photo = canvasElement.toDataURL('image/png'); | ||
var photoBlob = dataURLToBlob(photo); | ||
const mediaBlob = new Blob([data], { type: data.type }); | ||
this.setState({ photo: photo, photoBlob: photoBlob }); | ||
} | ||
}, { | ||
key: 'toggleStreamSrcObject', | ||
value: function toggleStreamSrcObject() { | ||
if (!HOCProps.streamElementId) return; | ||
if (!this.streamElement) return consoleErrors.elementNotFound('streamElementId'); | ||
this.setState({ mediaBlob, mediaObjectURL: URL.createObjectURL(mediaBlob) }); | ||
} | ||
if (!this.stream) { | ||
this.streamElement.srcObject = null; | ||
} | ||
startRecording() { | ||
if (!this.stream) return consoleErrors.missingStream('startRecording'); | ||
this.streamElement.srcObject = this.stream; | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
return react.createElement(Component, _extends({ | ||
stopStream: this.stopStream, | ||
getUserMedia: this.getUserMedia, | ||
takePhoto: this.takePhoto, | ||
startRecording: this.startRecording, | ||
stopRecording: this.stopRecording, | ||
stream: this.stream | ||
}, HOCProps, this.state, this.props)); | ||
} | ||
}, { | ||
key: 'streamElement', | ||
get: function get() { | ||
var streamElementNode = document.getElementById(HOCProps.streamElementId); | ||
this.mediaRecorder = this.createMediaRecorder(this.stream); | ||
this.mediaRecorder.addEventListener('dataavailable', this.createMediaObjectURL); | ||
this.mediaRecorder.start(); | ||
this.setState({ recording: true }); | ||
} | ||
streamElementNode.setAttribute('autoPlay', true); | ||
streamElementNode.setAttribute('playsInline', true); | ||
stopRecording() { | ||
this.mediaRecorder.stop(); | ||
this.setState({ recording: false }); | ||
} | ||
return streamElementNode; | ||
} | ||
}, { | ||
key: 'audioSupportedType', | ||
get: function get() { | ||
return AUDIO_MIME_TYPES.find(function (type) { | ||
return window.MediaRecorder.isTypeSupported(type); | ||
}); | ||
} | ||
}]); | ||
takePhoto() { | ||
if (!this.stream) return consoleErrors.missingStream('takePhoto'); | ||
if (!this.streamElement) return consoleErrors.elementNotFound('streamElementId'); | ||
return GetUserMedia; | ||
}(react.Component); | ||
const { videoWidth, videoHeight } = this.streamElement; | ||
const canvasElement = document.createElement('canvas'); | ||
canvasElement.height = videoHeight; | ||
canvasElement.width = videoWidth; | ||
canvasElement.getContext('2d').drawImage(this.streamElement, 0, 0); | ||
const photo = canvasElement.toDataURL('image/png'); | ||
const photoBlob = dataURLToBlob(photo); | ||
this.setState({ photo, photoBlob }); | ||
} | ||
toggleStreamSrcObject() { | ||
if (!HOCProps.streamElementId) return; | ||
if (!this.streamElement) return consoleErrors.elementNotFound('streamElementId'); | ||
if (!this.stream) { | ||
this.streamElement.srcObject = null; | ||
} | ||
this.streamElement.srcObject = this.stream; | ||
} | ||
render() { | ||
return react.createElement(Component, _extends({ | ||
stopStream: this.stopStream, | ||
getUserMedia: this.getUserMedia, | ||
takePhoto: this.takePhoto, | ||
startRecording: this.startRecording, | ||
stopRecording: this.stopRecording, | ||
stream: this.stream | ||
}, HOCProps, this.state, this.props)); | ||
} | ||
} | ||
const displayName = Component.displayName || Component.name || 'Component'; | ||
GetUserMedia.displayName = `withGetUserMedia(${displayName})`; | ||
return GetUserMedia; | ||
var displayName = Component.displayName || Component.name || 'Component'; | ||
GetUserMedia.displayName = 'withGetUserMedia(' + displayName + ')'; | ||
return GetUserMedia; | ||
}; | ||
}; | ||
@@ -211,3 +256,3 @@ | ||
var src = { withGetUserMedia }; | ||
var src = { withGetUserMedia: withGetUserMedia }; | ||
var src_1 = src.withGetUserMedia; | ||
@@ -214,0 +259,0 @@ |
{ | ||
"name": "react-get-user-media", | ||
"version": "0.1.16", | ||
"version": "0.1.17", | ||
"description": "A high order component that exposes some functions related to navigator.mediaDevices", | ||
@@ -11,3 +11,4 @@ "main": "src/index.js", | ||
"build": "rollup -c", | ||
"prepublishOnly": "NODE_ENV=production npm run clean && npm run lint && npm run build", | ||
"minify": "uglifyjs dist/react-get-user-media.js -o dist/react-get-user-media.min.js", | ||
"prepublishOnly": "NODE_ENV=production npm run clean && npm run lint && npm run build && npm run minify", | ||
"clean": "rimraf dist", | ||
@@ -48,3 +49,3 @@ "lint": "standard --fix" | ||
"rimraf": "^2.6.2", | ||
"rollup": "^0.61.2", | ||
"rollup": "^0.62.0", | ||
"rollup-plugin-babel": "^3.0.5", | ||
@@ -55,3 +56,4 @@ "rollup-plugin-commonjs": "^9.1.3", | ||
"rollup-plugin-uglify": "^4.0.0", | ||
"standard": "^11.0.1" | ||
"standard": "^11.0.1", | ||
"uglify-js": "^3.4.2" | ||
}, | ||
@@ -58,0 +60,0 @@ "standard": { |
Sorry, the diff of this file is not supported yet
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
39670
7
350
18
3