UNPKG

react-mic-record

Version:
570 lines (448 loc) 19.9 kB
/*! * react-mic-record v1.0.6 * MIT Licensed */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react")); else if(typeof define === 'function' && define.amd) define(["react"], factory); else if(typeof exports === 'object') exports["react-mic-record"] = factory(require("react")); else root["react-mic-record"] = factory(root["React"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_6__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 7); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_ReactMicRecord__ = __webpack_require__(1); /* harmony export (immutable) */ __webpack_exports__["browserSupportsAudio"] = browserSupportsAudio; function browserSupportsAudio() { var AudioContextClass = window.AudioContext || window.webkitAudioContext; if (!AudioContextClass) { return false; } var tmp = new AudioContextClass(); if (!tmp) { return false; } tmp.ok = true; return !!tmp.createAnalyser; } /* harmony default export */ __webpack_exports__["default"] = __WEBPACK_IMPORTED_MODULE_0__components_ReactMicRecord__["a" /* default */]; /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(6); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__libs_MicrophoneRecorder__ = __webpack_require__(4); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__libs_AudioContext__ = __webpack_require__(2); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__libs_AudioPlayer__ = __webpack_require__(3); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__libs_Visualizer__ = __webpack_require__(5); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ReactMicRecord; }); var _class, _temp, _jsxFileName = '/home/shroof/react-mic-record/src/components/ReactMicRecord.js'; 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; } var ReactMicRecord = (_temp = _class = function (_React$Component) { _inherits(ReactMicRecord, _React$Component); function ReactMicRecord(props) { _classCallCheck(this, ReactMicRecord); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.audioContext = null; _this.microphoneRecorder = null; _this.state = { canvas: null, canvasCtx: null }; return _this; } ReactMicRecord.prototype.componentDidMount = function componentDidMount() { var _this2 = this; var _props = this.props, onStop = _props.onStop, onStart = _props.onStart, onData = _props.onData, audioElem = _props.audioElem, audioBitsPerSecond = _props.audioBitsPerSecond, mimeType = _props.mimeType; var canvas = this.visualizerRef; var canvasCtx = canvas.getContext("2d"); var options = { audioBitsPerSecond: audioBitsPerSecond, mimeType: mimeType }; this.audioContext = new __WEBPACK_IMPORTED_MODULE_2__libs_AudioContext__["a" /* default */](); if (audioElem) { this.audioPlayer = new __WEBPACK_IMPORTED_MODULE_3__libs_AudioPlayer__["a" /* default */](audioElem, this.audioContext); } else { this.microphoneRecorder = new __WEBPACK_IMPORTED_MODULE_1__libs_MicrophoneRecorder__["a" /* default */](onStart, onStop, onData, options, this.audioContext); } this.setState({ canvas: canvas, canvasCtx: canvasCtx }, function () { return _this2.visualize(); }); }; ReactMicRecord.prototype.componentWillUnmount = function componentWillUnmount() { if (this.microphoneRecorder) { this.microphoneRecorder.unMount(); this.clear(); } }; ReactMicRecord.prototype.visualize = function visualize() { var _props2 = this.props, backgroundColor = _props2.backgroundColor, strokeColor = _props2.strokeColor, width = _props2.width, height = _props2.height, visualSetting = _props2.visualSetting; var _state = this.state, canvas = _state.canvas, canvasCtx = _state.canvasCtx; this.visualizer = new __WEBPACK_IMPORTED_MODULE_4__libs_Visualizer__["a" /* default */](this.audioContext, canvasCtx, canvas, width, height, backgroundColor, strokeColor); if (visualSetting === 'sinewave') { this.visualizer.visualizeSineWave(); } else if (visualSetting === 'frequencyBars') { this.visualizer.visualizeFrequencyBars(); } }; ReactMicRecord.prototype.clear = function clear() { var _state2 = this.state, canvasCtx = _state2.canvasCtx, width = _state2.width, height = _state2.height; canvasCtx.clearRect(0, 0, width, height); }; ReactMicRecord.prototype.render = function render() { var _this3 = this; var _props3 = this.props, record = _props3.record, width = _props3.width, height = _props3.height, className = _props3.className; if (record) { if (this.microphoneRecorder) { this.microphoneRecorder.startRecording(); this.visualize(); } } else { if (this.microphoneRecorder) { this.microphoneRecorder.stopRecording(); this.clear(); } } return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement('canvas', { ref: function ref(c) { return _this3.visualizerRef = c; }, height: height, width: width, className: className, __source: { fileName: _jsxFileName, lineNumber: 90 }, __self: this }); }; return ReactMicRecord; }(__WEBPACK_IMPORTED_MODULE_0_react___default.a.Component), _class.defaultProps = { backgroundColor: 'rgba(255, 255, 255, 0.5)', strokeColor: '#000000', className: 'visualizer', audioBitsPerSecond: 128000, mimeType: 'audio/webm;codecs=opus', record: false, width: 640, height: 100, visualSetting: 'sinewave' }, _temp); /***/ }), /* 2 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AudioContext; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var AudioContext = function () { function AudioContext() { _classCallCheck(this, AudioContext); this.audioCtx = new (window.AudioContext || window.webkitAudioContext)(); this.analyser = this.audioCtx.createAnalyser(); } AudioContext.prototype.getAudioContext = function getAudioContext() { return this.audioCtx; }; AudioContext.prototype.getAnalyser = function getAnalyser() { return this.analyser; }; return AudioContext; }(); /***/ }), /* 3 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AudioPlayer; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var AudioPlayer = function AudioPlayer(audioElem, audioContext) { _classCallCheck(this, AudioPlayer); var audioCtx = audioContext.getAudioContext(); var analyser = audioContext.getAnalyser(); this.audioSource = audioCtx.createMediaElementSource(audioElem); this.audioSource.connect(analyser); analyser.connect(audioCtx.destination); }; /***/ }), /* 4 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return MicrophoneRecorder; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var constraints = { audio: true, video: false }; // constraints - only audio needed var MicrophoneRecorder = function () { function MicrophoneRecorder(onStart, onStop, onData, options, audioContext) { _classCallCheck(this, MicrophoneRecorder); navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; this.audioCtx = audioContext.getAudioContext(); this.analyser = audioContext.getAnalyser(); this.stream = null; this.onStartCb = onStart; this.onStopCb = onStop; this.mediaOptions = options; this.onData = onData; this.chunks = []; this.startTime = null; } MicrophoneRecorder.prototype.startRecording = function startRecording() { var _this = this; this.startTime = Date.now(); if (this.mediaRecorder) { if (this.audioCtx && this.audioCtx.state === 'suspended') { this.audioCtx.resume(); } if (this.mediaRecorder && this.mediaRecorder.state === 'paused') { this.mediaRecorder.resume(); return; } if (this.audioCtx && this.mediaRecorder && this.mediaRecorder.state === 'inactive') { this.mediaRecorder.start(10); var source = this.audioCtx.createMediaStreamSource(this.stream); source.connect(this.analyser); if (this.onStartCb) { this.onStartCb(); } } } else { if (navigator.mediaDevices) { console.log('getUserMedia supported.'); navigator.mediaDevices.getUserMedia(constraints).then(function (str) { _this.stream = str; if (MediaRecorder.isTypeSupported(_this.mediaOptions.mimeType)) { _this.mediaRecorder = new MediaRecorder(_this.stream, _this.mediaOptions); } else { _this.mediaRecorder = new MediaRecorder(_this.stream); } if (_this.onStartCb) { _this.onStartCb(); } _this.mediaRecorder.onstop = function () { return _this.onStop(); }; _this.mediaRecorder.ondataavailable = function (e) { _this.chunks.push(e.data); if (_this.onData) { _this.onData(e.data); } }; _this.mediaRecorder.start(10); var source = _this.audioCtx.createMediaStreamSource(_this.stream); source.connect(_this.analyser); }); } else { alert('Your browser does not support audio recording'); } } }; MicrophoneRecorder.prototype.stopRecording = function stopRecording() { if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') { this.mediaRecorder.stop(); this.audioCtx.suspend(); } }; MicrophoneRecorder.prototype.unMount = function unMount() { this.stream && this.stream.getTracks()[0].stop(); this.mediaRecorder = null; }; MicrophoneRecorder.prototype.onStop = function onStop() { var blob = new Blob(this.chunks, { 'type': this.mediaOptions.mimeType }); this.chunks = []; var blobObject = { blob: blob, startTime: this.startTime, stopTime: Date.now(), options: this.mediaOptions, blobURL: window.URL.createObjectURL(blob) }; if (this.onStopCb) { this.onStopCb(blobObject); } }; return MicrophoneRecorder; }(); /***/ }), /* 5 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Visualizer; }); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function hexToRgb(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } var Visualizer = function () { function Visualizer(audioContext, canvasCtx, canvas, width, height, backgroundColor, strokeColor) { _classCallCheck(this, Visualizer); this.analyser = audioContext.getAnalyser(); this.canvasCtx = canvasCtx; this.canvas = canvas; this.width = width; this.height = height; this.backgroundColor = backgroundColor; this.strokeColor = strokeColor; this.drawVisual = null; } Visualizer.prototype.visualizeSineWave = function visualizeSineWave() { var _this = this; this.analyser.fftSize = 2048; var bufferLength = this.analyser.fftSize; var dataArray = new Uint8Array(bufferLength); this.canvasCtx.clearRect(0, 0, this.width, this.height); var draw = function draw() { _this.drawVisual = requestAnimationFrame(draw); _this.analyser.getByteTimeDomainData(dataArray); _this.canvasCtx.fillStyle = _this.backgroundColor; _this.canvasCtx.fillRect(0, 0, _this.width, _this.height); _this.canvasCtx.lineWidth = 2; _this.canvasCtx.strokeStyle = _this.strokeColor; _this.canvasCtx.beginPath(); var sliceWidth = _this.width * 1.0 / bufferLength; var x = 0; for (var i = 0; i < bufferLength; i++) { var v = dataArray[i] / 128.0; var y = v * _this.height / 2; if (i === 0) { _this.canvasCtx.moveTo(x, y); } else { _this.canvasCtx.lineTo(x, y); } x += sliceWidth; } _this.canvasCtx.lineTo(_this.canvas.width, _this.canvas.height / 2); _this.canvasCtx.stroke(); }; draw(); }; Visualizer.prototype.visualizeFrequencyBars = function visualizeFrequencyBars() { var _this2 = this; this.analyser.fftSize = 256; var bufferLength = this.analyser.frequencyBinCount; var dataArray = new Uint8Array(bufferLength); this.canvasCtx.clearRect(0, 0, this.width, this.height); var draw = function draw() { _this2.drawVisual = requestAnimationFrame(draw); _this2.analyser.getByteFrequencyData(dataArray); _this2.canvasCtx.fillStyle = _this2.backgroundColor; _this2.canvasCtx.fillRect(0, 0, _this2.width, _this2.height); var barWidth = _this2.width / bufferLength * 2.5; var barHeight = void 0; var x = 0; for (var i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; var rgb = hexToRgb(_this2.strokeColor); _this2.canvasCtx.fillStyle = _this2.strokeColor; _this2.canvasCtx.fillRect(x, _this2.height - barHeight / 2, barWidth, barHeight / 2); x += barWidth + 1; } }; draw(); }; return Visualizer; }(); /***/ }), /* 6 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_6__; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(0); /***/ }) /******/ ]); });