{"version":3,"sources":["webpack://WaveSurfer.[name]/webpack/universalModuleDefinition","webpack://WaveSurfer.[name]/webpack/bootstrap","webpack://WaveSurfer.[name]/./src/plugin/microphone.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","MicrophonePlugin","params","ws","_this","this","_classCallCheck","wavesurfer","active","paused","reloadBufferFunction","e","reloadBuffer","undefined","navigator","mediaDevices","getUserMedia","constraints","successCallback","errorCallback","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","Promise","reject","Error","video","audio","bufferSize","numberOfInputChannels","numberOfOutputChannels","_onBackendCreated","micContext","backend","getAudioContext","deferInit","instance","on","un","stop","_this2","then","data","gotStream","catch","deviceError","pause","play","start","connect","disconnect","stopDevice","empty","stream","result","detectBrowser","browser","version","getTracks","forEach","mediaStreamSource","createMediaStreamSource","levelChecker","createScriptProcessor","destination","onaudioprocess","event","loadDecodedBuffer","inputBuffer","fireEvent","code","uastring","expr","pos","match","length","parseInt","extractVersion","userAgent","minVersion","webkitRTCPeerConnection"],"mappings":"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","file":"wavesurfer.microphone.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"microphone\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"microphone\"] = factory();\n\telse\n\t\troot[\"WaveSurfer\"] = root[\"WaveSurfer\"] || {}, root[\"WaveSurfer\"][\"microphone\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"localhost:8080/dist/plugin/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","/**\n * @typedef {Object} MicrophonePluginParams\n * @property {MediaStreamConstraints} constraints The constraints parameter is a\n * MediaStreamConstaints object with two members: video and audio, describing\n * the media types requested. Either or both must be specified.\n * @property {number} bufferSize=4096 The buffer size in units of sample-frames.\n * If specified, the bufferSize must be one of the following values: `256`,\n * `512`, `1024`, `2048`, `4096`, `8192`, `16384`\n * @property {number} numberOfInputChannels=1 Integer specifying the number of\n * channels for this node's input. Values of up to 32 are supported.\n * @property {?boolean} deferInit Set to true to manually call\n * `initPlugin('microphone')`\n */\n\n/**\n * Visualise microphone input in a wavesurfer instance.\n *\n * @implements {PluginClass}\n * @extends {Observer}\n * @example\n * // es6\n * import MicrophonePlugin from 'wavesurfer.microphone.js';\n *\n * // commonjs\n * var MicrophonePlugin = require('wavesurfer.microphone.js');\n *\n * // if you are using <script> tags\n * var MicrophonePlugin = window.WaveSurfer.microphone;\n *\n * // ... initialising wavesurfer with the plugin\n * var wavesurfer = WaveSurfer.create({\n * // wavesurfer options ...\n * plugins: [\n * MicrophonePlugin.create({\n * // plugin options ...\n * })\n * ]\n * });\n */\nexport default class MicrophonePlugin {\n /**\n * Microphone plugin definition factory\n *\n * This function must be used to create a plugin definition which can be\n * used by wavesurfer to correctly instantiate the plugin.\n *\n * @param {MicrophonePluginParams} params parameters use to initialise the plugin\n * @return {PluginDefinition} an object representing the plugin\n */\n static create(params) {\n return {\n name: 'microphone',\n deferInit: params && params.deferInit ? params.deferInit : false,\n params: params,\n instance: MicrophonePlugin\n };\n }\n\n constructor(params, ws) {\n this.params = params;\n this.wavesurfer = ws;\n\n this.active = false;\n this.paused = false;\n this.reloadBufferFunction = e => this.reloadBuffer(e);\n\n // cross-browser getUserMedia\n const promisifiedOldGUM = (\n constraints,\n successCallback,\n errorCallback\n ) => {\n // get ahold of getUserMedia, if present\n const getUserMedia =\n navigator.getUserMedia ||\n navigator.webkitGetUserMedia ||\n navigator.mozGetUserMedia ||\n navigator.msGetUserMedia;\n // Some browsers just don't implement it - return a rejected\n // promise with an error to keep a consistent interface\n if (!getUserMedia) {\n return Promise.reject(\n new Error('getUserMedia is not implemented in this browser')\n );\n }\n // otherwise, wrap the call to the old navigator.getUserMedia with\n // a Promise\n return new Promise((successCallback, errorCallback) => {\n getUserMedia.call(\n navigator,\n constraints,\n successCallback,\n errorCallback\n );\n });\n };\n // Older browsers might not implement mediaDevices at all, so we set an\n // empty object first\n if (navigator.mediaDevices === undefined) {\n navigator.mediaDevices = {};\n }\n // Some browsers partially implement mediaDevices. We can't just assign\n // an object with getUserMedia as it would overwrite existing\n // properties. Here, we will just add the getUserMedia property if it's\n // missing.\n if (navigator.mediaDevices.getUserMedia === undefined) {\n navigator.mediaDevices.getUserMedia = promisifiedOldGUM;\n }\n this.constraints = this.params.constraints || {\n video: false,\n audio: true\n };\n this.bufferSize = this.params.bufferSize || 4096;\n this.numberOfInputChannels = this.params.numberOfInputChannels || 1;\n this.numberOfOutputChannels = this.params.numberOfOutputChannels || 1;\n\n this._onBackendCreated = () => {\n // wavesurfer's AudioContext where we'll route the mic signal to\n this.micContext = this.wavesurfer.backend.getAudioContext();\n };\n }\n\n init() {\n this.wavesurfer.on('backend-created', this._onBackendCreated);\n if (this.wavesurfer.backend) {\n this._onBackendCreated();\n }\n }\n\n /**\n * Destroy the microphone plugin.\n */\n destroy() {\n // make sure the buffer is not redrawn during\n // cleanup and demolition of this plugin.\n this.paused = true;\n\n this.wavesurfer.un('backend-created', this._onBackendCreated);\n this.stop();\n }\n\n /**\n * Allow user to select audio input device, eg. microphone, and\n * start the visualization.\n */\n start() {\n navigator.mediaDevices\n .getUserMedia(this.constraints)\n .then(data => this.gotStream(data))\n .catch(data => this.deviceError(data));\n }\n\n /**\n * Pause/resume visualization.\n */\n togglePlay() {\n if (!this.active) {\n // start it first\n this.start();\n } else {\n // toggle paused\n this.paused = !this.paused;\n\n if (this.paused) {\n this.pause();\n } else {\n this.play();\n }\n }\n }\n\n /**\n * Play visualization.\n */\n play() {\n this.paused = false;\n\n this.connect();\n }\n\n /**\n * Pause visualization.\n */\n pause() {\n this.paused = true;\n\n // disconnect sources so they can be used elsewhere\n // (eg. during audio playback)\n this.disconnect();\n }\n\n /**\n * Stop the device stream and remove any remaining waveform drawing from\n * the wavesurfer canvas.\n */\n stop() {\n if (this.active) {\n // stop visualization and device\n this.stopDevice();\n\n // empty last frame\n this.wavesurfer.empty();\n }\n }\n\n /**\n * Stop the device and the visualization.\n */\n stopDevice() {\n this.active = false;\n\n // stop visualization\n this.disconnect();\n\n // stop stream from device\n if (this.stream) {\n const result = this.detectBrowser();\n // MediaStream.stop is deprecated since:\n // - Firefox 44 (https://www.fxsitecompat.com/en-US/docs/2015/mediastream-stop-has-been-deprecated/)\n // - Chrome 45 (https://developers.google.com/web/updates/2015/07/mediastream-deprecations)\n if (\n (result.browser === 'chrome' && result.version >= 45) ||\n (result.browser === 'firefox' && result.version >= 44) ||\n result.browser === 'edge'\n ) {\n if (this.stream.getTracks) {\n // note that this should not be a call\n this.stream.getTracks().forEach(stream => stream.stop());\n return;\n }\n }\n\n this.stream.stop();\n }\n }\n\n /**\n * Connect the media sources that feed the visualization.\n */\n connect() {\n if (this.stream !== undefined) {\n // Create an AudioNode from the stream.\n this.mediaStreamSource = this.micContext.createMediaStreamSource(\n this.stream\n );\n\n this.levelChecker = this.micContext.createScriptProcessor(\n this.bufferSize,\n this.numberOfInputChannels,\n this.numberOfOutputChannels\n );\n this.mediaStreamSource.connect(this.levelChecker);\n\n this.levelChecker.connect(this.micContext.destination);\n this.levelChecker.onaudioprocess = this.reloadBufferFunction;\n }\n }\n\n /**\n * Disconnect the media sources that feed the visualization.\n */\n disconnect() {\n if (this.mediaStreamSource !== undefined) {\n this.mediaStreamSource.disconnect();\n }\n\n if (this.levelChecker !== undefined) {\n this.levelChecker.disconnect();\n this.levelChecker.onaudioprocess = undefined;\n }\n }\n\n /**\n * Redraw the waveform.\n */\n reloadBuffer(event) {\n if (!this.paused) {\n this.wavesurfer.empty();\n this.wavesurfer.loadDecodedBuffer(event.inputBuffer);\n }\n }\n\n /**\n * Audio input device is ready.\n *\n * @param {LocalMediaStream} stream The microphone's media stream.\n */\n gotStream(stream) {\n this.stream = stream;\n this.active = true;\n\n // start visualization\n this.play();\n\n // notify listeners\n this.fireEvent('deviceReady', stream);\n }\n\n /**\n * Device error callback.\n */\n deviceError(code) {\n // notify listeners\n this.fireEvent('deviceError', code);\n }\n\n /**\n * Extract browser version out of the provided user agent string.\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\n extractVersion(uastring, expr, pos) {\n const match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n }\n\n /**\n * Browser detector.\n * @return {object} result containing browser, version and minVersion\n * properties.\n */\n detectBrowser() {\n // Returned result object.\n const result = {};\n result.browser = null;\n result.version = null;\n result.minVersion = null;\n\n // Non supported browser.\n if (typeof window === 'undefined' || !window.navigator) {\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n // Firefox.\n if (navigator.mozGetUserMedia) {\n result.browser = 'firefox';\n result.version = this.extractVersion(\n navigator.userAgent,\n /Firefox\\/([0-9]+)\\./,\n 1\n );\n result.minVersion = 31;\n return result;\n }\n\n // Chrome/Chromium/Webview.\n if (navigator.webkitGetUserMedia && window.webkitRTCPeerConnection) {\n result.browser = 'chrome';\n result.version = this.extractVersion(\n navigator.userAgent,\n /Chrom(e|ium)\\/([0-9]+)\\./,\n 2\n );\n result.minVersion = 38;\n return result;\n }\n\n // Edge.\n if (\n navigator.mediaDevices &&\n navigator.userAgent.match(/Edge\\/(\\d+).(\\d+)$/)\n ) {\n result.browser = 'edge';\n result.version = this.extractVersion(\n navigator.userAgent,\n /Edge\\/(\\d+).(\\d+)$/,\n 2\n );\n result.minVersion = 10547;\n return result;\n }\n\n // Non supported browser default.\n result.browser = 'Not a supported browser.';\n return result;\n }\n}\n"],"sourceRoot":""}